This commit is contained in:
锦恢 2023-03-28 22:44:06 +08:00
parent 01f44548ea
commit 8a3c4b754a
19 changed files with 580 additions and 209 deletions

View File

@ -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": []
}
}

View File

@ -93,7 +93,29 @@
"function.doc.pdf.footerTemplate": { "function.doc.pdf.footerTemplate": {
"type": "string", "type": "string",
"default": "<div style=\"font-size: 9px; margin-left: 1cm;\"> <span class='title'></span></div> <div style=\"font-size: 9px; margin-left: auto; margin-right: 1cm; \"> <span class='date'></span></div>", "default": "<div style=\"font-size: 9px; margin-left: 1cm;\"> <span class='title'></span></div> <div style=\"font-size: 9px; margin-left: auto; margin-right: 1cm; \"> <span class='date'></span></div>",
"description": "<div style=\"font-size: 9px; margin: 0 auto;\"> <span class='pageNumber'></span> / <span class='totalPages'></span></div>" "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", "command": "digital-ide.tool.testbench",
"title": "%digital-ide.tool.testbench.title%", "title": "%digital-ide.tool.testbench.title%",
"category": "Digital-IDE" "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": { "menus": {
"editor/title": [ "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", "when": "editorLangId == verilog || editorLangId == systemverilog || editorLangId == vhdl",
"command": "digital-ide.hdlDoc.showWebview", "command": "digital-ide.hdlDoc.showWebview",
@ -149,17 +185,17 @@
}, },
"keybindings": [ "keybindings": [
{ {
"command": "digital-ide.tool.instance", "command": "digital-ide.tool.instance",
"key": "alt+i", "key": "alt+i",
"mac": "alt+i", "mac": "alt+i",
"when": "editorTextFocus" "when": "editorTextFocus"
}, },
{ {
"command": "digital-ide.tool.testbench", "command": "digital-ide.tool.testbench",
"key": "alt+t", "key": "alt+t",
"mac": "alt+t", "mac": "alt+t",
"when": "editorTextFocus" "when": "editorTextFocus"
} }
], ],
"languages": [ "languages": [
{ {
@ -248,7 +284,13 @@
".dld" ".dld"
], ],
"configuration": "./config/link.configuration.json" "configuration": "./config/link.configuration.json"
} },
{
"id": "digital-ide-output",
"mimetypes": [
"text/x-code-output"
]
}
], ],
"jsonValidation": [ "jsonValidation": [
{ {
@ -286,7 +328,12 @@
"language": "systemverilog", "language": "systemverilog",
"scopeName": "source.systemverilog", "scopeName": "source.systemverilog",
"path": "./syntaxes/systemverilog.json" "path": "./syntaxes/systemverilog.json"
} },
{
"language": "digital-ide-output",
"scopeName": "digital-ide.output",
"path": "./syntaxes/digital-ide-output.json"
}
], ],
"snippets": [ "snippets": [
{ {

View File

@ -5,5 +5,6 @@
"digital-ide.hdlDoc.exportProject.title": "export the document of current project", "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.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.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"
} }

View File

@ -3,7 +3,8 @@
"digital-ide.property-json.overwrite.title": "修改默认的 property.json 模板文件", "digital-ide.property-json.overwrite.title": "修改默认的 property.json 模板文件",
"digital-ide.hdlDoc.exportFile.title": "导出当前文件的文档", "digital-ide.hdlDoc.exportFile.title": "导出当前文件的文档",
"digital-ide.hdlDoc.exportProject.title": "导出当前项目的文档", "digital-ide.hdlDoc.exportProject.title": "导出当前项目的文档",
"digital-ide.hdlDoc.showWebview.title": "在webview中展示文档", "digital-ide.hdlDoc.showWebview.title": "在 webview 中展示文档",
"digital-ide.tool.instance.title": "生成选中module的例化模板", "digital-ide.tool.instance.title": "生成选中 module 的例化模板",
"digital-ide.tool.testbench.title": "从当前文件中选择module生成testbench" "digital-ide.tool.testbench.title": "从当前文件中选择 module 生成 testbench",
"digital-ide.tool.icarus.simulateFile.title": "对当前文件进行仿真"
} }

View File

@ -5,5 +5,6 @@
"digital-ide.hdlDoc.exportProject.title": "", "digital-ide.hdlDoc.exportProject.title": "",
"digital-ide.hdlDoc.showWebview.title": "", "digital-ide.hdlDoc.showWebview.title": "",
"digital-ide.tool.instance.title": "", "digital-ide.tool.instance.title": "",
"digital-ide.tool.testbench.title": "" "digital-ide.tool.testbench.title": "",
"digital-ide.tool.icarus.simulateFile.title": ""
} }

