CircuitOnline/simulator/src/Verilog2CV.js

202 lines
6.2 KiB
JavaScript
Raw Normal View History

import { newCircuit, switchCircuit, changeCircuitName} from './circuit'
import SubCircuit from './subcircuit';
import CodeMirror from 'codemirror/lib/codemirror.js';
import 'codemirror/lib/codemirror.css';
import 'codemirror/addon/hint/show-hint.css';
import 'codemirror/mode/verilog/verilog.js';
import 'codemirror/addon/edit/closebrackets.js';
import 'codemirror/addon/hint/anyword-hint.js';
import 'codemirror/addon/hint/show-hint.js';
import 'codemirror/addon/display/autorefresh.js';
import { showError, showMessage } from './utils';
import { showProperties } from './ux';
var editor;
var verilogMode = false;
export function createVerilogCircuit() {
newCircuit(undefined, undefined, true, true);
verilogModeSet(true);
}
export function saveVerilogCode() {
var code = editor.getValue();
globalScope.verilogMetadata.code = code;
generateVerilogCircuit(code);
}
export function resetVerilogCode() {
editor.setValue(globalScope.verilogMetadata.code);
}
export function hasVerilogCodeChanges() {
return editor.getValue() != globalScope.verilogMetadata.code;
}
export function verilogModeGet() {
return verilogMode;
}
export function verilogModeSet(mode) {
if(mode == verilogMode) return;
verilogMode = mode;
if(mode) {
$('#code-window').show();
$('.elementPanel').hide();
$('.timing-diagram-panel').hide();
$('.quick-btn').hide();
$('#verilogEditorPanel').show();
if (!embed) {
simulationArea.lastSelected = globalScope.root;
showProperties(undefined);
showProperties(simulationArea.lastSelected);
}
resetVerilogCode();
}
else {
$('#code-window').hide();
$('.elementPanel').show();
$('.timing-diagram-panel').show();
$('.quick-btn').show();
$('#verilogEditorPanel').hide();
}
}
import yosysTypeMap from './VerilogClasses';
class verilogSubCircuit {
constructor(circuit) {
this.circuit = circuit;
}
getPort(portName) {
var numInputs = this.circuit.inputNodes.length;
var numOutputs = this.circuit.outputNodes.length
for(var i = 0; i < numInputs; i++) {
if(this.circuit.data.Input[i].label == portName){
return this.circuit.inputNodes[i];
}
}
for(var i = 0; i < numOutputs; i++) {
if(this.circuit.data.Output[i].label == portName) {
return this.circuit.outputNodes[i];
}
}
}
}
export function YosysJSON2CV(JSON, parentScope = globalScope, name = "verilogCircuit", subCircuitScope = {}, root = false){
var parentID = (parentScope.id);
var subScope;
if(root) {
subScope = parentScope;
}
else {
subScope = newCircuit(name, undefined, true, false);
}
var circuitDevices = {};
for (var subCircuitName in JSON.subcircuits) {
var scope = YosysJSON2CV(JSON.subcircuits[subCircuitName], subScope, subCircuitName, subCircuitScope);
subCircuitScope[subCircuitName] = scope.id;
}
for (var device in JSON.devices) {
var deviceType = JSON.devices[device].type;
if(deviceType == "Subcircuit") {
var subCircuitName = JSON.devices[device].celltype;
circuitDevices[device] = new verilogSubCircuit(new SubCircuit(500, 500, undefined, subCircuitScope[subCircuitName]));
}
else {
circuitDevices[device] = new yosysTypeMap[deviceType](JSON.devices[device]);
}
}
for (var connection in JSON.connectors) {
var fromId = JSON.connectors[connection]["from"]["id"];
var fromPort = JSON.connectors[connection]["from"]["port"];
var toId = JSON.connectors[connection]["to"]["id"];
var toPort = JSON.connectors[connection]["to"]["port"];
var fromObj = circuitDevices[fromId];
var toObj = circuitDevices[toId];
var fromPortNode = fromObj.getPort(fromPort);
var toPortNode = toObj.getPort(toPort);
fromPortNode.connect(toPortNode);
}
if (!root) {
switchCircuit(parentID);
return subScope;
}
}
export default function generateVerilogCircuit(verilogCode, scope = globalScope) {
const url='/simulator/verilogcv';
var params = {"code": verilogCode};
$.ajax({
url: url,
type: 'POST',
beforeSend: function(xhr) {
xhr.setRequestHeader('X-CSRF-Token', $('meta[name="csrf-token"]').attr('content'))
},
data: params,
success: function(response) {
var circuitData = response;
scope.initialize();
for(var id in scope.verilogMetadata.subCircuitScopeIds)
delete scopeList[id];
scope.verilogMetadata.subCircuitScopeIds = [];
scope.verilogMetadata.code = verilogCode;
var subCircuitScope = {};
YosysJSON2CV(circuitData, globalScope, "verilogCircuit", subCircuitScope, true);
changeCircuitName(circuitData.name);
showMessage('Verilog Circuit Successfully Created');
$('#verilogOutput').empty();
},
error: function(XMLHttpRequest, textStatus, errorThrown) {
var errorCode = XMLHttpRequest.status;
if (errorCode == 500) {
showError("Could not connect to Yosys");
}
else {
showError("There is some issue with the code");
var errorMessage = XMLHttpRequest.responseJSON;
$('#verilogOutput').html(errorMessage.message);
}
},
failure: function(err) {
}
});
}
export function setupCodeMirrorEnvironment() {
var myTextarea = document.getElementById("codeTextArea");
CodeMirror.commands.autocomplete = function(cm) {
cm.showHint({hint: CodeMirror.hint.anyword});
}
editor = CodeMirror.fromTextArea(myTextarea, {
mode: "verilog",
autoRefresh:true,
styleActiveLine: true,
lineNumbers: true,
autoCloseBrackets: true,
smartIndent: true,
indentWithTabs: true,
extraKeys: {"Ctrl-Space": "autocomplete"}
});
editor.setValue("// Write Some Verilog Code Here!")
setTimeout(function() {
editor.refresh();
},1);
}