update
This commit is contained in:
parent
01f44548ea
commit
8a3c4b754a
169
draft.json
169
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": []
|
||||
}
|
||||
}
|
49
package.json
49
package.json
@ -93,7 +93,29 @@
|
||||
"function.doc.pdf.footerTemplate": {
|
||||
"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>",
|
||||
"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",
|
||||
"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",
|
||||
@ -248,6 +284,12 @@
|
||||
".dld"
|
||||
],
|
||||
"configuration": "./config/link.configuration.json"
|
||||
},
|
||||
{
|
||||
"id": "digital-ide-output",
|
||||
"mimetypes": [
|
||||
"text/x-code-output"
|
||||
]
|
||||
}
|
||||
],
|
||||
"jsonValidation": [
|
||||
@ -286,6 +328,11 @@
|
||||
"language": "systemverilog",
|
||||
"scopeName": "source.systemverilog",
|
||||
"path": "./syntaxes/systemverilog.json"
|
||||
},
|
||||
{
|
||||
"language": "digital-ide-output",
|
||||
"scopeName": "digital-ide.output",
|
||||
"path": "./syntaxes/digital-ide-output.json"
|
||||
}
|
||||
],
|
||||
"snippets": [
|
||||
|
@ -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"
|
||||
}
|
@ -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": "对当前文件进行仿真"
|
||||
}
|
@ -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": ""
|
||||
}
|
@ -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]);
|
||||
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) {
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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) {
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -1,8 +1,9 @@
|
||||
import { instantiation } from './instance';
|
||||
import { testbench } from './testbench';
|
||||
|
||||
import { Icarus } from './simulate';
|
||||
|
||||
export {
|
||||
instantiation,
|
||||
testbench
|
||||
testbench,
|
||||
Icarus
|
||||
};
|
@ -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 = [];
|
||||
|
347
src/function/sim/simulate.ts
Normal file
347
src/function/sim/simulate.ts
Normal 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
|
||||
};
|
@ -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);
|
||||
}
|
||||
|
0
src/function/treeView/index.ts
Normal file
0
src/function/treeView/index.ts
Normal file
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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) {
|
||||
|
@ -186,6 +186,7 @@ class HdlParam {
|
||||
// TODO : only support verilog now
|
||||
const langID = hdlFile.getLanguageId(path);
|
||||
if (langID === HdlLangID.Verilog) {
|
||||
try {
|
||||
const fast = await HdlSymbol.fast(path);
|
||||
if (fast) {
|
||||
new HdlFile(path,
|
||||
@ -193,6 +194,10 @@ class HdlParam {
|
||||
fast.macro,
|
||||
fast.content.modules);
|
||||
}
|
||||
} catch (error) {
|
||||
MainOutput.report('Error happen when parse ' + path, ReportType.Error);
|
||||
MainOutput.report('Reason: ' + error, ReportType.Error);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
90
syntaxes/digital-ide-output.json
Normal file
90
syntaxes/digital-ide-output.json
Normal 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"
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
8
test.js
8
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);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user