diff --git a/draft.json b/draft.json index 283b3d5..e69de29 100644 --- a/draft.json +++ b/draft.json @@ -1,169 +0,0 @@ -{ - "content": { - "error": [], - "symbols": [ - { - "name": "Main", - "range": { - "end": { - "character": 0, - "line": 31 - }, - "start": { - "character": 0, - "line": 10 - } - }, - "type": "module" - }, - { - "name": "a", - "range": { - "end": { - "character": 17, - "line": 11 - }, - "start": { - "character": 16, - "line": 11 - } - }, - "type": "input" - }, - { - "name": "b", - "range": { - "end": { - "character": 17, - "line": 12 - }, - "start": { - "character": 16, - "line": 12 - } - }, - "type": "input" - }, - { - "name": "c", - "range": { - "end": { - "character": 11, - "line": 13 - }, - "start": { - "character": 10, - "line": 13 - } - }, - "type": "input" - }, - { - "name": "Qus", - "range": { - "end": { - "character": 14, - "line": 14 - }, - "start": { - "character": 11, - "line": 14 - } - }, - "type": "output" - }, - { - "name": "Qs", - "range": { - "end": { - "character": 18, - "line": 14 - }, - "start": { - "character": 16, - "line": 14 - } - }, - "type": "output" - }, - { - "name": "`main_o", - "range": { - "end": { - "character": 27, - "line": 14 - }, - "start": { - "character": 20, - "line": 14 - } - }, - "type": "output" - }, - { - "name": "dependence_1", - "range": { - "end": { - "character": 1, - "line": 22 - }, - "start": { - "character": 0, - "line": 17 - } - }, - "type": "dependence_1" - }, - { - "name": "dependence_2", - "range": { - "end": { - "character": 1, - "line": 29 - }, - "start": { - "character": 0, - "line": 24 - } - }, - "type": "dependence_2" - } - ] - }, - "languageId": "verilog", - "macro": { - "defines": [ - { - "name": "main_o", - "range": { - "end": { - "character": 19, - "line": 9 - }, - "start": { - "character": 1, - "line": 9 - } - }, - "value": "out" - } - ], - "error": [], - "includes": [ - { - "path": "child_1.v", - "range": { - "end": { - "character": 9, - "line": 8 - }, - "start": { - "character": 1, - "line": 8 - } - } - } - ], - "invalid": [] - } - } \ No newline at end of file diff --git a/package.json b/package.json index 4518490..327538a 100644 --- a/package.json +++ b/package.json @@ -93,7 +93,29 @@ "function.doc.pdf.footerTemplate": { "type": "string", "default": "
", - "description": "
/
" + "description": "html template of footer, if displayHeaderFooter is set to false, this setting will be ignored" + }, + "function.simulate.icarus.installPath": { + "type": "string", + "description": "Path of install path of iverilog components, if set to \"\", then iverilog and vvp in environment will be used for simulation. Otherwise, ones that in the install path will be used." + }, + "function.simulate.simulationHome": { + "type": "string", + "description": "Path of simulation folder, .vvp and other file during simulation will be generated here" + }, + "function.simulate.gtkwavePath": { + "type": "string", + "default": "gtkwave", + "description": "Absolute path of launch path of gtkwave software" + }, + "function.simulate.xilinxLibPath": { + "type": "string", + "description": "Path of Xilinx library for simulation" + }, + "function.simulate.runInTerminal": { + "type": "boolean", + "default": false, + "description": "run the simulation command in terminal instead of output" } } }, @@ -136,10 +158,24 @@ "command": "digital-ide.tool.testbench", "title": "%digital-ide.tool.testbench.title%", "category": "Digital-IDE" + }, + { + "command": "digital-ide.tool.icarus.simulateFile", + "title": "%digital-ide.tool.icarus.simulateFile.title%", + "category": "Digital-IDE", + "icon": { + "light": "images/svg/light/debug.svg", + "dark": "images/svg/dark/debug.svg" + } } ], "menus": { "editor/title": [ + { + "when": "editorLangId == verilog || editorLangId == systemverilog || editorLangId == vhdl", + "command": "digital-ide.tool.icarus.simulateFile", + "group": "navigation@1" + }, { "when": "editorLangId == verilog || editorLangId == systemverilog || editorLangId == vhdl", "command": "digital-ide.hdlDoc.showWebview", @@ -149,17 +185,17 @@ }, "keybindings": [ { - "command": "digital-ide.tool.instance", - "key": "alt+i", - "mac": "alt+i", - "when": "editorTextFocus" - }, + "command": "digital-ide.tool.instance", + "key": "alt+i", + "mac": "alt+i", + "when": "editorTextFocus" + }, { - "command": "digital-ide.tool.testbench", - "key": "alt+t", - "mac": "alt+t", - "when": "editorTextFocus" - } + "command": "digital-ide.tool.testbench", + "key": "alt+t", + "mac": "alt+t", + "when": "editorTextFocus" + } ], "languages": [ { @@ -248,7 +284,13 @@ ".dld" ], "configuration": "./config/link.configuration.json" - } + }, + { + "id": "digital-ide-output", + "mimetypes": [ + "text/x-code-output" + ] + } ], "jsonValidation": [ { @@ -286,7 +328,12 @@ "language": "systemverilog", "scopeName": "source.systemverilog", "path": "./syntaxes/systemverilog.json" - } + }, + { + "language": "digital-ide-output", + "scopeName": "digital-ide.output", + "path": "./syntaxes/digital-ide-output.json" + } ], "snippets": [ { diff --git a/package.nls.json b/package.nls.json index e8c0e35..44efe66 100644 --- a/package.nls.json +++ b/package.nls.json @@ -5,5 +5,6 @@ "digital-ide.hdlDoc.exportProject.title": "export the document of current project", "digital-ide.hdlDoc.showWebview.title": "show the document of current file in a webview", "digital-ide.tool.instance.title": "generate instance template from selected module", - "digital-ide.tool.testbench.title": "generate testbench template from current file" + "digital-ide.tool.testbench.title": "generate testbench template from current file", + "digital-ide.tool.icarus.simulateFile.title": "do simulation for current file" } \ No newline at end of file diff --git a/package.nls.zh-cn.json b/package.nls.zh-cn.json index aa23fc5..3fb29a2 100644 --- a/package.nls.zh-cn.json +++ b/package.nls.zh-cn.json @@ -3,7 +3,8 @@ "digital-ide.property-json.overwrite.title": "修改默认的 property.json 模板文件", "digital-ide.hdlDoc.exportFile.title": "导出当前文件的文档", "digital-ide.hdlDoc.exportProject.title": "导出当前项目的文档", - "digital-ide.hdlDoc.showWebview.title": "在webview中展示文档", - "digital-ide.tool.instance.title": "生成选中module的例化模板", - "digital-ide.tool.testbench.title": "从当前文件中选择module生成testbench" + "digital-ide.hdlDoc.showWebview.title": "在 webview 中展示文档", + "digital-ide.tool.instance.title": "生成选中 module 的例化模板", + "digital-ide.tool.testbench.title": "从当前文件中选择 module 生成 testbench", + "digital-ide.tool.icarus.simulateFile.title": "对当前文件进行仿真" } \ No newline at end of file diff --git a/package.nls.zh-tw.json b/package.nls.zh-tw.json index 31c587d..af08476 100644 --- a/package.nls.zh-tw.json +++ b/package.nls.zh-tw.json @@ -5,5 +5,6 @@ "digital-ide.hdlDoc.exportProject.title": "", "digital-ide.hdlDoc.showWebview.title": "", "digital-ide.tool.instance.title": "", - "digital-ide.tool.testbench.title": "" + "digital-ide.tool.testbench.title": "", + "digital-ide.tool.icarus.simulateFile.title": "" } \ No newline at end of file diff --git a/resources/hdlParser/index.js b/resources/hdlParser/index.js index 9dd6084..3d4bf56 100644 --- a/resources/hdlParser/index.js +++ b/resources/hdlParser/index.js @@ -1,5 +1,6 @@ const hdlParser = require('./parser'); const fs = require('fs'); +const { exit } = require('process'); const _hdlParser = { module: null, @@ -25,7 +26,15 @@ async function vlogFast(path) { const source = fs.readFileSync(path, 'utf-8') + '\n'; wasmModule.FS.writeFile(_hdlParser.tempPath, source, { encoding: 'utf8' }); const res = wasmModule.ccall('vlog_fast', 'string', ['string'], [_hdlParser.tempPath]); - return JSON.parse(res); + try { + return JSON.parse(res); + } catch (err) { + console.log(res); + fs.writeFileSync('./draft.json', res); + console.log('error happen when parse ' + path); + console.log(err); + exit(-1); + } } async function vlogAll(path) { diff --git a/src/extension.ts b/src/extension.ts index fd172e5..d94ad9e 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -19,7 +19,7 @@ async function launch(context: vscode.ExtensionContext) { console.timeLog('launch'); await registerCommand(context); - MainOutput.report('Digital-IDE has launched, version: 0.3.0'); + MainOutput.report('Digital-IDE has launched, Version: 0.3.0'); MainOutput.report('OS: ' + opeParam.os); } diff --git a/src/function/index.ts b/src/function/index.ts index 4481a86..e1b47e3 100644 --- a/src/function/index.ts +++ b/src/function/index.ts @@ -13,6 +13,7 @@ function registerDocumentation(context: vscode.ExtensionContext) { function registerSimulation(context: vscode.ExtensionContext) { vscode.commands.registerCommand('digital-ide.tool.instance', Sim.instantiation); vscode.commands.registerCommand('digital-ide.tool.testbench', Sim.testbench); + vscode.commands.registerCommand('digital-ide.tool.icarus.simulateFile', Sim.Icarus.simulateFile); } function registerAllCommands(context: vscode.ExtensionContext) { diff --git a/src/function/lsp/util/completion.js b/src/function/lsp/util/completion.js index eaddeca..8d20abd 100644 --- a/src/function/lsp/util/completion.js +++ b/src/function/lsp/util/completion.js @@ -16,7 +16,7 @@ function filterIncludeFiles(folderPath, currentPath) { const suggestFiles = []; for (const fileName of fs.readdirSync(folderPath)) { const filePath = HDLPath.join(folderPath, fileName); - if (filePath == currentPath) { + if (filePath === currentPath) { continue; } diff --git a/src/function/sim/index.ts b/src/function/sim/index.ts index 19a6ae9..6fba570 100644 --- a/src/function/sim/index.ts +++ b/src/function/sim/index.ts @@ -1,8 +1,9 @@ import { instantiation } from './instance'; import { testbench } from './testbench'; - +import { Icarus } from './simulate'; export { instantiation, - testbench + testbench, + Icarus }; \ No newline at end of file diff --git a/src/function/sim/instance.ts b/src/function/sim/instance.ts index 2c47643..208caf0 100644 --- a/src/function/sim/instance.ts +++ b/src/function/sim/instance.ts @@ -216,6 +216,11 @@ function selectInsert(content: string, editor: vscode.TextEditor): boolean { return true; } +/** + * @description make item for vscode.window.showQuickPick from hdlModules + * @param modules + * @returns + */ function getSelectItem(modules: HdlModule[]) { // make ModuleInfoList const items = []; diff --git a/src/function/sim/simulate.ts b/src/function/sim/simulate.ts new file mode 100644 index 0000000..84bf9d9 --- /dev/null +++ b/src/function/sim/simulate.ts @@ -0,0 +1,347 @@ +import * as vscode from 'vscode'; +import * as child_process from 'child_process'; + +import { hdlParam } from '../../hdlParser'; +import { AbsPath, MainOutput, opeParam, ReportType } from '../../global'; +import { hdlDir, hdlFile, hdlPath } from '../../hdlFs'; +import { getSelectItem } from './instance'; +import { ToolChainType } from '../../global/enum'; +import { HdlModule } from '../../hdlParser/core'; + +interface SimulateConfig { + mod : string, // 设置的顶层模块 + clk : string, // 设置的主频信号 + rst : string, // 设置的复位信号 + end : string, // + wave : string, // wave存放的路径 + simulationHome : string, // sim运行的路径 + gtkwavePath : string, // gtkwave安装路径 + installPath : string // 第三方仿真工具的安装路径 + iverilogPath: string + vvpPath: string +} + +class Simulate { + regExp = { + mod : /\/\/ @ sim.module : (?\w+)/, + clk : /\/\/ @ sim.clk : (?\w+)/, + rst : /\/\/ @ sim.rst : (?\w+)/, + end : /#(?[0-9+])\s+\$(finish|stop)/, + wave : /\$dumpfile\s*\(\s*\"(?.+)\"\s*\);/, + }; + xilinxLib = [ + "xeclib", "unisims" ,"unimacro" ,"unifast" ,"retarget" + ]; + + /** + * @description 获取仿真的配置 + * @param path 代码路径 + * @param tool 仿真工具名 + */ + getConfig(path: AbsPath, tool: string): SimulateConfig | undefined { + let simConfig: SimulateConfig = { + mod : '', + clk : '', // 设置的主频信号 + rst : '', // 设置的复位信号 + end : '', // + wave : '', // wave存放的路径 + simulationHome : '', // sim运行的路径 + gtkwavePath : '', // gtkwave安装路径 + installPath : '', // 第三方仿真工具的安装路径 + iverilogPath: 'iverilog', // iverilog仿真器所在路径 + vvpPath: 'vvp' // vvp解释器所在路径 + }; + let code = hdlFile.readFile(path); + if (!code) { + MainOutput.report('error when read ' + path, ReportType.Error); + return; + } + + for (const element in this.regExp) { + const regGroup = code.match(this.regExp[element as keyof typeof this.regExp])?.groups; + if (regGroup) { + simConfig[element as keyof SimulateConfig] = regGroup[element]; + } + } + + const setting = vscode.workspace.getConfiguration(); + + // make simulation dir + const defaultSimulationDir = hdlPath.join(opeParam.prjInfo.arch.prjPath, 'simulation', 'icarus'); + simConfig.simulationHome = setting.get('function.simulate.simulationHome', ''); + if (!simConfig.simulationHome) { + simConfig.simulationHome = defaultSimulationDir; + } + + if (!hdlFile.isDir(simConfig.simulationHome)) { + hdlDir.mkdir(simConfig.simulationHome); + } + + simConfig.gtkwavePath = setting.get('function.simulate.gtkwavePath', 'gtkwave'); + + if (simConfig.gtkwavePath !== '' && !hdlFile.isDir(simConfig.gtkwavePath)) { + simConfig.gtkwavePath = 'gtkwave'; // 如果不存在则认为是加入了环境变量 + } else { + if (opeParam.os === 'win32') { + simConfig.gtkwavePath = hdlPath.join(simConfig.gtkwavePath, 'gtkwave.exe'); + } else { + simConfig.gtkwavePath = hdlPath.join(simConfig.gtkwavePath, 'gtkwave'); + } + } + + simConfig.installPath = setting.get('function.simulate.icarus.installPath', ''); + if (simConfig.installPath !== '' && !hdlFile.isDir(simConfig.installPath)) { + MainOutput.report(`install path ${simConfig.installPath} is illegal`, ReportType.Error); + return; + } + + return simConfig; + } + + /** + * @description 获取自带仿真库的路径 + * @param toolChain + */ + getSimLibArr(toolChain: ToolChainType): AbsPath[] { + let libPath: AbsPath[] = []; + const setting = vscode.workspace.getConfiguration(); + + // 获取xilinx的自带仿真库的路径 + if (toolChain === ToolChainType.Xilinx) { + const simLibPath = setting.get('function.simulate.xilinxLibPath', ''); + + if (!hdlFile.isDir(simLibPath)) { + return []; + } + const glblPath = hdlPath.join(simLibPath, 'glbl.v'); + libPath.push(glblPath); + for (const element of this.xilinxLib) { + const xilinxPath = hdlPath.join(simLibPath, element); + libPath.push(xilinxPath); + } + } + return libPath; + } +} + +/** + * @description icarus 仿真类 + * + */ +class IcarusSimulate extends Simulate { + os: string; + prjPath: AbsPath; + toolChain: ToolChainType; + + simConfig: SimulateConfig | undefined; + + constructor() { + super(); + this.os = opeParam.os; + this.prjPath = opeParam.prjInfo.arch.prjPath; + this.toolChain = opeParam.prjInfo.toolChain; + } + + /** + * generate acutal iverlog simulation command + * @param name name of top module + * @param path path of the simulated file + * @param dependences dependence that not specified in `include macro + * @returns + */ + private getCommand(name: string, path: AbsPath, dependences: string[]): string | undefined { + const simConfig = this.getConfig(path, 'iverilog'); + if (!simConfig) { + return; + } + this.simConfig = simConfig; + const installPath = simConfig.installPath; + + if (this.os === 'win32') { + simConfig.iverilogPath += '.exe'; + simConfig.vvpPath += '.exe'; + } + + if (hdlFile.isDir(installPath)) { + simConfig.iverilogPath = hdlPath.join(installPath, simConfig.iverilogPath); + simConfig.vvpPath = hdlPath.join(installPath, simConfig.vvpPath); + } + + let dependenceArgs = ''; + dependences.forEach(d => dependenceArgs += '"' + d + '" '); + dependenceArgs = dependenceArgs.trim(); + + let thirdLibPath = ' '; + this.getSimLibArr(this.toolChain).forEach(element => { + if(!hdlFile.isDir(element)) { + thirdLibPath += element + " "; + } else { + thirdLibPath += `-y ${element}`; + } + }); + + const iverilogPath = simConfig.iverilogPath; + const argu = '-g2012'; + const outVvpPath = '"' + hdlPath.join(simConfig.simulationHome, 'out.vvp') + '"'; + const mainPath = '"' + path + '"'; + + const cmd = `${iverilogPath} ${argu} -o ${outVvpPath} -s ${name} ${mainPath} ${dependenceArgs} ${thirdLibPath}`; + MainOutput.report(cmd, ReportType.Run); + return cmd; + } + + private execInTerminal(command: string, cwd: AbsPath) { + // let vvp: vscode.Terminal; + // const targetTerminals = vscode.window.terminals.filter(t => t.name === 'vvp'); + // if (targetTerminals.length > 0) { + // vvp = targetTerminals[0]; + // } else { + // vvp = vscode.window.createTerminal('vvp'); + // } + + // let cmd = `${vvpPath} ${outVvpPath}`; + // if (simConfig.wave !== '') { + // let waveExtname = simConfig.wave.split('.'); + // cmd += '-' + waveExtname[simConfig.wave.length - 1]; + // } + + // vvp.show(true); + // vvp.sendText(cmd); + // if (simConfig.wave !== '') { + // vvp.sendText(`${simConfig.gtkwavePath} ${simConfig.wave}`); + // } else { + // MainOutput.report('There is no wave image path in this testbench', ReportType.Error); + // } + } + + private execInOutput(command: string, cwd: AbsPath) { + const simConfig = this.simConfig; + if (!simConfig) { + return; + } + child_process.exec(command, { cwd }, (error, stdout, stderr) => { + if (error) { + MainOutput.report('Error took place when run ' + command, ReportType.Error); + MainOutput.report('Reason: ' + stderr, ReportType.Error); + } else { + MainOutput.report(stdout, ReportType.Info); + const vvpOutFile = hdlPath.join(simConfig.simulationHome, 'out.vvp'); + MainOutput.report("Create vvp to " + vvpOutFile, ReportType.Run); + + const outVvpPath = hdlPath.join(simConfig.simulationHome, 'out.vvp'); + const vvpPath = simConfig.vvpPath; + + // run vvp to interrupt script + const vvpCommand = `${vvpPath} ${outVvpPath}`; + MainOutput.report(vvpCommand, ReportType.Run); + + child_process.exec(vvpCommand, { cwd }, (error, stdout, stderr) => { + if (error) { + MainOutput.report('Error took place when run ' + vvpCommand, ReportType.Error); + MainOutput.report('Reason: ' + stderr, ReportType.Error); + } else { + MainOutput.report(stdout, ReportType.Info); + } + }); + } + }); + } + + private exec(command: string, cwd: AbsPath) { + const simConfig = this.simConfig; + if (!simConfig) { + MainOutput.report('this.simConfig is empty when exec'); + return; + } + + const runInTerminal = vscode.workspace.getConfiguration().get('function.simulate.runInTerminal'); + console.log(runInTerminal); + + if (runInTerminal) { + this.execInTerminal(command, cwd); + } else { + this.execInOutput(command, cwd); + } + } + + private getAllOtherDependences(path: AbsPath, name: string): AbsPath[] { + const deps = hdlParam.getAllDependences(path, name); + if (deps) { + console.log(deps); + + return deps.others; + } else { + MainOutput.report('Fail to get dependences of path: ' + path + ' name: ' + name, ReportType.Warn); + return []; + } + } + + private simulateByHdlModule(hdlModule: HdlModule) { + const name = hdlModule.name; + const path = hdlModule.path; + if (!hdlParam.isTopModule(path, name, false)) { + MainOutput.report('path: ' + path + ' name: ' + name + ' is not top module'); + return; + } + const dependences = this.getAllOtherDependences(path, name); + const simulationCommand = this.getCommand(name, path, dependences); + if (simulationCommand) { + const cwd = hdlPath.resolve(hdlModule.path, '..'); + this.exec(simulationCommand, cwd); + } else { + MainOutput.report('Fail to generate command', ReportType.Error); + return; + } + } + + + public async simulateModule(hdlModule: HdlModule) { + this.simulateByHdlModule(hdlModule); + } + + public async simulateFile() { + const editor = vscode.window.activeTextEditor; + if (!editor) { + return; + } + const uri = editor.document.uri; + const path = hdlPath.toSlash(uri.fsPath); + + const currentFile = hdlParam.getHdlFile(path); + if (!currentFile) { + MainOutput.report('path ' + path + ' is not a hdlFile', ReportType.Error); + return; + } + const items = getSelectItem(currentFile.getAllHdlModules()); + if (items.length) { + let selectModule: HdlModule; + if (items.length === 1) { + selectModule = items[0].module; + } else { + const select = await vscode.window.showQuickPick(items, {placeHolder: 'choose a top module'}); + if (select) { + selectModule = select.module; + } else { + return; + } + } + this.simulateByHdlModule(selectModule); + } + } +} + +const icarus = new IcarusSimulate(); + +namespace Icarus { + export async function simulateModule(hdlModule: HdlModule) { + await icarus.simulateModule(hdlModule); + } + + export async function simulateFile() { + await icarus.simulateFile(); + } +}; + +export { + Icarus +}; \ No newline at end of file diff --git a/src/function/sim/testbench.ts b/src/function/sim/testbench.ts index dc4c996..01d25b9 100644 --- a/src/function/sim/testbench.ts +++ b/src/function/sim/testbench.ts @@ -41,7 +41,7 @@ function generateTestbenchFile(module: HdlModule) { } try { hdlFile.writeFile(tbDisPath, content); - MainOutput.report("Generate testbench successed"); + MainOutput.report("Generate testbench to " + tbDisPath); } catch (err) { vscode.window.showErrorMessage("Generate testbench failed:" + err); } diff --git a/src/function/treeView/index.ts b/src/function/treeView/index.ts new file mode 100644 index 0000000..e69de29 diff --git a/src/global/outputChannel.ts b/src/global/outputChannel.ts index 01e55d5..d28cefa 100644 --- a/src/global/outputChannel.ts +++ b/src/global/outputChannel.ts @@ -8,7 +8,8 @@ enum ReportType { PathCheck = 'Path Check', Info = 'Info', Warn = 'Warn', - Error = 'Error' + Error = 'Error', + Run = 'Run' }; class Output { @@ -20,14 +21,30 @@ class Output { this._ignoreTypes = ignoreType; } - skipMessage(type: ReportType) : boolean { + private alignTime(s: number): string { + const sstr: string = s + ''; + if (sstr.length === 1) { + return '0' + sstr; + } else { + return sstr; + } + } + + private getCurrentTime() { + const date = new Date(); + const hms = [date.getHours(), date.getMinutes(), date.getSeconds()]; + return hms.map(this.alignTime).join(':'); + } + + private skipMessage(type: ReportType) : boolean { return this._ignoreTypes.includes(type); } - report(message: string | unknown, type: ReportType = ReportType.Info) { + public report(message: string | unknown, type: ReportType = ReportType.Info) { if (!this.skipMessage(type) && message) { this._output.show(true); - this._output.appendLine('[' + type + '] ' + message); + const currentTime = this.getCurrentTime(); + this._output.appendLine('[' + type + ' - ' + currentTime + '] ' + message); } } } diff --git a/src/global/prjInfo.ts b/src/global/prjInfo.ts index cf3a0c5..8c8d7a6 100644 --- a/src/global/prjInfo.ts +++ b/src/global/prjInfo.ts @@ -337,13 +337,19 @@ class PrjInfo implements PrjInfoMeta { const value: K = obj[attr]; let isNull = !Boolean(value); if (typeof value === 'string') { - isNull &&= value === 'none'; + isNull ||= value === 'none'; } if (isNull) { obj[attr] = defaultValue; } } + private checkDirExist(dir: AbsPath) { + if (!fs.existsSync(dir)) { + fs.mkdirSync(dir, { recursive: true }); + } + } + public updateArch(arch?: Arch) { const workspacePath = this._workspacePath; @@ -375,14 +381,21 @@ class PrjInfo implements PrjInfoMeta { this.arch.software.data = join(softwarePath, 'data'); } - // if path is '', set as workspace this.setDefaultValue(this.arch.hardware, 'src', workspacePath); this.setDefaultValue(this.arch.hardware, 'sim', workspacePath); this.setDefaultValue(this.arch.hardware, 'data', workspacePath); - this.setDefaultValue(this.arch.software, 'src', workspacePath); this.setDefaultValue(this.arch.software, 'data', workspacePath); + this.setDefaultValue(this.arch, 'prjPath', workspacePath); + + // check existence + this.checkDirExist(this.arch.hardware.sim); + this.checkDirExist(this.arch.hardware.src); + this.checkDirExist(this.arch.hardware.data); + this.checkDirExist(this.arch.software.src); + this.checkDirExist(this.arch.software.data); + this.checkDirExist(this.arch.prjPath); } public updateLibrary(library?: Library) { diff --git a/src/hdlParser/core.ts b/src/hdlParser/core.ts index 90cda43..afb2104 100644 --- a/src/hdlParser/core.ts +++ b/src/hdlParser/core.ts @@ -186,12 +186,17 @@ class HdlParam { // TODO : only support verilog now const langID = hdlFile.getLanguageId(path); if (langID === HdlLangID.Verilog) { - const fast = await HdlSymbol.fast(path); - if (fast) { - new HdlFile(path, - fast.languageId, - fast.macro, - fast.content.modules); + try { + const fast = await HdlSymbol.fast(path); + if (fast) { + new HdlFile(path, + fast.languageId, + fast.macro, + fast.content.modules); + } + } catch (error) { + MainOutput.report('Error happen when parse ' + path, ReportType.Error); + MainOutput.report('Reason: ' + error, ReportType.Error); } } } diff --git a/syntaxes/digital-ide-output.json b/syntaxes/digital-ide-output.json new file mode 100644 index 0000000..2631569 --- /dev/null +++ b/syntaxes/digital-ide-output.json @@ -0,0 +1,90 @@ +{ + "scopeName": "digital-ide.output", + "name": "digital-ide-output", + "patterns": [ + { + "name": "digital-ide.Info", + "match": "(\\[Info - (.*)\\])(.*)", + "captures": { + "1": { + "name": "token.info-token" + }, + "2": { + "name": "string" + } + } + }, + { + "name": "digital-ide.Error", + "match": "(\\[Error - (.*)\\])(.*)", + "captures": { + "1": { + "name": "token.error-token" + }, + "2": { + "name": "string" + }, + "3": { + "name": "token.error-token" + } + } + }, + { + "name": "digital-ide.Warn", + "match": "(\\[Warn - (.*)\\])(.*)", + "captures": { + "1": { + "name": "token.warn-token" + }, + "2": { + "name": "string" + }, + "3": { + "name": "token.warn-token" + } + } + }, + { + "name": "digital-ide.Debug", + "match": "(\\[Debug - (.*)\\])([\\s\\S]*)", + "captures": { + "1": { + "name": "token.debug-token" + }, + "2": { + "name": "string" + }, + "3": { + "name": "token.debug-token" + } + } + }, + { + "name": "digital-ide.Run", + "match": "(\\[Run - (.*)\\])([\\s\\S]*)", + "captures": { + "1": { + "name": "token.info-token" + }, + "2": { + "name": "string" + } + } + }, + { + "name": "string.quoted.double", + "begin": "\"", + "beginCaptures": { + "0": { + "name": "string" + } + }, + "end": "\"", + "endCaptures": { + "0": { + "name": "string" + } + } + } + ] +} \ No newline at end of file diff --git a/test.js b/test.js index fe81f5b..4e54885 100644 --- a/test.js +++ b/test.js @@ -63,10 +63,12 @@ function* walk(path, condition) { (async() => { console.time('test'); - for (const file of walk('./lib', f => f.endsWith('.v'))) { - console.log(file); + // await vlogFast('./lib/common/Apply/DSP/Advance/FFT/Flow_FFT_IFFT/BF_op.v'); + for (const file of walk('./src/test/vlog/dependence_test', f => f.endsWith('.v'))) { + console.log('[file] ', file); try { - await vlogFast(file); + const res = await vlogFast(file); + console.log(res); } catch (err) { console.log(err); }