完成 PL 的子进程接入

This commit is contained in:
锦恢 2024-11-16 22:00:34 +08:00
parent fee9679c74
commit b00c1649e2
17 changed files with 418 additions and 265 deletions

View File

@ -29,5 +29,13 @@
"info.treeview.ip-no-active.message": "当前 IP 还未激活,请通过 Xilinx 工具链将 XCI 文件生成完整的 IP 核", "info.treeview.ip-no-active.message": "当前 IP 还未激活,请通过 Xilinx 工具链将 XCI 文件生成完整的 IP 核",
"info.progress.initialize-configure": "初始化项目配置", "info.progress.initialize-configure": "初始化项目配置",
"info.pl.xilinx.launch.pick-project-placeholder": "Which project you want to open ?", "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 枚举:"
} }

View File

@ -29,5 +29,13 @@
"info.treeview.ip-no-active.message": "当前 IP 还未激活,请通过 Xilinx 工具链将 XCI 文件生成完整的 IP 核", "info.treeview.ip-no-active.message": "当前 IP 还未激活,请通过 Xilinx 工具链将 XCI 文件生成完整的 IP 核",
"info.progress.initialize-configure": "初始化项目配置", "info.progress.initialize-configure": "初始化项目配置",
"info.pl.xilinx.launch.pick-project-placeholder": "Which project you want to open ?", "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 枚举:"
} }

View File

@ -29,5 +29,13 @@
"info.treeview.ip-no-active.message": "当前 IP 还未激活,请通过 Xilinx 工具链将 XCI 文件生成完整的 IP 核", "info.treeview.ip-no-active.message": "当前 IP 还未激活,请通过 Xilinx 工具链将 XCI 文件生成完整的 IP 核",
"info.progress.initialize-configure": "初始化项目配置", "info.progress.initialize-configure": "初始化项目配置",
"info.pl.xilinx.launch.pick-project-placeholder": "Which project you want to open ?", "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 枚举:"
} }

View File

@ -29,5 +29,13 @@
"info.treeview.ip-no-active.message": "当前 IP 还未激活,请通过 Xilinx 工具链将 XCI 文件生成完整的 IP 核", "info.treeview.ip-no-active.message": "当前 IP 还未激活,请通过 Xilinx 工具链将 XCI 文件生成完整的 IP 核",
"info.progress.initialize-configure": "初始化项目配置", "info.progress.initialize-configure": "初始化项目配置",
"info.pl.xilinx.launch.pick-project-placeholder": "请选择需要打开的工程", "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 枚举:"
} }

View File

@ -29,5 +29,13 @@
"info.treeview.ip-no-active.message": "当前 IP 还未激活,请通过 Xilinx 工具链将 XCI 文件生成完整的 IP 核", "info.treeview.ip-no-active.message": "当前 IP 还未激活,请通过 Xilinx 工具链将 XCI 文件生成完整的 IP 核",
"info.progress.initialize-configure": "初始化项目配置", "info.progress.initialize-configure": "初始化项目配置",
"info.pl.xilinx.launch.pick-project-placeholder": "Which project you want to open ?", "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 枚举:"
} }

View File

@ -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

View File

@ -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

View File

