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); }