View File

@ -1,5 +1,6 @@
const hdlParser = require('./parser'); const hdlParser = require('./parser');
const fs = require('fs'); const fs = require('fs');
const { exit } = require('process');
const _hdlParser = { const _hdlParser = {
module: null, module: null,
@ -25,7 +26,15 @@ async function vlogFast(path) {
const source = fs.readFileSync(path, 'utf-8') + '\n'; const source = fs.readFileSync(path, 'utf-8') + '\n';
wasmModule.FS.writeFile(_hdlParser.tempPath, source, { encoding: 'utf8' }); wasmModule.FS.writeFile(_hdlParser.tempPath, source, { encoding: 'utf8' });
const res = wasmModule.ccall('vlog_fast', 'string', ['string'], [_hdlParser.tempPath]); 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) { async function vlogAll(path) {

View File

@ -19,7 +19,7 @@ async function launch(context: vscode.ExtensionContext) {
console.timeLog('launch'); console.timeLog('launch');
await registerCommand(context); 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); MainOutput.report('OS: ' + opeParam.os);
} }

View File

@ -13,6 +13,7 @@ function registerDocumentation(context: vscode.ExtensionContext) {
function registerSimulation(context: vscode.ExtensionContext) { function registerSimulation(context: vscode.ExtensionContext) {
vscode.commands.registerCommand('digital-ide.tool.instance', Sim.instantiation); vscode.commands.registerCommand('digital-ide.tool.instance', Sim.instantiation);
vscode.commands.registerCommand('digital-ide.tool.testbench', Sim.testbench); 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) { function registerAllCommands(context: vscode.ExtensionContext) {

View File

@ -16,7 +16,7 @@ function filterIncludeFiles(folderPath, currentPath) {
const suggestFiles = []; const suggestFiles = [];
for (const fileName of fs.readdirSync(folderPath)) { for (const fileName of fs.readdirSync(folderPath)) {
const filePath = HDLPath.join(folderPath, fileName); const filePath = HDLPath.join(folderPath, fileName);
if (filePath == currentPath) { if (filePath === currentPath) {
continue; continue;
} }

View File

@ -1,8 +1,9 @@
import { instantiation } from './instance'; import { instantiation } from './instance';
import { testbench } from './testbench'; import { testbench } from './testbench';
import { Icarus } from './simulate';
export { export {
instantiation, instantiation,
testbench testbench,
Icarus
}; };

View File

@ -216,6 +216,11 @@ function selectInsert(content: string, editor: vscode.TextEditor): boolean {
return true; return true;
} }
/**
* @description make item for vscode.window.showQuickPick from hdlModules
* @param modules
* @returns
*/
function getSelectItem(modules: HdlModule[]) { function getSelectItem(modules: HdlModule[]) {
// make ModuleInfoList // make ModuleInfoList
const items = []; const items = [];

View File

@ -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 : (?<mod>\w+)/,
clk : /\/\/ @ sim.clk : (?<clk>\w+)/,
rst : /\/\/ @ sim.rst : (?<rst>\w+)/,
end : /#(?<end>[0-9+])\s+\$(finish|stop)/,
wave : /\$dumpfile\s*\(\s*\"(?<wave>.+)\"\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
};

View File

@ -41,7 +41,7 @@ function generateTestbenchFile(module: HdlModule) {
} }
try { try {
hdlFile.writeFile(tbDisPath, content); hdlFile.writeFile(tbDisPath, content);
MainOutput.report("Generate testbench successed"); MainOutput.report("Generate testbench to " + tbDisPath);
} catch (err) { } catch (err) {
vscode.window.showErrorMessage("Generate testbench failed:" + err); vscode.window.showErrorMessage("Generate testbench failed:" + err);
} }

View File

View File

@ -8,7 +8,8 @@ enum ReportType {
PathCheck = 'Path Check', PathCheck = 'Path Check',
Info = 'Info', Info = 'Info',
Warn = 'Warn', Warn = 'Warn',
Error = 'Error' Error = 'Error',
Run = 'Run'
}; };
class Output { class Output {
@ -20,14 +21,30 @@ class Output {
this._ignoreTypes = ignoreType; 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); 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) { if (!this.skipMessage(type) && message) {
this._output.show(true); this._output.show(true);
this._output.appendLine('[' + type + '] ' + message); const currentTime = this.getCurrentTime();
this._output.appendLine('[' + type + ' - ' + currentTime + '] ' + message);
} }
} }
} }

View File

@ -337,13 +337,19 @@ class PrjInfo implements PrjInfoMeta {
const value: K = obj[attr]; const value: K = obj[attr];
let isNull = !Boolean(value); let isNull = !Boolean(value);
if (typeof value === 'string') { if (typeof value === 'string') {
isNull &&= value === 'none'; isNull ||= value === 'none';
} }
if (isNull) { if (isNull) {
obj[attr] = defaultValue; obj[attr] = defaultValue;
} }
} }
private checkDirExist(dir: AbsPath) {
if (!fs.existsSync(dir)) {
fs.mkdirSync(dir, { recursive: true });
}
}
public updateArch(arch?: Arch) { public updateArch(arch?: Arch) {
const workspacePath = this._workspacePath; const workspacePath = this._workspacePath;
@ -375,14 +381,21 @@ class PrjInfo implements PrjInfoMeta {
this.arch.software.data = join(softwarePath, 'data'); this.arch.software.data = join(softwarePath, 'data');
} }
// if path is '', set as workspace // if path is '', set as workspace
this.setDefaultValue(this.arch.hardware, 'src', workspacePath); this.setDefaultValue(this.arch.hardware, 'src', workspacePath);
this.setDefaultValue(this.arch.hardware, 'sim', workspacePath); this.setDefaultValue(this.arch.hardware, 'sim', workspacePath);
this.setDefaultValue(this.arch.hardware, 'data', workspacePath); this.setDefaultValue(this.arch.hardware, 'data', workspacePath);
this.setDefaultValue(this.arch.software, 'src', workspacePath); this.setDefaultValue(this.arch.software, 'src', workspacePath);
this.setDefaultValue(this.arch.software, 'data', 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) { public updateLibrary(library?: Library) {

View File

@ -186,12 +186,17 @@ class HdlParam {
// TODO : only support verilog now // TODO : only support verilog now
const langID = hdlFile.getLanguageId(path); const langID = hdlFile.getLanguageId(path);
if (langID === HdlLangID.Verilog) { if (langID === HdlLangID.Verilog) {
const fast = await HdlSymbol.fast(path); try {
if (fast) { const fast = await HdlSymbol.fast(path);
new HdlFile(path, if (fast) {
fast.languageId, new HdlFile(path,
fast.macro, fast.languageId,
fast.content.modules); fast.macro,
fast.content.modules);
}
} catch (error) {
MainOutput.report('Error happen when parse ' + path, ReportType.Error);
MainOutput.report('Reason: ' + error, ReportType.Error);
} }
} }
} }

View File

@ -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"
}
}
}
]
}

View File

@ -63,10 +63,12 @@ function* walk(path, condition) {
(async() => { (async() => {
console.time('test'); console.time('test');
for (const file of walk('./lib', f => f.endsWith('.v'))) { // await vlogFast('./lib/common/Apply/DSP/Advance/FFT/Flow_FFT_IFFT/BF_op.v');
console.log(file); for (const file of walk('./src/test/vlog/dependence_test', f => f.endsWith('.v'))) {
console.log('[file] ', file);
try { try {
await vlogFast(file); const res = await vlogFast(file);
console.log(res);
} catch (err) { } catch (err) {
console.log(err); console.log(err);
} }