@ -166,6 +166,9 @@ async function getDocsFromModule(module: HdlModule): Promise<MarkdownString> {
for (const inst of module.getAllInstances()) { for (const inst of module.getAllInstances()) {
insts.push(inst); insts.push(inst);
} }
console.log('文档化 debug');
console.log(insts);
makeTableFromObjArray(md, insts, 'Dependencies', makeTableFromObjArray(md, insts, 'Dependencies',
['name', 'type', 'instModPath'], ['name', 'type', 'instModPath'],
['name', 'module', 'path']); ['name', 'module', 'path']);

View File

@ -128,7 +128,7 @@ function bin2float(bin: string, exp: number, fra: number): number | undefined {
function getFullSymbolInfoVlog(document: vscode.TextDocument, range: Range) { function getFullSymbolInfoVlog(document: vscode.TextDocument, range: Range) {
const comments = []; const comments = [];
const currentLine = range.start.line - 1; const currentLine = range.start.line;
const currentText = document.lineAt(currentLine).text; const currentText = document.lineAt(currentLine).text;
// 往上找到第一个非空行 // 往上找到第一个非空行

View File

@ -27,7 +27,13 @@ const PPY_REPLACE: Record<string, string> = {
SOC: 'soc', SOC: 'soc',
SOC_MODE: 'soc', SOC_MODE: 'soc',
enableShowlog: 'enableShowLog', enableShowlog: 'enableShowLog',
Device: 'device' Device: 'device',
HardwareLIB: 'library'
};
const HARDWARD_LIB_STATE_REPLACE: Record<string, string> = {
virtual: 'remote',
real: 'local'
}; };
const PPY_ARCH_REPLACE: Record<string, string> = { const PPY_ARCH_REPLACE: Record<string, string> = {
@ -41,6 +47,7 @@ const PPY_LIB_REPLACE: Record<string, string> = {
}; };
async function transformOldPpy() { async function transformOldPpy() {
const { t } = vscode.l10n;
const propertyJsonPath = opeParam.propertyJsonPath; const propertyJsonPath = opeParam.propertyJsonPath;
if (fs.existsSync(propertyJsonPath)) { if (fs.existsSync(propertyJsonPath)) {
const oldPpyContent = hdlFile.readJSON(propertyJsonPath) as Record<any, any>; const oldPpyContent = hdlFile.readJSON(propertyJsonPath) as Record<any, any>;
@ -56,6 +63,9 @@ async function transformOldPpy() {
if (oldPpyContent.library) { if (oldPpyContent.library) {
for (const oldName of Object.keys(PPY_LIB_REPLACE)) { for (const oldName of Object.keys(PPY_LIB_REPLACE)) {
const newName = PPY_LIB_REPLACE[oldName]; const newName = PPY_LIB_REPLACE[oldName];
if (typeof newName !== 'string') {
continue;
}
oldPpyContent.library[newName] = oldPpyContent.library[oldName]; oldPpyContent.library[newName] = oldPpyContent.library[oldName];
delete oldPpyContent.library[oldName]; delete oldPpyContent.library[oldName];
} }
@ -73,6 +83,32 @@ async function transformOldPpy() {
delete oldPpyContent.soc['soc']; 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); hdlFile.writeJSON(propertyJsonPath, oldPpyContent);
} else { } else {

View File

@ -196,28 +196,13 @@ class ToolTreeProvider extends BaseCommandTreeProvider {
} }
public async clean() { public async clean() {
console.log('current removed');
return;
const workspacePath = opeParam.workspacePath; 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 // move bd * ip
const plName = opeParam.prjInfo.prjName.PL; const plName = opeParam.prjInfo.prjName.PL;
const targetPath = fspath.dirname(opeParam.prjInfo.arch.hardware.src); const targetPath = fspath.dirname(opeParam.prjInfo.arch.hardware.src);
// TODO: 适配更多的 toolChain
const sourceIpPath = `${workspacePath}/prj/xilinx/${plName}.srcs/sources_1/ip`; const sourceIpPath = `${workspacePath}/prj/xilinx/${plName}.srcs/sources_1/ip`;
const sourceBdPath = `${workspacePath}/prj/xilinx/${plName}.srcs/sources_1/bd`; const sourceBdPath = `${workspacePath}/prj/xilinx/${plName}.srcs/sources_1/bd`;
@ -227,17 +212,26 @@ class ToolTreeProvider extends BaseCommandTreeProvider {
hdlDir.mvdir(sourceBdPath, targetPath, true); hdlDir.mvdir(sourceBdPath, targetPath, true);
MainOutput.report("move dir from " + sourceBdPath + " to " + targetPath); MainOutput.report("move dir from " + sourceBdPath + " to " + targetPath);
const ignores = hdlIgnore.getIgnoreFiles(); // if (prjPath !== opeParam.workspacePath) {
const strFiles = hdlFile.pickFileRecursive(workspacePath, ignores, p => p.endsWith('.str')); // hdlDir.rmdir(prjPath);
for (const path of strFiles) { // hdlDir.rmdir(xilFolder);
hdlFile.removeFile(path); // MainOutput.report("remove dir : " + prjPath);
MainOutput.report("remove file " + path); // 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 logFiles = hdlFile.pickFileRecursive(workspacePath, ignores, p => p.endsWith('.log')); // const ignores = hdlIgnore.getIgnoreFiles();
for (const path of logFiles) { // const strFiles = hdlFile.pickFileRecursive(workspacePath, ignores, p => p.endsWith('.str'));
hdlFile.readFile(path); // 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);
// }
MainOutput.report('finish digital-ide.tool.clean'); MainOutput.report('finish digital-ide.tool.clean');
} }

View File

@ -71,17 +71,25 @@ class Output {
public show() { public show() {
this._output.show(true); this._output.show(true);
} }
public clear() {
this._output.clear();
}
} }
const MainOutput = new Output('Digital-IDE'); const MainOutput = new Output('Digital-IDE');
const LspOutput = new Output('Digital-IDE Linter'); const LspOutput = new Output('Digital-IDE Linter');
const YosysOutput = new Output('Digital-IDE Yosys'); const YosysOutput = new Output('Digital-IDE Yosys');
const WaveViewOutput = new Output('Digital-IDE Wave Viewer'); const WaveViewOutput = new Output('Digital-IDE Wave Viewer');
const HardwareOutput = new Output('Digital-IDE Hareware');
const HardwareErrorOutput = new Output('Digital-IDE Hareware Error');
export { export {
ReportType, ReportType,
MainOutput, MainOutput,
LspOutput, LspOutput,
YosysOutput, YosysOutput,
WaveViewOutput WaveViewOutput,
HardwareOutput,
HardwareErrorOutput
}; };

View File

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

View File

@ -4,6 +4,6 @@ export async function generateEfinityConfig() {
} }
class EfinityOperation { export class EfinityOperation {
} }

View File

@ -4,7 +4,7 @@
*/ */
import * as vscode from 'vscode'; import * as vscode from 'vscode';
import { PLConfig, XilinxOperation } from './xilinx'; import { PLContext, XilinxOperation } from './xilinx';
import { BaseManage } from '../common'; import { BaseManage } from '../common';
import { opeParam } from '../../global'; import { opeParam } from '../../global';
import { ToolChainType } from '../../global/enum'; import { ToolChainType } from '../../global/enum';
@ -12,108 +12,105 @@ import { hdlFile, hdlPath } from '../../hdlFs';
import { moduleTreeProvider, ModuleDataItem } from '../../function/treeView/tree'; import { moduleTreeProvider, ModuleDataItem } from '../../function/treeView/tree';
import { HdlFileType } from '../../hdlParser/common'; import { HdlFileType } from '../../hdlParser/common';
import { PropertySchema } from '../../global/propertySchema'; import { PropertySchema } from '../../global/propertySchema';
import { HardwareOutput, ReportType } from '../../global/outputChannel';
class PlManage extends BaseManage { class PlManage extends BaseManage {
config: PLConfig; context: PLContext;
constructor() { constructor() {
super(); super();
this.config = {
tool: 'default', this.context = {
tool: opeParam.prjInfo.toolChain || 'xilinx',
path: '', path: '',
ope: new XilinxOperation(), ope: new XilinxOperation(),
terminal: null terminal: undefined,
process: undefined
}; };
if (opeParam.prjInfo.toolChain) { const curToolChain = this.context.tool;
this.config.tool = opeParam.prjInfo.toolChain;
}
const curToolChain = this.config.tool;
if (curToolChain === ToolChainType.Xilinx) { if (curToolChain === ToolChainType.Xilinx) {
const vivadoPath = vscode.workspace.getConfiguration('digital-ide.prj.vivado.install').get('path', ''); const vivadoPath = vscode.workspace.getConfiguration('digital-ide.prj.vivado.install').get('path', '');
if (hdlFile.isDir(vivadoPath)) { 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') { if (opeParam.os === 'win32') {
this.config.path += '.bat'; this.context.path += '.bat';
} }
} else { } else {
this.config.path = 'vivado'; this.context.path = 'vivado';
} }
} }
} }
public launch() { public launch() {
this.config.terminal = this.createTerminal('Hardware'); this.context.ope.launch(this.context);
this.config.terminal.show(true);
this.config.ope.launch(this.config);
} }
public simulate() { public simulate() {
if (!this.config.terminal) { if (this.context.process === undefined) {
return; return;
} }
this.config.ope.simulate(this.config); this.context.ope.simulate(this.context);
} }
public simulateCli() { public simulateCli() {
this.config.ope.simulateCli(this.config); this.context.ope.simulateCli(this.context);
} }
public simulateGui() { public simulateGui() {
this.config.ope.simulateGui(this.config); this.context.ope.simulateGui(this.context);
} }
public refresh() { public refresh() {
if (!this.config.terminal) { if (this.context.process === undefined) {
return; return;
} }
this.config.ope.refresh(this.config.terminal); this.context.ope.refresh(this.context);
} }
public build() { public build() {
this.config.ope.build(this.config); this.context.ope.build(this.context);
} }
public synth() { public synth() {
this.config.ope.synth(this.config); this.context.ope.synth(this.context);
} }
public impl() { public impl() {
if (!this.config.terminal) { if (this.context.process === undefined) {
return null; return null;
} }
this.context.ope.impl(this.context);
this.config.ope.impl(this.config);
} }
public bitstream() { public bitstream() {
this.config.ope.generateBit(this.config); this.context.ope.generateBit(this.context);
} }
public program() { public program() {
this.config.ope.program(this.config); this.context.ope.program(this.context);
} }
public gui() { public gui() {
this.config.ope.gui(this.config); this.context.ope.gui(this.context);
} }
public exit() { public exit() {
if (!this.config.terminal) { const { t } = vscode.l10n;
return null;
if (this.context.process === undefined) {
return;
} }
this.config.terminal.show(true); HardwareOutput.show();
this.config.terminal.sendText(`exit`); this.context.process.stdin.write('exit\n');
this.config.terminal.sendText(`exit`); HardwareOutput.report(t('info.pl.exit.title'), ReportType.Info);
this.config.terminal = null; this.context.process = undefined;
} }
public setSrcTop(item: ModuleDataItem) { 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); const type = moduleTreeProvider.getItemType(item);
if (type === HdlFileType.Src) { if (type === HdlFileType.Src) {
moduleTreeProvider.setFirstTop(HdlFileType.Src, item.name, item.path); moduleTreeProvider.setFirstTop(HdlFileType.Src, item.name, item.path);
@ -122,7 +119,7 @@ class PlManage extends BaseManage {
} }
public setSimTop(item: ModuleDataItem) { 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); const type = moduleTreeProvider.getItemType(item);
if (type === HdlFileType.Sim) { if (type === HdlFileType.Sim) {
moduleTreeProvider.setFirstTop(HdlFileType.Sim, item.name, item.path); moduleTreeProvider.setFirstTop(HdlFileType.Sim, item.name, item.path);
@ -132,11 +129,11 @@ class PlManage extends BaseManage {
async addFiles(files: string[]) { async addFiles(files: string[]) {
this.config.ope.addFiles(files, this.config); this.context.ope.addFiles(files, this.context);
} }
async delFiles(files: string[]) { async delFiles(files: string[]) {
this.config.ope.delFiles(files, this.config); this.context.ope.delFiles(files, this.context);
} }
async addDevice() { async addDevice() {

View File

@ -1,6 +1,6 @@
/* eslint-disable @typescript-eslint/naming-convention */ /* eslint-disable @typescript-eslint/naming-convention */
import * as vscode from 'vscode'; import * as vscode from 'vscode';
import { exec } from 'child_process'; import { ChildProcessWithoutNullStreams, exec, spawn } from 'child_process';
import * as fspath from 'path'; import * as fspath from 'path';
import * as fs from 'fs'; import * as fs from 'fs';
@ -10,7 +10,8 @@ import { hdlFile, hdlDir, hdlPath } from '../../hdlFs';
import { PropertySchema } from '../../global/propertySchema'; import { PropertySchema } from '../../global/propertySchema';
import { XilinxIP } from '../../global/enum'; import { XilinxIP } from '../../global/enum';
import { MainOutput } from '../../global/outputChannel'; import { HardwareOutput, MainOutput, ReportType } from '../../global/outputChannel';
import { debounce } from '../../global/util';
interface XilinxCustom { interface XilinxCustom {
ipRepo: AbsPath, ipRepo: AbsPath,
@ -22,10 +23,17 @@ interface TopMod {
sim: string sim: string
}; };
interface PLConfig { // Programmable Logic Context for short
terminal : vscode.Terminal | null, interface PLContext {
tool? : string, // 工具类型 // 保留启动上下文
path? : string, // 第三方工具运行路径 terminal? : vscode.Terminal,
// 目前使用的启动上下文
process?: ChildProcessWithoutNullStreams,
// 工具类型
tool? : string,
// 第三方工具运行路径
path? : string,
// 操作类
ope : XilinxOperation, ope : XilinxOperation,
}; };
@ -128,17 +136,12 @@ class XilinxOperation {
/** /**
* xilinx下的launch运行 * xilinx下的launch运行
* @param config * @param context
*/ */
async launch(config: PLConfig): Promise<string | undefined> { public async launch(context: PLContext): Promise<string | undefined> {
const { t } = vscode.l10n; const { t } = vscode.l10n;
this.guiLaunched = false; this.guiLaunched = false;
const vivadoTerminal = config.terminal;
if (!vivadoTerminal) {
return undefined;
}
let scripts: string[] = []; let scripts: string[] = [];
let prjFilePath = this.prjPath as AbsPath; let prjFilePath = this.prjPath as AbsPath;
@ -173,17 +176,96 @@ class XilinxOperation {
scripts.push(this.getRefreshCmd()); scripts.push(this.getRefreshCmd());
scripts.push(`file delete ${tclPath} -force`); scripts.push(`file delete ${tclPath} -force`);
const tclCommands = scripts.join('\n') + '\n'; const tclCommands = scripts.join('\n') + '\n';
hdlFile.writeFile(tclPath, tclCommands); hdlFile.writeFile(tclPath, tclCommands);
const argu = `-notrace -nolog -nojournal`; 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<ChildProcessWithoutNullStreams> {
// 执行 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';
});
});
} }
create(scripts: string[]) { 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;
}
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(`set_param general.maxThreads 8`);
scripts.push(`create_project ${this.prjInfo.name} ${this.prjInfo.path} -part ${this.prjInfo.device} -force`); 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]`); 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`); 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(`set_param general.maxThreads 8`);
scripts.push(`open_project ${path} -quiet`); scripts.push(`open_project ${path} -quiet`);
} }
@ -305,68 +387,75 @@ class XilinxOperation {
return cmd; return cmd;
} }
refresh(terminal: vscode.Terminal) { public refresh(context: PLContext) {
const cmd = this.getRefreshCmd(); const cmd = this.getRefreshCmd();
terminal.sendText(cmd); context.process?.stdin.write(cmd + '\n');
} }
simulate(config: PLConfig) { public simulate(context: PLContext) {
this.simulateCli(config); this.simulateCli(context);
} }
simulateGui(config: PLConfig) { public simulateGui(context: PLContext) {
const scriptPath = `${this.xilinxPath}/simulate.tcl`; const scriptPath = `${this.xilinxPath}/simulate.tcl`;
const script = `
if {[current_sim] != ""} {
relaunch_sim -quiet
} else {
launch_simulation -quiet
}
set curr_wave [current_wave_config] const script = `
if { [string length $curr_wave] == 0 } { 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} { if { [llength [get_objects]] > 0} {
add_wave / add_wave /
set_property needs_save false [current_wave_config] set_property needs_save false [current_wave_config]
} else { } 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." 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 run 1us
start_gui -quiet
file delete ${scriptPath} -force\n`;
start_gui -quiet
file delete ${scriptPath} -force\n`;
hdlFile.writeFile(scriptPath, script); hdlFile.writeFile(scriptPath, script);
const cmd = `source ${scriptPath} -quiet`; 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 scriptPath = hdlPath.join(this.xilinxPath, 'simulate.tcl');
const script = ` const script = `
if {[current_sim] != ""} { if {[current_sim] != ""} {
relaunch_sim -quiet relaunch_sim -quiet
} else { } else {
launch_simulation -quiet launch_simulation -quiet
} }
set curr_wave [current_wave_config] set curr_wave [current_wave_config]
if { [string length $curr_wave] == 0 } { if { [string length $curr_wave] == 0 } {
if { [llength [get_objects]] > 0} { if { [llength [get_objects]] > 0} {
add_wave / add_wave /
set_property needs_save false [current_wave_config] set_property needs_save false [current_wave_config]
} else { } 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." 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 run 1us
file delete ${scriptPath} -force\n`; file delete ${scriptPath} -force\n`;
hdlFile.writeFile(scriptPath, script); hdlFile.writeFile(scriptPath, script);
const cmd = `source ${scriptPath} -quiet`; 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 = ''; let quietArg = '';
if (opeParam.prjInfo.enableShowLog) { if (opeParam.prjInfo.enableShowLog) {
quietArg = '-quiet'; quietArg = '-quiet';
@ -377,10 +466,10 @@ class XilinxOperation {
script += `launch_runs synth_1 ${quietArg} -jobs 4;`; script += `launch_runs synth_1 ${quietArg} -jobs 4;`;
script += `wait_on_run synth_1 ${quietArg}`; 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 = ''; let quietArg = '';
if (opeParam.prjInfo.enableShowLog) { if (opeParam.prjInfo.enableShowLog) {
quietArg = '-quiet'; quietArg = '-quiet';
@ -393,10 +482,10 @@ class XilinxOperation {
script += `open_run impl_1 ${quietArg};`; script += `open_run impl_1 ${quietArg};`;
script += `report_timing_summary ${quietArg}`; script += `report_timing_summary ${quietArg}`;
config.terminal?.sendText(script); context.process?.stdin.write(script + '\n');
} }
build(config: PLConfig) { build(context: PLContext) {
let quietArg = ''; let quietArg = '';
if (this.prjConfig.enableShowLog) { if (this.prjConfig.enableShowLog) {
quietArg = '-quiet'; quietArg = '-quiet';
@ -412,7 +501,7 @@ class XilinxOperation {
script += `open_run impl_1 ${quietArg}\n`; script += `open_run impl_1 ${quietArg}\n`;
script += `report_timing_summary ${quietArg}\n`; script += `report_timing_summary ${quietArg}\n`;
this.generateBit(config); this.generateBit(context);
const scriptPath = `${this.xilinxPath}/build.tcl`; const scriptPath = `${this.xilinxPath}/build.tcl`;
script += `source ${scriptPath} -notrace\n`; script += `source ${scriptPath} -notrace\n`;
@ -420,11 +509,12 @@ class XilinxOperation {
script += `file delete ${scriptPath} -force\n`; script += `file delete ${scriptPath} -force\n`;
hdlFile.writeFile(scriptPath, script); hdlFile.writeFile(scriptPath, script);
const cmd = `source ${scriptPath} -quiet`; 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 scripts: string[] = [];
let core = this.prjConfig.soc.core; let core = this.prjConfig.soc.core;
let sysdefPath = `${this.prjInfo.path}/${this.prjInfo.name}.runs` + let sysdefPath = `${this.prjInfo.path}/${this.prjInfo.name}.runs` +
@ -451,16 +541,17 @@ class XilinxOperation {
script += `file delete ${scriptPath} -force\n`; script += `file delete ${scriptPath} -force\n`;
hdlFile.writeFile(scriptPath, script); hdlFile.writeFile(scriptPath, script);
const cmd = `source ${scriptPath} -quiet`; 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 scriptPath = `${this.xilinxPath}/program.tcl`;
let script = ` let script = `
open_hw -quiet open_hw -quiet
connect_hw_server -quiet connect_hw_server -quiet
set found 0 set found 0
foreach hw_target [get_hw_targets] { foreach hw_target [get_hw_targets] {
current_hw_target $hw_target current_hw_target $hw_target
open_hw_target -quiet open_hw_target -quiet
foreach hw_device [get_hw_devices] { foreach hw_device [get_hw_devices] {
@ -472,76 +563,95 @@ class XilinxOperation {
} }
if {$found == 1} {break} if {$found == 1} {break}
close_hw_target close_hw_target
} }
#download the hw_targets #download the hw_targets
if {$found == 0 } { if {$found == 0 } {
puts "******ERROR : Did not find any Hardware Target with a ${this.prjInfo.device} device****** " puts "******ERROR : Did not find any Hardware Target with a ${this.prjInfo.device} device****** "
} else { } else {
set_property PROGRAM.FILE ./[current_project].bit [current_hw_device] set_property PROGRAM.FILE ./[current_project].bit [current_hw_device]
program_hw_devices [current_hw_device] -quiet program_hw_devices [current_hw_device] -quiet
disconnect_hw_server -quiet disconnect_hw_server -quiet
} }
file delete ${scriptPath} -force\n`; file delete ${scriptPath} -force\n`;
hdlFile.writeFile(scriptPath, script); hdlFile.writeFile(scriptPath, script);
const cmd = `source ${scriptPath} -quiet`; const cmd = `source ${scriptPath} -quiet`;
config.terminal?.sendText(cmd);
context.process?.stdin.write(cmd + '\n');
} }
public gui(config: PLConfig) { public async gui(context: PLContext) {
if (config.terminal) { const { t } = vscode.l10n;
config.terminal.sendText("start_gui -quiet");
this.guiLaunched = true;
} else {
const prjFiles = hdlFile.pickFileRecursive(this.prjPath, [],
filePath => filePath.endsWith('.xpr'));
const arg = '-notrace -nolog -nojournal'; if (context.process === undefined) {
const cmd = `${config.path} -mode gui -s ${prjFiles[0]} ${arg}`; await this.launch(context);
exec(cmd, (error, stdout, stderr) => { }
if (error !== null) {
vscode.window.showErrorMessage(stderr); if (context.process) {
} else { context.process.stdin.write('start_gui -quiet\n');
vscode.window.showInformationMessage("GUI open successfully"); HardwareOutput.report(t('info.pl.gui.report-title'), ReportType.Info);
HardwareOutput.show();
this.guiLaunched = true; this.guiLaunched = true;
} }
});
}
} }
public addFiles(files: string[], config: PLConfig) { public addFiles(files: string[], context: PLContext) {
const { t } = vscode.l10n;
if (!this.guiLaunched) { 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) { 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]`; 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]`; 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; * @description TCL command
if (terminal) { * @param files
* @param context
* @param command
*/
public processFileInPrj(files: string[], context: PLContext, command: string) {
if (context.process === undefined) {
return;
}
for (const file of files) { for (const file of files) {
terminal.sendText(command + ' ' + file); context.process.stdin.write(command + ' ' + file + '\n');
}
} }
} }
xExecShowLog(logPath: AbsPath) { public xExecShowLog(logPath: AbsPath) {
let logPathList = ["runme", "xvlog", "elaborate"]; let logPathList = ["runme", "xvlog", "elaborate"];
let fileName = fspath.basename(logPath, ".log"); let fileName = fspath.basename(logPath, ".log");
@ -599,7 +709,7 @@ class XilinxBd {
this.bdRepo = this.setting.get('digital-ide.prj.xilinx.BD.repo.path', ''); this.bdRepo = this.setting.get('digital-ide.prj.xilinx.BD.repo.path', '');
} }
getConfig() { public getConfig() {
this.extensionPath = opeParam.extensionPath; this.extensionPath = opeParam.extensionPath;
this.xbdPath = hdlPath.join(this.extensionPath, 'lib', 'bd', 'xilinx'); this.xbdPath = hdlPath.join(this.extensionPath, 'lib', 'bd', 'xilinx');
this.schemaPath = opeParam.propertySchemaPath; this.schemaPath = opeParam.propertySchemaPath;
@ -608,7 +718,7 @@ class XilinxBd {
this.bdRepo = this.setting.get('digital-ide.prj.xilinx.BD.repo.path', ''); this.bdRepo = this.setting.get('digital-ide.prj.xilinx.BD.repo.path', '');
} }
async overwrite(uri: vscode.Uri): Promise<void> { public async overwrite(uri: vscode.Uri): Promise<void> {
this.getConfig(); this.getConfig();
// 获取当前bd file的路径 // 获取当前bd file的路径
const select = await vscode.window.showQuickPick(this.bdEnum); 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(); this.getConfig();
// 获取当前bd file的路径 // 获取当前bd file的路径
let docPath = hdlPath.toSlash(uri.fsPath); let docPath = hdlPath.toSlash(uri.fsPath);
@ -664,7 +774,7 @@ class XilinxBd {
} }
delete() { public delete() {
this.getConfig(); this.getConfig();
vscode.window.showQuickPick(this.bdEnum).then(select => { vscode.window.showQuickPick(this.bdEnum).then(select => {
// the user canceled the select // the user canceled the select
@ -685,7 +795,7 @@ class XilinxBd {
}); });
} }
load() { public load() {
this.getConfig(); this.getConfig();
if (hdlFile.isDir(this.bdRepo)) { if (hdlFile.isDir(this.bdRepo)) {
for (const file of fs.readdirSync(this.bdRepo)) { for (const file of fs.readdirSync(this.bdRepo)) {
@ -845,5 +955,5 @@ export {
XilinxOperation, XilinxOperation,
tools, tools,
XilinxBd, XilinxBd,
PLConfig PLContext
}; };

View File

@ -4,7 +4,7 @@
"patterns": [ "patterns": [
{ {
"name": "digital-ide.Info", "name": "digital-ide.Info",
"match": "(\\[Info - (.*)\\])(.*)", "match": "^(\\[Info - (.*?)\\])(.*)",
"captures": { "captures": {
"1": { "1": {
"name": "token.info-token" "name": "token.info-token"
@ -16,7 +16,7 @@
}, },
{ {
"name": "digital-ide.Error", "name": "digital-ide.Error",
"match": "(\\[Error - (.*)\\])(.*)", "match": "^(\\[Error - (.*?)\\])(.*)",
"captures": { "captures": {
"1": { "1": {
"name": "token.error-token" "name": "token.error-token"
@ -31,7 +31,7 @@
}, },
{ {
"name": "digital-ide.Warn", "name": "digital-ide.Warn",
"match": "(\\[Warn - (.*)\\])(.*)", "match": "^(\\[Warn - (.*?)\\])(.*)",
"captures": { "captures": {
"1": { "1": {
"name": "token.warn-token" "name": "token.warn-token"
@ -46,7 +46,7 @@
}, },
{ {
"name": "digital-ide.Debug", "name": "digital-ide.Debug",
"match": "(\\[Debug - (.*)\\])([\\s\\S]*)", "match": "^(\\[Debug - (.*?)\\])([\\s\\S]*)",
"captures": { "captures": {
"1": { "1": {
"name": "token.debug-token" "name": "token.debug-token"
@ -61,7 +61,7 @@
}, },
{ {
"name": "digital-ide.Run", "name": "digital-ide.Run",
"match": "(\\[Run - (.*)\\])([\\s\\S]*)", "match": "^(\\[Run - (.*?)\\])([\\s\\S]*)",
"captures": { "captures": {
"1": { "1": {
"name": "token.info-token" "name": "token.info-token"
@ -73,7 +73,7 @@
}, },
{ {
"name": "digital-ide.Launch", "name": "digital-ide.Launch",
"match": "(\\[Launch - (.*)\\])([\\s\\S]*)", "match": "^(\\[Launch - (.*?)\\])([\\s\\S]*)",
"captures": { "captures": {
"1": { "1": {
"name": "keyword.launch-token" "name": "keyword.launch-token"