From b00c1649e2cd418f22e5a4b0ac6afa3f163617cf Mon Sep 17 00:00:00 2001 From: Kirigaya <1193466151@qq.com> Date: Sat, 16 Nov 2024 22:00:34 +0800 Subject: [PATCH] =?UTF-8?q?=E5=AE=8C=E6=88=90=20PL=20=E7=9A=84=E5=AD=90?= =?UTF-8?q?=E8=BF=9B=E7=A8=8B=E6=8E=A5=E5=85=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- l10n/bundle.l10n.de.json | 10 +- l10n/bundle.l10n.en.json | 10 +- l10n/bundle.l10n.ja.json | 10 +- l10n/bundle.l10n.zh-cn.json | 10 +- l10n/bundle.l10n.zh-tw.json | 10 +- resources/script/xilinx/launch.tcl | 7 - resources/script/xilinx/refresh.tcl | 40 --- src/function/hdlDoc/markdown.ts | 5 +- src/function/lsp/util/feature.ts | 2 +- src/function/tool.ts | 38 ++- src/function/treeView/command.ts | 48 ++-- src/global/outputChannel.ts | 10 +- src/global/util.ts | 12 + src/manager/PL/efinity.ts | 2 +- src/manager/PL/index.ts | 79 +++--- src/manager/PL/xilinx.ts | 378 ++++++++++++++++++---------- syntaxes/digital-ide-output.json | 12 +- 17 files changed, 418 insertions(+), 265 deletions(-) delete mode 100644 resources/script/xilinx/launch.tcl delete mode 100644 resources/script/xilinx/refresh.tcl diff --git a/l10n/bundle.l10n.de.json b/l10n/bundle.l10n.de.json index 5298979..6443a35 100644 --- a/l10n/bundle.l10n.de.json +++ b/l10n/bundle.l10n.de.json @@ -29,5 +29,13 @@ "info.treeview.ip-no-active.message": "当前 IP 还未激活,请通过 Xilinx 工具链将 XCI 文件生成完整的 IP 核", "info.progress.initialize-configure": "初始化项目配置", "info.pl.xilinx.launch.pick-project-placeholder": "Which project you want to open ?", - "error.common.not-valid-hdl-file": "is not a valid hdl file in our parse list, check your property.json to see if arch.hardware.src is set correctly!\\ncurrent parse list: \\n" + "error.common.not-valid-hdl-file": "is not a valid hdl file in our parse list, check your property.json to see if arch.hardware.src is set correctly!\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ncurrent parse list: \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\n", + "info.pl.gui.open-successfully": "GUI open successfully", + "info.pl.gui.report-title": "启动 GUI ...", + "info.pl.exit.title": "正在退出 ...", + "info.pl.add-files.title": "添加如下文件到工程", + "info.pl.del-files.title": "从项目中删除如下文件", + "info.pl.launch.launch-info": "成功启动 Vivado TCL 脚本解释器", + "info.pl.launch.progress.launch-tcl.title": "正在启动 Vivado TCL 脚本解释器", + "warn.command.transform-old-ppy.unknown-hardwarelib-state": "无法转换 HardwareLIB.state ,原因:未知的 state 枚举:" } \ No newline at end of file diff --git a/l10n/bundle.l10n.en.json b/l10n/bundle.l10n.en.json index a0ea9b5..d4a4fbd 100644 --- a/l10n/bundle.l10n.en.json +++ b/l10n/bundle.l10n.en.json @@ -29,5 +29,13 @@ "info.treeview.ip-no-active.message": "当前 IP 还未激活,请通过 Xilinx 工具链将 XCI 文件生成完整的 IP 核", "info.progress.initialize-configure": "初始化项目配置", "info.pl.xilinx.launch.pick-project-placeholder": "Which project you want to open ?", - "error.common.not-valid-hdl-file": "is not a valid hdl file in our parse list, check your property.json to see if arch.hardware.src is set correctly!\\ncurrent parse list: \\n" + "error.common.not-valid-hdl-file": "is not a valid hdl file in our parse list, check your property.json to see if arch.hardware.src is set correctly!\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ncurrent parse list: \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\n", + "info.pl.gui.open-successfully": "GUI open successfully", + "info.pl.gui.report-title": "启动 GUI ...", + "info.pl.exit.title": "正在退出 ...", + "info.pl.add-files.title": "添加如下文件到工程", + "info.pl.del-files.title": "从项目中删除如下文件", + "info.pl.launch.launch-info": "成功启动 Vivado TCL 脚本解释器", + "info.pl.launch.progress.launch-tcl.title": "正在启动 Vivado TCL 脚本解释器", + "warn.command.transform-old-ppy.unknown-hardwarelib-state": "无法转换 HardwareLIB.state ,原因:未知的 state 枚举:" } \ No newline at end of file diff --git a/l10n/bundle.l10n.ja.json b/l10n/bundle.l10n.ja.json index 844ce85..2649df8 100644 --- a/l10n/bundle.l10n.ja.json +++ b/l10n/bundle.l10n.ja.json @@ -29,5 +29,13 @@ "info.treeview.ip-no-active.message": "当前 IP 还未激活,请通过 Xilinx 工具链将 XCI 文件生成完整的 IP 核", "info.progress.initialize-configure": "初始化项目配置", "info.pl.xilinx.launch.pick-project-placeholder": "Which project you want to open ?", - "error.common.not-valid-hdl-file": "is not a valid hdl file in our parse list, check your property.json to see if arch.hardware.src is set correctly!\\ncurrent parse list: \\n" + "error.common.not-valid-hdl-file": "is not a valid hdl file in our parse list, check your property.json to see if arch.hardware.src is set correctly!\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ncurrent parse list: \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\n", + "info.pl.gui.open-successfully": "GUI open successfully", + "info.pl.gui.report-title": "启动 GUI ...", + "info.pl.exit.title": "正在退出 ...", + "info.pl.add-files.title": "添加如下文件到工程", + "info.pl.del-files.title": "从项目中删除如下文件", + "info.pl.launch.launch-info": "成功启动 Vivado TCL 脚本解释器", + "info.pl.launch.progress.launch-tcl.title": "正在启动 Vivado TCL 脚本解释器", + "warn.command.transform-old-ppy.unknown-hardwarelib-state": "无法转换 HardwareLIB.state ,原因:未知的 state 枚举:" } \ No newline at end of file diff --git a/l10n/bundle.l10n.zh-cn.json b/l10n/bundle.l10n.zh-cn.json index 4fde85c..3f85f83 100644 --- a/l10n/bundle.l10n.zh-cn.json +++ b/l10n/bundle.l10n.zh-cn.json @@ -29,5 +29,13 @@ "info.treeview.ip-no-active.message": "当前 IP 还未激活,请通过 Xilinx 工具链将 XCI 文件生成完整的 IP 核", "info.progress.initialize-configure": "初始化项目配置", "info.pl.xilinx.launch.pick-project-placeholder": "请选择需要打开的工程", - "error.common.not-valid-hdl-file": "并不在系统的解析列表中,请检查你的 property.json 配置文件中的 arch.hardware.src 是否被正确设置。当前的解析路径为:" + "error.common.not-valid-hdl-file": "并不在系统的解析列表中,请检查你的 property.json 配置文件中的 arch.hardware.src 是否被正确设置。当前的解析路径为:", + "info.pl.gui.open-successfully": "GUI 启动成功", + "info.pl.gui.report-title": "启动 GUI ...", + "info.pl.exit.title": "正在退出 ...", + "info.pl.add-files.title": "添加如下文件到工程", + "info.pl.del-files.title": "从项目中删除如下文件", + "info.pl.launch.launch-info": "成功启动 Vivado TCL 脚本解释器", + "info.pl.launch.progress.launch-tcl.title": "正在启动 Vivado TCL 脚本解释器", + "warn.command.transform-old-ppy.unknown-hardwarelib-state": "无法转换 HardwareLIB.state ,原因:未知的 state 枚举:" } \ No newline at end of file diff --git a/l10n/bundle.l10n.zh-tw.json b/l10n/bundle.l10n.zh-tw.json index f820a42..3082509 100644 --- a/l10n/bundle.l10n.zh-tw.json +++ b/l10n/bundle.l10n.zh-tw.json @@ -29,5 +29,13 @@ "info.treeview.ip-no-active.message": "当前 IP 还未激活,请通过 Xilinx 工具链将 XCI 文件生成完整的 IP 核", "info.progress.initialize-configure": "初始化项目配置", "info.pl.xilinx.launch.pick-project-placeholder": "Which project you want to open ?", - "error.common.not-valid-hdl-file": "is not a valid hdl file in our parse list, check your property.json to see if arch.hardware.src is set correctly!\\ncurrent parse list: \\n" + "error.common.not-valid-hdl-file": "is not a valid hdl file in our parse list, check your property.json to see if arch.hardware.src is set correctly!\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ncurrent parse list: \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\n", + "info.pl.gui.open-successfully": "GUI open successfully", + "info.pl.gui.report-title": "启动 GUI ...", + "info.pl.exit.title": "正在退出 ...", + "info.pl.add-files.title": "添加如下文件到工程", + "info.pl.del-files.title": "从项目中删除如下文件", + "info.pl.launch.launch-info": "成功启动 Vivado TCL 脚本解释器", + "info.pl.launch.progress.launch-tcl.title": "正在启动 Vivado TCL 脚本解释器", + "warn.command.transform-old-ppy.unknown-hardwarelib-state": "无法转换 HardwareLIB.state ,原因:未知的 state 枚举:" } \ No newline at end of file diff --git a/resources/script/xilinx/launch.tcl b/resources/script/xilinx/launch.tcl deleted file mode 100644 index 30a83d4..0000000 --- a/resources/script/xilinx/launch.tcl +++ /dev/null @@ -1,7 +0,0 @@ -set_param general.maxThreads 8 -create_project template /home/dide/project/Digital-Test/DIDEtemp/prj/xilinx -part none -force -set_property SOURCE_SET sources_1 [get_filesets sim_1] -set_property top_lib xil_defaultlib [get_filesets sim_1] -update_compile_order -fileset sim_1 -quiet -source /home/dide/project/Digital-IDE/resources/script/xilinx/refresh.tcl -quiet -file delete /home/dide/project/Digital-IDE/resources/script/xilinx/launch.tcl -force diff --git a/resources/script/xilinx/refresh.tcl b/resources/script/xilinx/refresh.tcl deleted file mode 100644 index 04066fa..0000000 --- a/resources/script/xilinx/refresh.tcl +++ /dev/null @@ -1,40 +0,0 @@ -remove_files -quiet [get_files] -set xip_repo_paths {} -set_property ip_repo_paths $xip_repo_paths [current_project] -quiet -update_ip_catalog -quiet -add_files /home/dide/project/Digital-Test/DIDEtemp/user/ip/xfft_v9/xfft_v9.xci -quiet -add_files /home/dide/project/Digital-Test/DIDEtemp/user/src/ifft/bimpy.v -quiet -add_files -fileset sim_1 /home/dide/project/Digital-Test/DIDEtemp/user/src/ifft/bimpy.v -quiet -add_files /home/dide/project/Digital-Test/DIDEtemp/user/src/ifft/bitreverse.v -quiet -add_files -fileset sim_1 /home/dide/project/Digital-Test/DIDEtemp/user/src/ifft/bitreverse.v -quiet -add_files /home/dide/project/Digital-Test/DIDEtemp/user/src/ifft/butterfly.v -quiet -add_files -fileset sim_1 /home/dide/project/Digital-Test/DIDEtemp/user/src/ifft/butterfly.v -quiet -add_files /home/dide/project/Digital-Test/DIDEtemp/user/src/ifft/convround.v -quiet -add_files -fileset sim_1 /home/dide/project/Digital-Test/DIDEtemp/user/src/ifft/convround.v -quiet -add_files /home/dide/project/Digital-Test/DIDEtemp/user/src/ifft/hwbfly.v -quiet -add_files -fileset sim_1 /home/dide/project/Digital-Test/DIDEtemp/user/src/ifft/hwbfly.v -quiet -add_files /home/dide/project/Digital-Test/DIDEtemp/user/src/ifft/ifftmain.v -quiet -add_files -fileset sim_1 /home/dide/project/Digital-Test/DIDEtemp/user/src/ifft/ifftmain.v -quiet -add_files /home/dide/project/Digital-Test/DIDEtemp/user/src/ifft/ifftstage.v -quiet -add_files -fileset sim_1 /home/dide/project/Digital-Test/DIDEtemp/user/src/ifft/ifftstage.v -quiet -add_files /home/dide/project/Digital-Test/DIDEtemp/user/src/ifft/laststage.v -quiet -add_files -fileset sim_1 /home/dide/project/Digital-Test/DIDEtemp/user/src/ifft/laststage.v -quiet -add_files /home/dide/project/Digital-Test/DIDEtemp/user/src/ifft/longbimpy.v -quiet -add_files -fileset sim_1 /home/dide/project/Digital-Test/DIDEtemp/user/src/ifft/longbimpy.v -quiet -add_files /home/dide/project/Digital-Test/DIDEtemp/user/src/ifft/qtrstage.v -quiet -add_files -fileset sim_1 /home/dide/project/Digital-Test/DIDEtemp/user/src/ifft/qtrstage.v -quiet -add_files -fileset sim_1 /home/dide/project/Digital-Test/DIDEtemp/user/sim/FFT_IFFT_tb.v -quiet -add_files -fileset sim_1 /home/dide/project/Digital-IDE/library/Basic/Math/Advance/FFT/Flow/FFT_IFFT.v -quiet -add_files -fileset sim_1 /home/dide/project/Digital-IDE/library/Basic/Math/Advance/FFT/Flow/stage/BF_stage.v -quiet -add_files -fileset sim_1 /home/dide/project/Digital-IDE/library/Basic/Math/Advance/FFT/Flow/stage/fft_stage.v -quiet -add_files -fileset sim_1 /home/dide/project/Digital-IDE/library/Basic/Math/Advance/FFT/Flow/top/fft.v -quiet -add_files -fileset sim_1 /home/dide/project/Digital-IDE/library/Basic/Math/Advance/FFT/Flow/top/ifft.v -quiet -add_files -fileset sim_1 /home/dide/project/Digital-IDE/library/Basic/Math/Advance/FFT/Flow/utils/ftrans.v -quiet -add_files -fileset sim_1 /home/dide/project/Digital-IDE/library/Basic/Math/Advance/FFT/Flow/utils/ftwiddle.v -quiet -add_files -fileset sim_1 /home/dide/project/Digital-IDE/library/Basic/Memory/SRAM/Shift/shiftTaps.v -quiet -add_files -fileset sim_1 /home/dide/project/Digital-IDE/library/Basic/Math/Advance/Complex/cmplAdsu.v -quiet -add_files -fileset sim_1 /home/dide/project/Digital-IDE/library/Basic/Math/Advance/Complex/cmplMult.v -quiet -add_files -fileset sim_1 /home/dide/project/Digital-IDE/library/Basic/Memory/SRAM/SDPRAM.v -quiet -add_files -fileset sim_1 /home/dide/project/Digital-IDE/library/Basic/Math/Advance/Complex/cordic.v -quiet -add_files -fileset constrs_1 /home/dide/project/Digital-Test/DIDEtemp/user/data -quiet -file delete /home/dide/project/Digital-IDE/resources/script/xilinx/refresh.tcl -force diff --git a/src/function/hdlDoc/markdown.ts b/src/function/hdlDoc/markdown.ts index 21d67f4..3da237e 100644 --- a/src/function/hdlDoc/markdown.ts +++ b/src/function/hdlDoc/markdown.ts @@ -159,13 +159,16 @@ async function getDocsFromModule(module: HdlModule): Promise { ['Port Name', 'Direction', 'Range', 'Description']); md.addEnter(); - + // dependency section md.addTitle('Dependency', 2); const insts = []; for (const inst of module.getAllInstances()) { insts.push(inst); } + console.log('文档化 debug'); + console.log(insts); + makeTableFromObjArray(md, insts, 'Dependencies', ['name', 'type', 'instModPath'], ['name', 'module', 'path']); diff --git a/src/function/lsp/util/feature.ts b/src/function/lsp/util/feature.ts index 055aabf..7f2cfbd 100644 --- a/src/function/lsp/util/feature.ts +++ b/src/function/lsp/util/feature.ts @@ -128,7 +128,7 @@ function bin2float(bin: string, exp: number, fra: number): number | undefined { function getFullSymbolInfoVlog(document: vscode.TextDocument, range: Range) { const comments = []; - const currentLine = range.start.line - 1; + const currentLine = range.start.line; const currentText = document.lineAt(currentLine).text; // 往上找到第一个非空行 diff --git a/src/function/tool.ts b/src/function/tool.ts index 1bb3656..dc5e9c8 100644 --- a/src/function/tool.ts +++ b/src/function/tool.ts @@ -27,7 +27,13 @@ const PPY_REPLACE: Record = { SOC: 'soc', SOC_MODE: 'soc', enableShowlog: 'enableShowLog', - Device: 'device' + Device: 'device', + HardwareLIB: 'library' +}; + +const HARDWARD_LIB_STATE_REPLACE: Record = { + virtual: 'remote', + real: 'local' }; const PPY_ARCH_REPLACE: Record = { @@ -41,6 +47,7 @@ const PPY_LIB_REPLACE: Record = { }; async function transformOldPpy() { + const { t } = vscode.l10n; const propertyJsonPath = opeParam.propertyJsonPath; if (fs.existsSync(propertyJsonPath)) { const oldPpyContent = hdlFile.readJSON(propertyJsonPath) as Record; @@ -56,6 +63,9 @@ async function transformOldPpy() { if (oldPpyContent.library) { for (const oldName of Object.keys(PPY_LIB_REPLACE)) { const newName = PPY_LIB_REPLACE[oldName]; + if (typeof newName !== 'string') { + continue; + } oldPpyContent.library[newName] = oldPpyContent.library[oldName]; delete oldPpyContent.library[oldName]; } @@ -73,6 +83,32 @@ async function transformOldPpy() { delete oldPpyContent.soc['soc']; } + // 老版本的是 SOC_MODE.bd_file,新版本需要变成 soc.bd + if (oldPpyContent.soc && oldPpyContent.soc.bd_file !== undefined) { + oldPpyContent.soc.bd = oldPpyContent.soc.bd_file; + delete oldPpyContent.soc['bd_file']; + } + + // 老版本的是 HardwareLIB,新版本需要变成 library + if (oldPpyContent.library) { + // 老版本的是 "state": "virtual" + if (oldPpyContent.library.state) { + const newState = HARDWARD_LIB_STATE_REPLACE[oldPpyContent.library.state]; + if (typeof newState === 'string') { + oldPpyContent.library.state = newState; + } else { + vscode.window.showWarningMessage(t('warn.command.transform-old-ppy.unknown-hardwarelib-state') + oldPpyContent.library.state); + } + } + // 老版本的是 HardwareLIB.common , 新版本是 library.hardware.common + if (oldPpyContent.library.common) { + oldPpyContent.library.hardware = { + common: oldPpyContent.library.common + }; + delete oldPpyContent.library['common']; + } + } + hdlFile.writeJSON(propertyJsonPath, oldPpyContent); } else { diff --git a/src/function/treeView/command.ts b/src/function/treeView/command.ts index 6c7e250..a9e88de 100644 --- a/src/function/treeView/command.ts +++ b/src/function/treeView/command.ts @@ -196,28 +196,13 @@ class ToolTreeProvider extends BaseCommandTreeProvider { } public async clean() { - console.log('current removed'); - return; - const workspacePath = opeParam.workspacePath; - // remove prjPath & .xil - const prjPath = opeParam.prjInfo.arch.prjPath; - - const xilFolder = hdlPath.join(workspacePath, '.Xil'); - - if (prjPath !== opeParam.workspacePath) { - hdlDir.rmdir(prjPath); - hdlDir.rmdir(xilFolder); - MainOutput.report("remove dir : " + prjPath); - MainOutput.report("remove dir : " + xilFolder); - } else { - vscode.window.showWarningMessage("arch.prjPath is the same as the workspace path, the clean will delete the project, please check your arch.prjPath!"); - } - // move bd * ip const plName = opeParam.prjInfo.prjName.PL; const targetPath = fspath.dirname(opeParam.prjInfo.arch.hardware.src); + + // TODO: 适配更多的 toolChain const sourceIpPath = `${workspacePath}/prj/xilinx/${plName}.srcs/sources_1/ip`; const sourceBdPath = `${workspacePath}/prj/xilinx/${plName}.srcs/sources_1/bd`; @@ -226,18 +211,27 @@ class ToolTreeProvider extends BaseCommandTreeProvider { hdlDir.mvdir(sourceBdPath, targetPath, true); MainOutput.report("move dir from " + sourceBdPath + " to " + targetPath); + + // if (prjPath !== opeParam.workspacePath) { + // hdlDir.rmdir(prjPath); + // hdlDir.rmdir(xilFolder); + // MainOutput.report("remove dir : " + prjPath); + // MainOutput.report("remove dir : " + xilFolder); + // } else { + // vscode.window.showWarningMessage("arch.prjPath is the same as the workspace path, the clean will delete the project, please check your arch.prjPath!"); + // } - const ignores = hdlIgnore.getIgnoreFiles(); - const strFiles = hdlFile.pickFileRecursive(workspacePath, ignores, p => p.endsWith('.str')); - for (const path of strFiles) { - hdlFile.removeFile(path); - MainOutput.report("remove file " + path); - } + // const ignores = hdlIgnore.getIgnoreFiles(); + // const strFiles = hdlFile.pickFileRecursive(workspacePath, ignores, p => p.endsWith('.str')); + // for (const path of strFiles) { + // hdlFile.removeFile(path); + // MainOutput.report("remove file " + path); + // } - const logFiles = hdlFile.pickFileRecursive(workspacePath, ignores, p => p.endsWith('.log')); - for (const path of logFiles) { - hdlFile.readFile(path); - } + // const logFiles = hdlFile.pickFileRecursive(workspacePath, ignores, p => p.endsWith('.log')); + // for (const path of logFiles) { + // hdlFile.readFile(path); + // } MainOutput.report('finish digital-ide.tool.clean'); } diff --git a/src/global/outputChannel.ts b/src/global/outputChannel.ts index c574233..c3d018b 100644 --- a/src/global/outputChannel.ts +++ b/src/global/outputChannel.ts @@ -71,17 +71,25 @@ class Output { public show() { this._output.show(true); } + + public clear() { + this._output.clear(); + } } const MainOutput = new Output('Digital-IDE'); const LspOutput = new Output('Digital-IDE Linter'); const YosysOutput = new Output('Digital-IDE Yosys'); const WaveViewOutput = new Output('Digital-IDE Wave Viewer'); +const HardwareOutput = new Output('Digital-IDE Hareware'); +const HardwareErrorOutput = new Output('Digital-IDE Hareware Error'); export { ReportType, MainOutput, LspOutput, YosysOutput, - WaveViewOutput + WaveViewOutput, + HardwareOutput, + HardwareErrorOutput }; \ No newline at end of file diff --git a/src/global/util.ts b/src/global/util.ts index 066d7d1..64eb46e 100644 --- a/src/global/util.ts +++ b/src/global/util.ts @@ -102,3 +102,15 @@ export function replacePlaceholders(template: string, ...args: string[]): string }); } +export function debounce(fn: (...args: any[]) => any, timeout: number) { + let timer: NodeJS.Timeout | undefined = undefined; + + return (...args: any[]) => { + if (timer) { + clearTimeout(timer); + } + timer = setTimeout(() => { + fn(...args); + }, timeout); + }; +} \ No newline at end of file diff --git a/src/manager/PL/efinity.ts b/src/manager/PL/efinity.ts index 56a9ae3..ffa6fca 100644 --- a/src/manager/PL/efinity.ts +++ b/src/manager/PL/efinity.ts @@ -4,6 +4,6 @@ export async function generateEfinityConfig() { } -class EfinityOperation { +export class EfinityOperation { } \ No newline at end of file diff --git a/src/manager/PL/index.ts b/src/manager/PL/index.ts index 6403655..dfe9d68 100644 --- a/src/manager/PL/index.ts +++ b/src/manager/PL/index.ts @@ -4,7 +4,7 @@ */ import * as vscode from 'vscode'; -import { PLConfig, XilinxOperation } from './xilinx'; +import { PLContext, XilinxOperation } from './xilinx'; import { BaseManage } from '../common'; import { opeParam } from '../../global'; import { ToolChainType } from '../../global/enum'; @@ -12,108 +12,105 @@ import { hdlFile, hdlPath } from '../../hdlFs'; import { moduleTreeProvider, ModuleDataItem } from '../../function/treeView/tree'; import { HdlFileType } from '../../hdlParser/common'; import { PropertySchema } from '../../global/propertySchema'; +import { HardwareOutput, ReportType } from '../../global/outputChannel'; class PlManage extends BaseManage { - config: PLConfig; + context: PLContext; constructor() { super(); - this.config = { - tool: 'default', + + this.context = { + tool: opeParam.prjInfo.toolChain || 'xilinx', path: '', ope: new XilinxOperation(), - terminal: null + terminal: undefined, + process: undefined }; - if (opeParam.prjInfo.toolChain) { - this.config.tool = opeParam.prjInfo.toolChain; - } - - const curToolChain = this.config.tool; + const curToolChain = this.context.tool; if (curToolChain === ToolChainType.Xilinx) { const vivadoPath = vscode.workspace.getConfiguration('digital-ide.prj.vivado.install').get('path', ''); if (hdlFile.isDir(vivadoPath)) { - this.config.path = hdlPath.join(hdlPath.toSlash(vivadoPath), 'vivado'); + this.context.path = hdlPath.join(hdlPath.toSlash(vivadoPath), 'vivado'); if (opeParam.os === 'win32') { - this.config.path += '.bat'; + this.context.path += '.bat'; } } else { - this.config.path = 'vivado'; + this.context.path = 'vivado'; } } } public launch() { - this.config.terminal = this.createTerminal('Hardware'); - this.config.terminal.show(true); - this.config.ope.launch(this.config); + this.context.ope.launch(this.context); } public simulate() { - if (!this.config.terminal) { + if (this.context.process === undefined) { return; } - this.config.ope.simulate(this.config); + this.context.ope.simulate(this.context); } public simulateCli() { - this.config.ope.simulateCli(this.config); + this.context.ope.simulateCli(this.context); } public simulateGui() { - this.config.ope.simulateGui(this.config); + this.context.ope.simulateGui(this.context); } public refresh() { - if (!this.config.terminal) { + if (this.context.process === undefined) { return; } - this.config.ope.refresh(this.config.terminal); + this.context.ope.refresh(this.context); } public build() { - this.config.ope.build(this.config); + this.context.ope.build(this.context); } - public synth() { - this.config.ope.synth(this.config); + this.context.ope.synth(this.context); } public impl() { - if (!this.config.terminal) { + if (this.context.process === undefined) { return null; } - - this.config.ope.impl(this.config); + this.context.ope.impl(this.context); } public bitstream() { - this.config.ope.generateBit(this.config); + this.context.ope.generateBit(this.context); } public program() { - this.config.ope.program(this.config); + this.context.ope.program(this.context); } public gui() { - this.config.ope.gui(this.config); + this.context.ope.gui(this.context); } public exit() { - if (!this.config.terminal) { - return null; + const { t } = vscode.l10n; + + if (this.context.process === undefined) { + return; } - this.config.terminal.show(true); - this.config.terminal.sendText(`exit`); - this.config.terminal.sendText(`exit`); - this.config.terminal = null; + HardwareOutput.show(); + this.context.process.stdin.write('exit\n'); + HardwareOutput.report(t('info.pl.exit.title'), ReportType.Info); + this.context.process = undefined; } public setSrcTop(item: ModuleDataItem) { - this.config.ope.setSrcTop(item.name, this.config); + this.context.ope.setSrcTop(item.name, this.context); const type = moduleTreeProvider.getItemType(item); if (type === HdlFileType.Src) { moduleTreeProvider.setFirstTop(HdlFileType.Src, item.name, item.path); @@ -122,7 +119,7 @@ class PlManage extends BaseManage { } public setSimTop(item: ModuleDataItem) { - this.config.ope.setSimTop(item.name, this.config); + this.context.ope.setSimTop(item.name, this.context); const type = moduleTreeProvider.getItemType(item); if (type === HdlFileType.Sim) { moduleTreeProvider.setFirstTop(HdlFileType.Sim, item.name, item.path); @@ -132,11 +129,11 @@ class PlManage extends BaseManage { async addFiles(files: string[]) { - this.config.ope.addFiles(files, this.config); + this.context.ope.addFiles(files, this.context); } async delFiles(files: string[]) { - this.config.ope.delFiles(files, this.config); + this.context.ope.delFiles(files, this.context); } async addDevice() { diff --git a/src/manager/PL/xilinx.ts b/src/manager/PL/xilinx.ts index 195fab7..cbc8315 100644 --- a/src/manager/PL/xilinx.ts +++ b/src/manager/PL/xilinx.ts @@ -1,6 +1,6 @@ /* eslint-disable @typescript-eslint/naming-convention */ import * as vscode from 'vscode'; -import { exec } from 'child_process'; +import { ChildProcessWithoutNullStreams, exec, spawn } from 'child_process'; import * as fspath from 'path'; import * as fs from 'fs'; @@ -10,7 +10,8 @@ import { hdlFile, hdlDir, hdlPath } from '../../hdlFs'; import { PropertySchema } from '../../global/propertySchema'; import { XilinxIP } from '../../global/enum'; -import { MainOutput } from '../../global/outputChannel'; +import { HardwareOutput, MainOutput, ReportType } from '../../global/outputChannel'; +import { debounce } from '../../global/util'; interface XilinxCustom { ipRepo: AbsPath, @@ -22,10 +23,17 @@ interface TopMod { sim: string }; -interface PLConfig { - terminal : vscode.Terminal | null, - tool? : string, // 工具类型 - path? : string, // 第三方工具运行路径 +// Programmable Logic Context for short +interface PLContext { + // 保留启动上下文 + terminal? : vscode.Terminal, + // 目前使用的启动上下文 + process?: ChildProcessWithoutNullStreams, + // 工具类型 + tool? : string, + // 第三方工具运行路径 + path? : string, + // 操作类 ope : XilinxOperation, }; @@ -128,17 +136,12 @@ class XilinxOperation { /** * xilinx下的launch运行,打开存在的工程或者再没有工程时进行新建 - * @param config + * @param context */ - async launch(config: PLConfig): Promise { + public async launch(context: PLContext): Promise { const { t } = vscode.l10n; this.guiLaunched = false; - const vivadoTerminal = config.terminal; - if (!vivadoTerminal) { - return undefined; - } - let scripts: string[] = []; let prjFilePath = this.prjPath as AbsPath; @@ -173,17 +176,96 @@ class XilinxOperation { scripts.push(this.getRefreshCmd()); scripts.push(`file delete ${tclPath} -force`); const tclCommands = scripts.join('\n') + '\n'; - hdlFile.writeFile(tclPath, tclCommands); const argu = `-notrace -nolog -nojournal`; - const cmd = `${config.path} -mode tcl -s ${tclPath} ${argu}`; + const cmd = `${context.path} -mode tcl -s ${tclPath} ${argu}`; - vivadoTerminal.show(true); - vivadoTerminal.sendText(cmd); + + const _this = this; + + const onVivadoClose = debounce(() => { + _this.onVivadoClose(); + }, 200); + + function launchScript(): Promise { + // 执行 cmd 启动 + const vivadoProcess = spawn(cmd, [], { shell: true, stdio: 'pipe' }); + + vivadoProcess.on('close', () => { + onVivadoClose(); + }); + vivadoProcess.on('exit', () => { + onVivadoClose(); + }); + vivadoProcess.on('disconnect', () => { + onVivadoClose(); + }); + + vivadoProcess.stderr.on('data', data => { + HardwareOutput.report(data.toString(), ReportType.Error); + HardwareOutput.show(); + }); + + let status: 'pending' | 'fulfilled' = 'pending'; + + return new Promise(resolve => { + vivadoProcess.stdout.on('data', data => { + const message: string = _this.handleMessage(data.toString(), status); + if (status === 'pending') { + HardwareOutput.clear(); + HardwareOutput.show(); + resolve(vivadoProcess); + } + HardwareOutput.report(message, ReportType.Info); + status = 'fulfilled'; + }); + }); + } + + const process = await vscode.window.withProgress({ + title: t('info.pl.launch.progress.launch-tcl.title'), + location: vscode.ProgressLocation.Notification + }, async () => { + return await launchScript(); + }); + + context.process = process; } - create(scripts: string[]) { + private handleMessage(message: string, status: 'pending' | 'fulfilled'): string { + if (status === 'fulfilled') { + return message.trim(); + } else { + const messageBuffer: string[] = []; + for (const line of message.trim().split('\n')) { + if (line.startsWith('source') && line.includes('.tcl')) { + continue; + } + messageBuffer.push(line); + } + const launchInfo = vscode.l10n.t('info.pl.launch.launch-info'); + messageBuffer.unshift(launchInfo); + return messageBuffer.join("\n"); + } + } + + private onVivadoClose() { + const workspacePath = opeParam.workspacePath; + const plName = opeParam.prjInfo.prjName.PL; + const targetPath = fspath.dirname(opeParam.prjInfo.arch.hardware.src); + + const sourceIpPath = `${workspacePath}/prj/xilinx/${plName}.srcs/sources_1/ip`; + const sourceBdPath = `${workspacePath}/prj/xilinx/${plName}.srcs/sources_1/bd`; + + hdlDir.mvdir(sourceIpPath, targetPath, true); + HardwareOutput.report("move dir from " + sourceIpPath + " to " + targetPath); + + hdlDir.mvdir(sourceBdPath, targetPath, true); + HardwareOutput.report("move dir from " + sourceBdPath + " to " + targetPath); + } + + public create(scripts: string[]) { scripts.push(`set_param general.maxThreads 8`); scripts.push(`create_project ${this.prjInfo.name} ${this.prjInfo.path} -part ${this.prjInfo.device} -force`); scripts.push(`set_property SOURCE_SET sources_1 [get_filesets sim_1]`); @@ -191,7 +273,7 @@ class XilinxOperation { scripts.push(`update_compile_order -fileset sim_1 -quiet`); } - open(path: AbsPath, scripts: string[]) { + public open(path: AbsPath, scripts: string[]) { scripts.push(`set_param general.maxThreads 8`); scripts.push(`open_project ${path} -quiet`); } @@ -305,68 +387,75 @@ class XilinxOperation { return cmd; } - refresh(terminal: vscode.Terminal) { + public refresh(context: PLContext) { const cmd = this.getRefreshCmd(); - terminal.sendText(cmd); + context.process?.stdin.write(cmd + '\n'); } - simulate(config: PLConfig) { - this.simulateCli(config); + public simulate(context: PLContext) { + this.simulateCli(context); } - simulateGui(config: PLConfig) { + public simulateGui(context: PLContext) { const scriptPath = `${this.xilinxPath}/simulate.tcl`; + const script = ` - if {[current_sim] != ""} { - relaunch_sim -quiet - } else { - launch_simulation -quiet - } +if {[current_sim] != ""} { + relaunch_sim -quiet +} else { + launch_simulation -quiet +} - set curr_wave [current_wave_config] - if { [string length $curr_wave] == 0 } { - if { [llength [get_objects]] > 0} { - add_wave / - set_property needs_save false [current_wave_config] - } else { - send_msg_id Add_Wave-1 WARNING "No top level signals found. Simulator will start without a wave window. If you want to open a wave window go to 'File->New Waveform Configuration' or type 'create_wave_config' in the TCL console." - } - } - run 1us +set curr_wave [current_wave_config] +if { [string length $curr_wave] == 0 } { + if { [llength [get_objects]] > 0} { + add_wave / + set_property needs_save false [current_wave_config] + } else { + send_msg_id Add_Wave-1 WARNING "No top level signals found. Simulator will start without a wave window. If you want to open a wave window go to 'File->New Waveform Configuration' or type 'create_wave_config' in the TCL console." + } +} +run 1us + +start_gui -quiet +file delete ${scriptPath} -force\n`; - start_gui -quiet - file delete ${scriptPath} -force\n`; hdlFile.writeFile(scriptPath, script); const cmd = `source ${scriptPath} -quiet`; - config.terminal?.sendText(cmd); + + HardwareOutput.report('simulateGui'); + context.process?.stdin.write(cmd + '\n'); } - simulateCli(config: PLConfig) { + public simulateCli(context: PLContext) { const scriptPath = hdlPath.join(this.xilinxPath, 'simulate.tcl'); const script = ` - if {[current_sim] != ""} { - relaunch_sim -quiet - } else { - launch_simulation -quiet - } +if {[current_sim] != ""} { + relaunch_sim -quiet +} else { + launch_simulation -quiet +} + +set curr_wave [current_wave_config] +if { [string length $curr_wave] == 0 } { + if { [llength [get_objects]] > 0} { + add_wave / + set_property needs_save false [current_wave_config] + } else { + send_msg_id Add_Wave-1 WARNING "No top level signals found. Simulator will start without a wave window. If you want to open a wave window go to 'File->New Waveform Configuration' or type 'create_wave_config' in the TCL console." + } +} +run 1us +file delete ${scriptPath} -force\n`; - set curr_wave [current_wave_config] - if { [string length $curr_wave] == 0 } { - if { [llength [get_objects]] > 0} { - add_wave / - set_property needs_save false [current_wave_config] - } else { - send_msg_id Add_Wave-1 WARNING "No top level signals found. Simulator will start without a wave window. If you want to open a wave window go to 'File->New Waveform Configuration' or type 'create_wave_config' in the TCL console." - } - } - run 1us - file delete ${scriptPath} -force\n`; hdlFile.writeFile(scriptPath, script); const cmd = `source ${scriptPath} -quiet`; - config.terminal?.sendText(cmd); + + HardwareOutput.report('simulateCli'); + context.process?.stdin.write(cmd + '\n'); } - synth(config: PLConfig) { + public synth(context: PLContext) { let quietArg = ''; if (opeParam.prjInfo.enableShowLog) { quietArg = '-quiet'; @@ -377,10 +466,10 @@ class XilinxOperation { script += `launch_runs synth_1 ${quietArg} -jobs 4;`; script += `wait_on_run synth_1 ${quietArg}`; - config.terminal?.sendText(script); + context.process?.stdin.write(script + '\n'); } - impl(config: PLConfig) { + impl(context: PLContext) { let quietArg = ''; if (opeParam.prjInfo.enableShowLog) { quietArg = '-quiet'; @@ -393,10 +482,10 @@ class XilinxOperation { script += `open_run impl_1 ${quietArg};`; script += `report_timing_summary ${quietArg}`; - config.terminal?.sendText(script); + context.process?.stdin.write(script + '\n'); } - build(config: PLConfig) { + build(context: PLContext) { let quietArg = ''; if (this.prjConfig.enableShowLog) { quietArg = '-quiet'; @@ -412,7 +501,7 @@ class XilinxOperation { script += `open_run impl_1 ${quietArg}\n`; script += `report_timing_summary ${quietArg}\n`; - this.generateBit(config); + this.generateBit(context); const scriptPath = `${this.xilinxPath}/build.tcl`; script += `source ${scriptPath} -notrace\n`; @@ -420,11 +509,12 @@ class XilinxOperation { script += `file delete ${scriptPath} -force\n`; hdlFile.writeFile(scriptPath, script); const cmd = `source ${scriptPath} -quiet`; - config.terminal?.sendText(cmd); + + context.process?.stdin.write(cmd + '\n'); } - generateBit(config: PLConfig) { + generateBit(context: PLContext) { let scripts: string[] = []; let core = this.prjConfig.soc.core; let sysdefPath = `${this.prjInfo.path}/${this.prjInfo.name}.runs` + @@ -451,97 +541,117 @@ class XilinxOperation { script += `file delete ${scriptPath} -force\n`; hdlFile.writeFile(scriptPath, script); const cmd = `source ${scriptPath} -quiet`; - config.terminal?.sendText(cmd); + + context.process?.stdin.write(cmd + '\n'); } - program(config: PLConfig) { + program(context: PLContext) { let scriptPath = `${this.xilinxPath}/program.tcl`; let script = ` - open_hw -quiet - connect_hw_server -quiet - set found 0 - foreach hw_target [get_hw_targets] { - current_hw_target $hw_target - open_hw_target -quiet - foreach hw_device [get_hw_devices] { - if { [string equal -length 6 [get_property PART $hw_device] ${this.prjInfo.device}] == 1 } { - puts "------Successfully Found Hardware Target with a ${this.prjInfo.device} device------ " - current_hw_device $hw_device - set found 1 - } - } - if {$found == 1} {break} - close_hw_target - } - - #download the hw_targets - if {$found == 0 } { - puts "******ERROR : Did not find any Hardware Target with a ${this.prjInfo.device} device****** " - } else { - set_property PROGRAM.FILE ./[current_project].bit [current_hw_device] - program_hw_devices [current_hw_device] -quiet - disconnect_hw_server -quiet +open_hw -quiet +connect_hw_server -quiet +set found 0 +foreach hw_target [get_hw_targets] { + current_hw_target $hw_target + open_hw_target -quiet + foreach hw_device [get_hw_devices] { + if { [string equal -length 6 [get_property PART $hw_device] ${this.prjInfo.device}] == 1 } { + puts "------Successfully Found Hardware Target with a ${this.prjInfo.device} device------ " + current_hw_device $hw_device + set found 1 } - file delete ${scriptPath} -force\n`; + } + if {$found == 1} {break} + close_hw_target +} + +#download the hw_targets +if {$found == 0 } { + puts "******ERROR : Did not find any Hardware Target with a ${this.prjInfo.device} device****** " +} else { + set_property PROGRAM.FILE ./[current_project].bit [current_hw_device] + program_hw_devices [current_hw_device] -quiet + disconnect_hw_server -quiet +} +file delete ${scriptPath} -force\n`; hdlFile.writeFile(scriptPath, script); const cmd = `source ${scriptPath} -quiet`; - config.terminal?.sendText(cmd); + + context.process?.stdin.write(cmd + '\n'); } - public gui(config: PLConfig) { - if (config.terminal) { - config.terminal.sendText("start_gui -quiet"); + public async gui(context: PLContext) { + const { t } = vscode.l10n; + + if (context.process === undefined) { + await this.launch(context); + } + + if (context.process) { + context.process.stdin.write('start_gui -quiet\n'); + HardwareOutput.report(t('info.pl.gui.report-title'), ReportType.Info); + HardwareOutput.show(); this.guiLaunched = true; - } else { - const prjFiles = hdlFile.pickFileRecursive(this.prjPath, [], - filePath => filePath.endsWith('.xpr')); - - const arg = '-notrace -nolog -nojournal'; - const cmd = `${config.path} -mode gui -s ${prjFiles[0]} ${arg}`; - exec(cmd, (error, stdout, stderr) => { - if (error !== null) { - vscode.window.showErrorMessage(stderr); - } else { - vscode.window.showInformationMessage("GUI open successfully"); - this.guiLaunched = true; - } - }); } } - public addFiles(files: string[], config: PLConfig) { + public addFiles(files: string[], context: PLContext) { + const { t } = vscode.l10n; + if (!this.guiLaunched) { - this.processFileInPrj(files, config, "add_file"); + const filesString = files.join("\n"); + HardwareOutput.report(t('info.pl.add-files.title') + '\n' + filesString); + this.processFileInPrj(files, context, "add_file"); } } - public delFiles(files: string[], config: PLConfig) { + public delFiles(files: string[], context: PLContext) { + const { t } = vscode.l10n; + if (!this.guiLaunched) { - this.processFileInPrj(files, config, "remove_files"); + const filesString = files.join("\n"); + HardwareOutput.report(t('info.pl.del-files.title') + '\n' + filesString); + this.processFileInPrj(files, context, "remove_files"); } } - setSrcTop(name: string, config: PLConfig) { + /** + * @description 设置为 src 顶层文件 + * @param name + * @param context + */ + public setSrcTop(name: string, context: PLContext) { const cmd = `set_property top ${name} [current_fileset]`; - config.terminal?.sendText(cmd); + context.process?.stdin.write(cmd + '\n'); } - setSimTop(name: string, config: PLConfig) { + /** + * @description 设置为 sim 顶层文件 + * @param name + * @param context + */ + public setSimTop(name: string, context: PLContext) { const cmd = `set_property top ${name} [get_filesets sim_1]`; - config.terminal?.sendText(cmd); + context.process?.stdin.write(cmd + '\n'); } - processFileInPrj(files: string[], config: PLConfig, command: string) { - const terminal = config.terminal; - if (terminal) { - for (const file of files) { - terminal.sendText(command + ' ' + file); - } + /** + * @description 为输入的每一个文件在 TCL 解释器中执行 command + * @param files + * @param context + * @param command + */ + public processFileInPrj(files: string[], context: PLContext, command: string) { + if (context.process === undefined) { + return; + } + for (const file of files) { + context.process.stdin.write(command + ' ' + file + '\n'); } } - xExecShowLog(logPath: AbsPath) { + public xExecShowLog(logPath: AbsPath) { let logPathList = ["runme", "xvlog", "elaborate"]; let fileName = fspath.basename(logPath, ".log"); @@ -599,7 +709,7 @@ class XilinxBd { this.bdRepo = this.setting.get('digital-ide.prj.xilinx.BD.repo.path', ''); } - getConfig() { + public getConfig() { this.extensionPath = opeParam.extensionPath; this.xbdPath = hdlPath.join(this.extensionPath, 'lib', 'bd', 'xilinx'); this.schemaPath = opeParam.propertySchemaPath; @@ -608,7 +718,7 @@ class XilinxBd { this.bdRepo = this.setting.get('digital-ide.prj.xilinx.BD.repo.path', ''); } - async overwrite(uri: vscode.Uri): Promise { + public async overwrite(uri: vscode.Uri): Promise { this.getConfig(); // 获取当前bd file的路径 const select = await vscode.window.showQuickPick(this.bdEnum); @@ -633,7 +743,7 @@ class XilinxBd { } } - add(uri: vscode.Uri) { + public add(uri: vscode.Uri) { this.getConfig(); // 获取当前bd file的路径 let docPath = hdlPath.toSlash(uri.fsPath); @@ -664,7 +774,7 @@ class XilinxBd { } - delete() { + public delete() { this.getConfig(); vscode.window.showQuickPick(this.bdEnum).then(select => { // the user canceled the select @@ -685,7 +795,7 @@ class XilinxBd { }); } - load() { + public load() { this.getConfig(); if (hdlFile.isDir(this.bdRepo)) { for (const file of fs.readdirSync(this.bdRepo)) { @@ -845,5 +955,5 @@ export { XilinxOperation, tools, XilinxBd, - PLConfig + PLContext }; diff --git a/syntaxes/digital-ide-output.json b/syntaxes/digital-ide-output.json index 7945dea..13a59d0 100644 --- a/syntaxes/digital-ide-output.json +++ b/syntaxes/digital-ide-output.json @@ -4,7 +4,7 @@ "patterns": [ { "name": "digital-ide.Info", - "match": "(\\[Info - (.*)\\])(.*)", + "match": "^(\\[Info - (.*?)\\])(.*)", "captures": { "1": { "name": "token.info-token" @@ -16,7 +16,7 @@ }, { "name": "digital-ide.Error", - "match": "(\\[Error - (.*)\\])(.*)", + "match": "^(\\[Error - (.*?)\\])(.*)", "captures": { "1": { "name": "token.error-token" @@ -31,7 +31,7 @@ }, { "name": "digital-ide.Warn", - "match": "(\\[Warn - (.*)\\])(.*)", + "match": "^(\\[Warn - (.*?)\\])(.*)", "captures": { "1": { "name": "token.warn-token" @@ -46,7 +46,7 @@ }, { "name": "digital-ide.Debug", - "match": "(\\[Debug - (.*)\\])([\\s\\S]*)", + "match": "^(\\[Debug - (.*?)\\])([\\s\\S]*)", "captures": { "1": { "name": "token.debug-token" @@ -61,7 +61,7 @@ }, { "name": "digital-ide.Run", - "match": "(\\[Run - (.*)\\])([\\s\\S]*)", + "match": "^(\\[Run - (.*?)\\])([\\s\\S]*)", "captures": { "1": { "name": "token.info-token" @@ -73,7 +73,7 @@ }, { "name": "digital-ide.Launch", - "match": "(\\[Launch - (.*)\\])([\\s\\S]*)", + "match": "^(\\[Launch - (.*?)\\])([\\s\\S]*)", "captures": { "1": { "name": "keyword.launch-token"