diff --git a/.gitignore b/.gitignore index ce04596b..cb6d6a2e 100644 --- a/.gitignore +++ b/.gitignore @@ -26,4 +26,5 @@ resources/project_manager/help *quartus.rec *.cf *.o -Project** \ No newline at end of file +./venv +./work \ No newline at end of file diff --git a/.vscode/launch.json b/.vscode/launch.json index 762f81de..826719ae 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -39,8 +39,14 @@ "name": "Run TerosHDL", "sourceMaps": true, "outFiles": [ - "${workspaceFolder}/out/**/*.js", + "${workspaceFolder}/out/**/*.js" ], + "sourceMapPathOverrides": { + "../../../../../src/*": "${workspaceFolder}/src/*", + "src/*": "${workspaceFolder}/src/*", + "out/*": "${workspaceFolder}/out/*", + "webpack:///./out/*": "${workspaceFolder}/out/*" + }, "preLaunchTask": "teros watch", "request": "launch", "type": "extensionHost" diff --git a/package.json b/package.json index 1bc3c141..0c7e0889 100644 --- a/package.json +++ b/package.json @@ -34,9 +34,8 @@ }, "main": "./out/teroshdl/extension.js", "_moduleAliases": { - "colibri": "./out/colibri" + "colibri": "./out/colibri" }, - "contributes": { "viewsContainers": { "activitybar": [ @@ -130,8 +129,7 @@ "view": "teroshdl-view-actions", "contents": "[Verify Setup](command:teroshdl.verifySetup)\n[Open Global Settings Menu](command:teroshdl.configuration.global)\n[Export Settings](command:teroshdl.view.project.export_configuration)\n[Load Settings](command:teroshdl.view.project.load_configuration)\n[Documentation](command:teroshdl.documentation)" } - ], - + ], "grammars": [ { "language": "logTerosHDL", @@ -180,268 +178,212 @@ } ], "menus": { - "editor/context": [ - - ], + "editor/context": [], "explorer/context": [ - { "when": "resourceLangId == gtkw_wavebin || resourceLangId == gtkw_waveconfig || resourceLangId == vcd", - "command": "teroshdl.waveform", "group": "navigation" } - ], "view/title": [ - { "when": "view == teroshdl-project", - "command": "teroshdl.view.project.add", "group": "navigation" - } - - ,{ + }, + { "when": "view == teroshdl-view-source", - "command": "teroshdl.view.source.save_project", "group": "navigation" - } - - ,{ + }, + { "when": "view == teroshdl-view-source", - "command": "teroshdl.view.source.search", "group": "navigation" - } - - ,{ + }, + { "when": "view == teroshdl-view-source", - "command": "teroshdl.view.source.add", "group": "navigation" - } - - ,{ + }, + { "when": "view == teroshdl-view-dependency", - "command": "teroshdl.view.dependency.refresh", "group": "navigation" - } - - ,{ + }, + { "when": "view == teroshdl-view-dependency", - "command": "teroshdl.view.dependency.schematic", "group": "navigation" - } - - ,{ + }, + { "when": "view == teroshdl-view-dependency", - "command": "teroshdl.view.dependency.viewer", "group": "navigation" - } - - ,{ + }, + { "when": "view == teroshdl-view-runs", - "command": "teroshdl.view.runs.run_all", "group": "navigation" - } - - ,{ + }, + { "when": "view == teroshdl-view-runs", - "command": "teroshdl.view.runs.stop", "group": "navigation" - } - - ,{ + }, + { "when": "view == teroshdl-view-runs", - "command": "teroshdl.view.runs.refresh", "group": "navigation" - } - - ,{ + }, + { "when": "view == teroshdl-view-tasks && view == teroshdl-view-tasks", - "command": "teroshdl.view.tasks.stop", "group": "navigation" - } - - ,{ + }, + { "when": "view == teroshdl-view-tasks && view == teroshdl-view-tasks", - "command": "teroshdl.view.tasks.clean", "group": "navigation" - } - - ,{ + }, + { "when": "view == teroshdl-view-watcher && view == teroshdl-view-watcher", - "command": "teroshdl.view.watcher.add", "group": "navigation" - } - - ,{ + }, + { "when": "view == teroshdl-view-output && view == teroshdl-view-output", - "command": "teroshdl.view.outputs.clean", "group": "navigation" } - ], "view/item/context": [ - - { - "when": "viewItem == project && view == teroshdl-project", - "command": "teroshdl.configuration.project", - "group": "inline" - } - - ,{ - "when": "viewItem == project && view == teroshdl-project", - "command": "teroshdl.view.project.delete", - "group": "inline" - } - - ,{ - "when": "viewItem == project && view == teroshdl-project", - "command": "teroshdl.view.project.rename", - "group": "inline" - } - - ,{ - "when": "viewItem == library && view == teroshdl-view-source", - "command": "teroshdl.view.source.add_source_to_library", - "group": "inline" - } - - ,{ - "when": "viewItem == library && view == teroshdl-view-source", - "command": "teroshdl.view.source.delete_library", - "group": "inline" - } - - ,{ - "when": "viewItem == source && view == teroshdl-view-source", - "command": "teroshdl.view.source.properties", - "group": "inline" - } - - ,{ - "when": "viewItem == source && view == teroshdl-view-source", - "command": "teroshdl.view.source.delete_source", - "group": "inline" - } - - ,{ - "when": "viewItem == source && view == teroshdl-view-source", - "command": "teroshdl.view.source.select_toplevel", - "group": "inline" - } - - ,{ - "when": "viewItem == run && view == teroshdl-view-runs", - "command": "teroshdl.view.runs.run", - "group": "inline" - } - - ,{ - "when": "viewItem =~ /logs/ && view == teroshdl-view-tasks", - "command": "teroshdl.view.tasks.logs", - "group": "inline" - } - - ,{ - "when": "viewItem =~ /report/ && view == teroshdl-view-tasks", - "command": "teroshdl.view.tasks.report", - "group": "inline" - } - - ,{ - "when": "viewItem =~ /timinganalyzer/ && view == teroshdl-view-tasks", - "command": "teroshdl.view.tasks.timing_analyzer", - "group": "inline" - } - - ,{ - "when": "viewItem =~ /technologymapviewer/ && view == teroshdl-view-tasks", - "command": "teroshdl.view.tasks.technology_map_viewer", - "group": "inline" - } - - ,{ - "when": "viewItem =~ /snapshotviewer/ && view == teroshdl-view-tasks", - "command": "teroshdl.view.tasks.snapshotviewer", - "group": "inline" - } - - ,{ - "when": "viewItem == watcher && view == teroshdl-view-watcher", - "command": "teroshdl.view.watcher.delete", - "group": "inline" - } - + { + "when": "viewItem == project && view == teroshdl-project", + "command": "teroshdl.configuration.project", + "group": "inline" + }, + { + "when": "viewItem == project && view == teroshdl-project", + "command": "teroshdl.view.project.delete", + "group": "inline" + }, + { + "when": "viewItem == project && view == teroshdl-project", + "command": "teroshdl.view.project.rename", + "group": "inline" + }, + { + "when": "viewItem == library && view == teroshdl-view-source", + "command": "teroshdl.view.source.add_source_to_library", + "group": "inline" + }, + { + "when": "viewItem == library && view == teroshdl-view-source", + "command": "teroshdl.view.source.delete_library", + "group": "inline" + }, + { + "when": "viewItem == source && view == teroshdl-view-source", + "command": "teroshdl.view.source.properties", + "group": "inline" + }, + { + "when": "viewItem == source && view == teroshdl-view-source", + "command": "teroshdl.view.source.delete_source", + "group": "inline" + }, + { + "when": "viewItem == source && view == teroshdl-view-source", + "command": "teroshdl.view.source.select_toplevel", + "group": "inline" + }, + { + "when": "viewItem == run && view == teroshdl-view-runs", + "command": "teroshdl.view.runs.run", + "group": "inline" + }, + { + "when": "viewItem =~ /logs/ && view == teroshdl-view-tasks", + "command": "teroshdl.view.tasks.logs", + "group": "inline" + }, + { + "when": "viewItem =~ /report/ && view == teroshdl-view-tasks", + "command": "teroshdl.view.tasks.report", + "group": "inline" + }, + { + "when": "viewItem =~ /timinganalyzer/ && view == teroshdl-view-tasks", + "command": "teroshdl.view.tasks.timing_analyzer", + "group": "inline" + }, + { + "when": "viewItem =~ /technologymapviewer/ && view == teroshdl-view-tasks", + "command": "teroshdl.view.tasks.technology_map_viewer", + "group": "inline" + }, + { + "when": "viewItem =~ /snapshotviewer/ && view == teroshdl-view-tasks", + "command": "teroshdl.view.tasks.snapshotviewer", + "group": "inline" + }, + { + "when": "viewItem == watcher && view == teroshdl-view-watcher", + "command": "teroshdl.view.watcher.delete", + "group": "inline" + } ], "editor/title": [ - { "when": "resourceLangId == verilog || resourceLangId == systemverilog || resourceLangId == vhdl", "command": "teroshdl.generate_template", "group": "navigation" - } - - ,{ + }, + { "when": "resourceLangId == verilog || resourceLangId == systemverilog || resourceLangId == vhdl", "command": "teroshdl.state_machine.viewer", "group": "navigation" - } - - ,{ + }, + { "when": "resourceLangId == verilog || resourceLangId == systemverilog || resourceLangId == vhdl", "command": "teroshdl.netlist.viewer", "group": "navigation" - } - - ,{ + }, + { "when": "resourceLangId == verilog || resourceLangId == systemverilog || resourceLangId == vhdl", "command": "teroshdl.format", "group": "navigation" - } - - ,{ + }, + { "when": "resourceLangId == verilog || resourceLangId == systemverilog || resourceLangId == vhdl", "command": "teroshdl.documentation.module", "group": "navigation" } - ] }, "commands": [ { "command": "teroshdl.go_to_parent", "title": "Go to parent file" - }, + }, { "command": "teroshdl.open", "title": "Open file with TerosHDL" - }, + }, { "command": "teroshdl.configuration.global", "title": "TerosHDL: Open Global Settings Menu" - }, + }, { "command": "teroshdl.verifySetup", "title": "TerosHDL: Verify Setup" - }, + }, { "command": "teroshdl.waveform", "title": "Open waveform viewer" - }, + }, { "command": "teroshdl.view.project.add", "icon": { @@ -449,7 +391,7 @@ "dark": "resources/icon/dark/add.svg" }, "title": "Add project" - }, + }, { "command": "teroshdl.configuration.project", "icon": { @@ -457,7 +399,7 @@ "dark": "resources/icon/dark/gear.svg" }, "title": "Open Project Settings" - }, + }, { "command": "teroshdl.view.project.delete", "icon": { @@ -465,7 +407,7 @@ "dark": "resources/icon/dark/chrome-close.svg" }, "title": "Delete project" - }, + }, { "command": "teroshdl.view.project.rename", "icon": { @@ -473,7 +415,7 @@ "dark": "resources/icon/dark/edit.svg" }, "title": "Rename project" - }, + }, { "command": "teroshdl.view.source.save_project", "icon": { @@ -481,7 +423,7 @@ "dark": "resources/icon/dark/save.svg" }, "title": "Save Project" - }, + }, { "command": "teroshdl.view.source.search", "icon": { @@ -489,7 +431,7 @@ "dark": "resources/icon/dark/search.svg" }, "title": "Search" - }, + }, { "command": "teroshdl.view.source.add", "icon": { @@ -497,7 +439,7 @@ "dark": "resources/icon/dark/add.svg" }, "title": "Add" - }, + }, { "command": "teroshdl.view.source.add_source_to_library", "icon": { @@ -505,7 +447,7 @@ "dark": "resources/icon/dark/add.svg" }, "title": "Add to library" - }, + }, { "command": "teroshdl.view.source.delete_library", "icon": { @@ -513,7 +455,7 @@ "dark": "resources/icon/dark/dash.svg" }, "title": "Delete library" - }, + }, { "command": "teroshdl.view.source.properties", "icon": { @@ -521,7 +463,7 @@ "dark": "resources/icon/dark/gear.svg" }, "title": "File Properties" - }, + }, { "command": "teroshdl.view.source.delete_source", "icon": { @@ -529,7 +471,7 @@ "dark": "resources/icon/dark/dash.svg" }, "title": "Delete source" - }, + }, { "command": "teroshdl.view.source.select_toplevel", "icon": { @@ -537,7 +479,7 @@ "dark": "resources/icon/dark/check.svg" }, "title": "Select source as toplevel" - }, + }, { "command": "teroshdl.view.dependency.refresh", "icon": { @@ -545,7 +487,7 @@ "dark": "resources/icon/dark/refresh.svg" }, "title": "Refresh" - }, + }, { "command": "teroshdl.view.dependency.schematic", "icon": { @@ -553,7 +495,7 @@ "dark": "resources/icon/dark/list-tree.svg" }, "title": "Schematic viewer" - }, + }, { "command": "teroshdl.view.dependency.viewer", "icon": { @@ -561,7 +503,7 @@ "dark": "resources/icon/dark/dep.svg" }, "title": "Dependencies viewer" - }, + }, { "command": "teroshdl.view.runs.run_all", "icon": { @@ -569,7 +511,7 @@ "dark": "resources/icon/dark/run-all.svg" }, "title": "Run all" - }, + }, { "command": "teroshdl.view.runs.stop", "icon": { @@ -577,7 +519,7 @@ "dark": "resources/icon/dark/stop.svg" }, "title": "Stop" - }, + }, { "command": "teroshdl.view.runs.refresh", "icon": { @@ -585,7 +527,7 @@ "dark": "resources/icon/dark/refresh.svg" }, "title": "Refresh" - }, + }, { "command": "teroshdl.view.runs.run", "icon": { @@ -593,7 +535,7 @@ "dark": "resources/icon/dark/run.svg" }, "title": "TerosHDL: Run Tool" - }, + }, { "command": "teroshdl.view.tasks.stop", "icon": { @@ -601,7 +543,7 @@ "dark": "resources/icon/dark/stop.svg" }, "title": "Stop" - }, + }, { "command": "teroshdl.view.tasks.clean", "icon": { @@ -609,7 +551,7 @@ "dark": "resources/icon/dark/trash.svg" }, "title": "Clean project" - }, + }, { "command": "teroshdl.view.tasks.logs", "icon": { @@ -617,7 +559,7 @@ "dark": "resources/icon/dark/database.svg" }, "title": "Open Log" - }, + }, { "command": "teroshdl.view.tasks.report", "icon": { @@ -625,7 +567,7 @@ "dark": "resources/icon/dark/output.svg" }, "title": "Open Report" - }, + }, { "command": "teroshdl.view.tasks.timing_analyzer", "icon": { @@ -633,7 +575,7 @@ "dark": "resources/icon/dark/watch.svg" }, "title": "Open Timing Analyzer" - }, + }, { "command": "teroshdl.view.tasks.technology_map_viewer", "icon": { @@ -641,7 +583,7 @@ "dark": "resources/icon/dark/search.svg" }, "title": "Open Technology Map Viewer" - }, + }, { "command": "teroshdl.view.tasks.snapshotviewer", "icon": { @@ -649,63 +591,63 @@ "dark": "resources/icon/dark/eye.svg" }, "title": "Open Snapshop Viewer" - }, + }, { "command": "teroshdl.project.quartus.rtlAnalyzer", "title": "TerosHDL [Quartus]: Open RTL Analyzer" - }, + }, { "command": "teroshdl.project.quartus.compileDesigh", "title": "TerosHDL [Quartus]: Run Compile Design" - }, + }, { "command": "teroshdl.project.quartus.analysisAndSynthesis", "title": "TerosHDL [Quartus]: run Analysis and Synthesis" - }, + }, { "command": "teroshdl.project.quartus.analysisAndElaboration", "title": "TerosHDL [Quartus]: run Analysis and Elaboration" - }, + }, { "command": "teroshdl.project.quartus.synthesis", "title": "TerosHDL [Quartus]: run Synthesis" - }, + }, { "command": "teroshdl.project.quartus.earlyTimingAnalysis", "title": "TerosHDL [Quartus]: run Early Timing Analysis" - }, + }, { "command": "teroshdl.project.quartus.fitter", "title": "TerosHDL [Quartus]: run Fitter" - }, + }, { "command": "teroshdl.project.quartus.fitterImplement", "title": "TerosHDL [Quartus]: run Fitter Implement" - }, + }, { "command": "teroshdl.project.quartus.plan", "title": "TerosHDL [Quartus]: run Plan" - }, + }, { "command": "teroshdl.project.quartus.place", "title": "TerosHDL [Quartus]: run Place" - }, + }, { "command": "teroshdl.project.quartus.route", "title": "TerosHDL [Quartus]: run Route" - }, + }, { "command": "teroshdl.project.quartus.fitterFinalize", "title": "TerosHDL [Quartus]: run Fitter Finalize" - }, + }, { "command": "teroshdl.project.quartus.timingAnalysisSignoff", "title": "TerosHDL [Quartus]: run Timing Analysis Signoff" - }, + }, { "command": "teroshdl.project.quartus.assembler", "title": "TerosHDL [Quartus]: run Assembler" - }, + }, { "command": "teroshdl.view.watcher.add", "icon": { @@ -713,7 +655,7 @@ "dark": "resources/icon/dark/add.svg" }, "title": "Add" - }, + }, { "command": "teroshdl.view.watcher.delete", "icon": { @@ -721,7 +663,7 @@ "dark": "resources/icon/dark/dash.svg" }, "title": "Delete watcher" - }, + }, { "command": "teroshdl.view.outputs.clean", "icon": { @@ -729,7 +671,7 @@ "dark": "resources/icon/dark/trash.svg" }, "title": "Clean project" - }, + }, { "command": "teroshdl.generate_template", "icon": { @@ -737,7 +679,7 @@ "dark": "resources/icon/dark/file-code.svg" }, "title": "TerosHDL: Generate template" - }, + }, { "command": "teroshdl.state_machine.viewer", "icon": { @@ -745,7 +687,7 @@ "dark": "resources/icon/dark/state-machine.svg" }, "title": "State machine viewer" - }, + }, { "command": "teroshdl.netlist.viewer", "icon": { @@ -753,7 +695,7 @@ "dark": "resources/icon/dark/list-tree.svg" }, "title": "Schematic viewer" - }, + }, { "command": "teroshdl.format", "icon": { @@ -761,7 +703,7 @@ "dark": "resources/icon/dark/check.svg" }, "title": "Format" - }, + }, { "command": "teroshdl.documentation.module", "icon": { @@ -772,115 +714,161 @@ } ], "languages": [ - - { - "id": "vhdl", - "aliases": ["VHDL", "vhdl"], - "configuration": "./configs/vhdl.configuration.json", - "extensions": [".vhd", ".vho", ".vhdl", ".vhd"], - "icon": { - "light": "./resources/icon/light/vhdl.svg", - "dark": "./resources/icon/dark/vhdl.svg" - } - } - - ,{ - "id": "verilog", - "aliases": ["Verilog", "verilog"], - "configuration": "./configs/verilog.configuration.json", - "extensions": [".v", ".vh", ".vl"], - "icon": { - "light": "./resources/icon/light/verilog.svg", - "dark": "./resources/icon/dark/verilog.svg" - } - } - - ,{ - "id": "systemverilog", - "aliases": ["System Verilog", "systemverilog"], - "configuration": "./configs/systemverilog.configuration.json", - "extensions": [".sv", ".svh", ".SV"], - "icon": { - "light": "./resources/icon/light/systemverilog.svg", - "dark": "./resources/icon/dark/systemverilog.svg" - } - } - - ,{ - "id": "vcd", - "extensions": [".vcd"] - } - - ,{ - "id": "logTerosHDL", - "extensions": [".logTerosHDL"] - } - - ,{ - "id": "gtkw_waveconfig", - "extensions": [".gtkw"] - } - - ,{ - "id": "gtkw_wavebin", - "extensions": [".fst", ".ghw"] - } - - ,{ - "id": "tcl", - "aliases": ["TCL", "tcl"], - "configuration": "./configs/tcl.configuration.json", - "extensions": [".tcl", ".pro"], - "icon": { - "light": "./resources/icon/light/tcl.svg", - "dark": "./resources/icon/dark/tcl.svg" - } - } - - ,{ - "id": "ucf", - "aliases": ["vivado ucf", "ucf constraints"], - "configuration": "./configs/ucfconstraints.configuration.json", - "extensions": [".ucf"], - "icon": { - "light": "./resources/icon/light/ucf.svg", - "dark": "./resources/icon/dark/ucf.svg" - } - } - - ,{ - "id": "xdc", - "aliases": ["vivado xdc", "xdc constraints"], - "configuration": "./configs/xdcconstraints.configuration.json", - "extensions": [".xdc", ".sdc"], - "icon": { - "light": "./resources/icon/light/xdc.svg", - "dark": "./resources/icon/dark/xdc.svg" - } - } - - ,{ - "id": "ldc", - "aliases": ["lattice constraints"], - "configuration": "./configs/xdcconstraints.configuration.json", - "extensions": [".ldc", ".pdc"], - "icon": { - "light": "./resources/icon/light/xdc.svg", - "dark": "./resources/icon/dark/xdc.svg" - } - } - - ,{ - "id": "TL-Verilog", - "aliases": ["TL-Verilog", "tlv", "Transactional-Level Verilog"], - "configuration": "./configs/tlverilog.configuration.json", - "extensions": [".tlv"], - "icon": { - "light": "./resources/icon/light/verilog.svg", - "dark": "./resources/icon/dark/verilog.svg" + { + "id": "vhdl", + "aliases": [ + "VHDL", + "vhdl" + ], + "configuration": "./configs/vhdl.configuration.json", + "extensions": [ + ".vhd", + ".vho", + ".vhdl", + ".vhd" + ], + "icon": { + "light": "./resources/icon/light/vhdl.svg", + "dark": "./resources/icon/dark/vhdl.svg" + } + }, + { + "id": "verilog", + "aliases": [ + "Verilog", + "verilog" + ], + "configuration": "./configs/verilog.configuration.json", + "extensions": [ + ".v", + ".vh", + ".vl" + ], + "icon": { + "light": "./resources/icon/light/verilog.svg", + "dark": "./resources/icon/dark/verilog.svg" + } + }, + { + "id": "systemverilog", + "aliases": [ + "System Verilog", + "systemverilog" + ], + "configuration": "./configs/systemverilog.configuration.json", + "extensions": [ + ".sv", + ".svh", + ".SV" + ], + "icon": { + "light": "./resources/icon/light/systemverilog.svg", + "dark": "./resources/icon/dark/systemverilog.svg" + } + }, + { + "id": "vcd", + "extensions": [ + ".vcd" + ] + }, + { + "id": "logTerosHDL", + "extensions": [ + ".logTerosHDL" + ] + }, + { + "id": "gtkw_waveconfig", + "extensions": [ + ".gtkw" + ] + }, + { + "id": "gtkw_wavebin", + "extensions": [ + ".fst", + ".ghw" + ] + }, + { + "id": "tcl", + "aliases": [ + "TCL", + "tcl" + ], + "configuration": "./configs/tcl.configuration.json", + "extensions": [ + ".tcl", + ".pro" + ], + "icon": { + "light": "./resources/icon/light/tcl.svg", + "dark": "./resources/icon/dark/tcl.svg" + } + }, + { + "id": "ucf", + "aliases": [ + "vivado ucf", + "ucf constraints" + ], + "configuration": "./configs/ucfconstraints.configuration.json", + "extensions": [ + ".ucf" + ], + "icon": { + "light": "./resources/icon/light/ucf.svg", + "dark": "./resources/icon/dark/ucf.svg" + } + }, + { + "id": "xdc", + "aliases": [ + "vivado xdc", + "xdc constraints" + ], + "configuration": "./configs/xdcconstraints.configuration.json", + "extensions": [ + ".xdc", + ".sdc" + ], + "icon": { + "light": "./resources/icon/light/xdc.svg", + "dark": "./resources/icon/dark/xdc.svg" + } + }, + { + "id": "ldc", + "aliases": [ + "lattice constraints" + ], + "configuration": "./configs/xdcconstraints.configuration.json", + "extensions": [ + ".ldc", + ".pdc" + ], + "icon": { + "light": "./resources/icon/light/xdc.svg", + "dark": "./resources/icon/dark/xdc.svg" + } + }, + { + "id": "TL-Verilog", + "aliases": [ + "TL-Verilog", + "tlv", + "Transactional-Level Verilog" + ], + "configuration": "./configs/tlverilog.configuration.json", + "extensions": [ + ".tlv" + ], + "icon": { + "light": "./resources/icon/light/verilog.svg", + "dark": "./resources/icon/dark/verilog.svg" + } } - } - ], "snippets": [ { @@ -916,7 +904,6 @@ "path": "./snippets/verilog/verilog.json" } ], - "keybindings": [ { "command": "teroshdl.go_to_parent", @@ -926,99 +913,98 @@ } ] }, - "scripts": { - "build-package": "cd auto_package && ./gen.sh", - "clean": "shx rm -rf out", - "vscode:prepublish": "npm run generate-examples & npm run compile", - "compile": "npm run-script copy-files & npm run-script build-webviews & npm run-script build-webviews-configuration & tsc -p ./", - "lint": "eslint src", - "watch": "npm run-script copy-files & tsc --watch --p ./tsconfig.json & nodemon --ignore 'resources/webviews/reporters/**/wb/' --watch resources/webviews/reporters -e js,ts,tsx,html --exec \"npm run-script build-webviews\"", - "generate-examples": "cd ./resources/project_manager; ./copy_examples.sh", - "pre-package": "mkdir ./node_modules/teroshdl2/node_modules/onml/lib; cp ./node_modules/teroshdl2/node_modules/onml/*.js ./node_modules/teroshdl2/node_modules/onml/lib", - "package": "npm run pre-package & vsce package --allow-star-activation", - "package-prerelease": "npm run pre-package & vsce package --pre-release -o ./pre-release.vsix --allow-star-activation", - "auto-package": "cd auto_package & ./gen.sh", - "build-webviews": "NODE_ENV=production node resources/webviews/reporters/esbuild.js", - "build-webviews-configuration": "NODE_ENV=production node resources/webviews/fileConfiguration/esbuild.js", - "compile-esbuild": "NODE_ENV=production node ./esbuild.js", - "copy-files": "python3 copy_files.py ", + "build-package": "cd auto_package && ./gen.sh", + "clean": "shx rm -rf out", + "vscode:prepublish": "npm run generate-examples & npm run compile", + "compile": "npm run-script copy-files && npm run-script build-webviews & npm run-script build-webviews-configuration & tsc -p ./", + "lint": "eslint src", + "watch": "npm run-script copy-files & tsc --watch --p ./tsconfig.json & nodemon --ignore 'resources/webviews/reporters/**/wb/' --watch resources/webviews/reporters -e js,ts,tsx,html --exec \"npm run-script build-webviews\"", + "generate-examples": "cd ./resources/project_manager; ./copy_examples.sh", + "pre-package": "mkdir ./node_modules/teroshdl2/node_modules/onml/lib; cp ./node_modules/teroshdl2/node_modules/onml/*.js ./node_modules/teroshdl2/node_modules/onml/lib", + "package": "npm run pre-package & vsce package --allow-star-activation", + "package-prerelease": "npm run pre-package & vsce package --pre-release -o ./pre-release.vsix --allow-star-activation", + "auto-package": "cd auto_package & ./gen.sh", + "build-webviews": "cross-env NODE_ENV=production node resources/webviews/reporters/esbuild.js", + "build-webviews-configuration": "cross-env NODE_ENV=production node resources/webviews/fileConfiguration/esbuild.js", + "compile-esbuild": "cross-env NODE_ENV=production node ./esbuild.js", + "copy-files": "python3 copy_files.py ", "test": "node --trace-warnings --experimental-vm-modules ./node_modules/.bin/jest --forceExit --runInBand --config ./jest.config.json" }, "dependencies": { + "@oclif/core": "^1", + "@oclif/plugin-help": "^5", + "@oclif/plugin-plugins": "^2.0.1", "@octokit/rest": "16.36.0", "@types/node-fetch": "2.5.7", - "@types/semver": "6.2.0", - "abort-controller": "3.0.0", - "fs-extra": "8.1.0", - "netlistsvg": "https://github.com/TerosTechnology/netlistsvg.git#hierarchy", - "open": "8.3.0", - "proper-lockfile": "4.1.1", - "semver": "^7.6.3", - "shelljs": "^0.8.3", - "tmp": "0.2.1", - "vscode-languageclient": "^9.0.1", - "xml2js": "^0.6.2", - "nunjucks": "^3.2.0", "@types/nunjucks": "^3.1.4", - "tree-kill": "1.2.2", + "@types/semver": "6.2.0", "@vscode/webview-ui-toolkit": "^1.4.0", - "esbuild-plugin-alias": "^0.2.1", - "@oclif/core": "^1", - "@oclif/plugin-help": "^5", - "@oclif/plugin-plugins": "^2.0.1", "@yowasp/yosys": "0.41.721", + "abort-controller": "3.0.0", "axios": "^1.7.2", "chokidar": "3.5.3", "cli-color": "^2.0.3", "clone": "^2.1.2", "console-table-printer": "^2.11.0", + "esbuild-plugin-alias": "^0.2.1", + "fast-json-stable-stringify": "^2.1.0", "fast-xml-parser": "4.3.2", + "fs-extra": "8.1.0", "jest-html-reporter": "^3.7.0", "js-yaml": "^4.1.0", "json5": "^2.2.3", "lodash": "^4.17.21", + "module-alias": "^2.2.3", + "netlistsvg": "https://github.com/TerosTechnology/netlistsvg.git#hierarchy", + "nunjucks": "^3.2.0", "onml": "2.1.0", + "open": "8.3.0", + "proper-lockfile": "4.1.1", "pyodide": "0.24.1", + "semver": "^7.6.3", + "shelljs": "^0.8.3", "showdown": "1.9.1", "showdown-highlight": "2.1.8", "sql.js": "^1.9.0", "state-machine-cat": "10.1.11", - "fast-json-stable-stringify": "^2.1.0", "svg.js": "2.7.1", "svgdom": "^0.0.21", "temp": "0.9.4", "tiny-glob": "^0.2.9", + "tmp": "0.2.1", + "tree-kill": "1.2.2", + "vscode-languageclient": "^9.0.1", "wavedrom": "3.3.0", "web-tree-sitter": "^0.20.7", - "module-alias": "^2.2.3" + "xml2js": "^0.6.2" }, "devDependencies": { - "@types/node": "^17.0.31", - "@types/vscode": "^1.45.0", - "js-yaml": "^3.13.1", - "shx": "^0.3.3", - "esbuild": "^0.16.17", - "nodemon": "^3.0.2", - "assert": "^2.0.0", - "jest": "^29.7.0", - "jest-html-reporters": "^3.1.4", - "ts-jest": "^29.1.2", - "typedoc": "^0.23.9", - "typedoc-theme-hierarchy": "^3.0.0", "@types/assert": "^1.5.6", - "chai": "^4", "@types/chai": "^4", "@types/cli-color": "^2.0.2", "@types/jest": "^29.4.3", "@types/js-yaml": "^4.0.5", + "@types/node": "^17.0.31", "@types/temp": "^0.9.4", - "typescript": "^4.8.2", + "@types/vscode": "^1.45.0", "@typescript-eslint/eslint-plugin": "^8.7.0", "@typescript-eslint/parser": "^8.7.0", + "assert": "^2.0.0", + "chai": "^4", + "cross-env": "^10.1.0", + "esbuild": "^0.16.17", "eslint": "^9.11.1", "eslint-config-prettier": "^9.0.0", - "eslint-plugin-prettier": "^4.0.0" + "eslint-plugin-prettier": "^4.0.0", + "jest": "^29.7.0", + "jest-html-reporters": "^3.1.4", + "js-yaml": "^3.13.1", + "nodemon": "^3.0.2", + "shx": "^0.3.3", + "ts-jest": "^29.1.2", + "typedoc": "^0.23.9", + "typedoc-theme-hierarchy": "^3.0.0", + "typescript": "^4.8.2" } - -} \ No newline at end of file +} diff --git a/src/colibri/config/config_declaration.ts b/src/colibri/config/config_declaration.ts index 2e9158af..9faff12e 100644 --- a/src/colibri/config/config_declaration.ts +++ b/src/colibri/config/config_declaration.ts @@ -17,6 +17,8 @@ // You should have received a copy of the GNU General Public License // along with colibri2. If not, see . +import { string } from "@oclif/core/lib/parser"; + export type e_config = { "general" : { "general" : e_general_general, @@ -39,6 +41,7 @@ export type e_config = { "general" : e_linter_general, "vhdlls" : e_linter_vhdlls, "ghdl" : e_linter_ghdl, + "nvc" : e_linter_nvc, "icarus" : e_linter_icarus, "modelsim" : e_linter_modelsim, "verible" : e_linter_verible, @@ -86,6 +89,7 @@ export type e_config = { "activehdl" : e_tools_activehdl, "questa" : e_tools_questa, "raptor" : e_tools_raptor, + "nvc" : e_tools_nvc, } [key: string]: { [key: string]: any; @@ -182,6 +186,10 @@ export type e_linter_vhdlls = { export type e_linter_ghdl = { arguments : string, }; + +export type e_linter_nvc = { + arguments : string, +}; export type e_linter_icarus = { arguments : string, @@ -322,7 +330,59 @@ export type e_tools_ghdl = { disp_tree : e_tools_ghdl_disp_tree, no_run : boolean, }; - + +export type e_tools_nvc = { + installation_path : string, + vhdl_standard : e_tools_nvc_vhdl_standard, + ieee_library : e_tools_nvc_ieee_library, + relaxed_parsing : boolean, + unicode_support : boolean, + psl_enabled : boolean, + work_library : string, + library_paths : any[], + check_syntax_options : any[], + analyze_options : any[], + elaborate_options : any[], + run_options : any[], + synthesis_options : any[], + extra_flags : any[], + relaxed_rules : boolean, + bind_checks : boolean, + vital_checks : boolean, + simulation_time : string, + resolution_limit : string, + stack_size : string, + stop_delta_cycles : number, + waveform_enabled : boolean, + waveform_format : e_tools_nvc_waveform_format, + waveform_options : any[], + wave_start_time : string, + vcd_4states : boolean, + vcd_nodate : boolean, + read_wave_opt : string, + write_wave_opt : string, + debug_level : e_tools_nvc_debug_level, + verbose : boolean, + warnings_as_errors : boolean, + suppress_warnings : any[], + assert_level : e_tools_nvc_assert_level, + display_time : boolean, + unbuffered_output : boolean, + max_stack_alloc : number, + backtrace_severity : e_tools_nvc_backtrace_severity, + ieee_asserts : e_tools_nvc_ieee_asserts, + asserts_policy : e_tools_nvc_asserts_policy, + sdf_file : string, + vpi_modules : any[], + vhpi_modules : any[], + vpi_trace_file : string, + vhpi_trace_file : string, + psl_report_file : string, + psl_report_uncovered : boolean, + disp_tree : e_tools_nvc_disp_tree, + no_run : boolean, +}; + export type e_tools_icarus = { installation_path : string, timescale : string, @@ -694,6 +754,7 @@ export enum e_linter_general_linter_vhdl { modelsim = "modelsim", vivado = "vivado", none = "none", + nvc = "nvc", } export enum e_linter_general_linter_verilog { disabled = "disabled", @@ -753,7 +814,9 @@ export enum e_tools_general_select_tool { radiant = "radiant", sandpiper = "sandpiper", yosys = "yosys", + nvc = "nvc", } + export enum e_tools_general_execution_mode { gui = "gui", cmd = "cmd", @@ -854,6 +917,58 @@ export enum e_tools_ghdl_disp_tree { proc = "proc", port = "port", } +export enum e_tools_nvc_vhdl_standard { + auto = "auto", + vhdl87 = "vhdl87", + vhdl93 = "vhdl93", + vhdl02 = "vhdl02", + vhdl08 = "vhdl08", + vhdl19 = "vhdl19", +} +export enum e_tools_nvc_ieee_library { + standard = "standard", + synopsys = "synopsys", +} +export enum e_tools_nvc_waveform_format { + vcd = "vcd", + ghw = "ghw", + fst = "fst", +} +export enum e_tools_nvc_debug_level { + none = "none", + minimal = "minimal", + full = "full", +} +export enum e_tools_nvc_assert_level { + note = "note", + warning = "warning", + error = "error", + failure = "failure", + none = "none", +} +export enum e_tools_nvc_backtrace_severity { + note = "note", + warning = "warning", + error = "error", + failure = "failure", + none = "none", +} +export enum e_tools_nvc_ieee_asserts { + enable = "enable", + disable = "disable", + disable_at_0 = "disable-at-0", +} +export enum e_tools_nvc_asserts_policy { + enable = "enable", + disable = "disable", + disable_at_0 = "disable-at-0", +} +export enum e_tools_nvc_disp_tree { + none = "none", + inst = "inst", + proc = "proc", + port = "port", +} export enum e_tools_icestorm_pnr { arachne = "arachne", next = "next", @@ -1071,6 +1186,9 @@ export function get_default_config(): e_config { ghdl: { arguments : "", }, + nvc: { + arguments : "", + }, icarus: { arguments : "", }, @@ -1444,6 +1562,57 @@ export function get_default_config(): e_config { simulator_pnr : e_tools_raptor_simulator_pnr.ghdl, simulation_options_pnr : "--stop-time=1000ns", }, + nvc: { + installation_path: "", + vhdl_standard : e_tools_nvc_vhdl_standard.vhdl08, + ieee_library : e_tools_nvc_ieee_library.standard, + relaxed_parsing : false, + unicode_support : false, + psl_enabled : false, + work_library : "work", + library_paths : [], + check_syntax_options : [], + analyze_options : [], + elaborate_options : [], + run_options : [], + synthesis_options : [], + extra_flags : [], + relaxed_rules : false, + bind_checks : true, + vital_checks : false, + simulation_time : "", + resolution_limit : "", + stack_size : "", + stop_delta_cycles : 0, + waveform_enabled : true, + waveform_format : e_tools_nvc_waveform_format.vcd, + waveform_options : [], + wave_start_time : "", + vcd_4states : false, + vcd_nodate : false, + read_wave_opt : "", + write_wave_opt : "", + debug_level : e_tools_nvc_debug_level.none, + verbose : false, + warnings_as_errors : false, + suppress_warnings : [], + assert_level : e_tools_nvc_assert_level.error, + display_time : false, + unbuffered_output : false, + max_stack_alloc : 0, + backtrace_severity : e_tools_nvc_backtrace_severity.error, + ieee_asserts : e_tools_nvc_ieee_asserts.enable, + asserts_policy : e_tools_nvc_asserts_policy.enable, + sdf_file : "", + vpi_modules : [], + vhpi_modules : [], + vpi_trace_file : "", + vhpi_trace_file : "", + psl_report_file : "", + psl_report_uncovered : false, + disp_tree : e_tools_nvc_disp_tree.none, + no_run : false, + }, }, }; } @@ -2064,6 +2233,9 @@ export function get_config_from_json(json_config: any): e_config { if ( current_value_48 === "none"){ default_config['linter']['general']['linter_vhdl'] = e_linter_general_linter_vhdl.none; } + if ( current_value_48 === "nvc"){ + default_config['linter']['general']['linter_vhdl'] = e_linter_general_linter_vhdl.nvc; + } // linter -> general -> linter_verilog let current_value_49 = undefined; @@ -2158,6 +2330,16 @@ export function get_config_from_json(json_config: any): e_config { if (typeof current_value_55 === 'string'){ default_config['linter']['ghdl']['arguments'] = current_value_55; } + + // linter -> nvc -> arguments + let current_value_55_nvc = undefined; + try { + current_value_55_nvc = json_config['linter']['nvc']['arguments']; + } + catch(e){} + if (typeof current_value_55_nvc === 'string'){ + default_config['linter']['nvc']['arguments'] = current_value_55_nvc; + } // linter -> icarus -> arguments let current_value_56 = undefined; diff --git a/src/colibri/config/config_web.ts b/src/colibri/config/config_web.ts index ba3af11f..5300f331 100755 --- a/src/colibri/config/config_web.ts +++ b/src/colibri/config/config_web.ts @@ -760,6 +760,9 @@ body.vscode-high-contrast {
GHDL linter
+
+ NVC linter +
Icarus linter
@@ -1579,6 +1582,7 @@ body.vscode-high-contrast { + + + +
@@ -5229,6 +5250,7 @@ body.vscode-high-contrast { document.getElementById("linter-general").classList.remove('active'); document.getElementById("linter-vhdlls").classList.remove('active'); document.getElementById("linter-ghdl").classList.remove('active'); + document.getElementById("linter-nvc").classList.remove('active'); document.getElementById("linter-icarus").classList.remove('active'); document.getElementById("linter-modelsim").classList.remove('active'); document.getElementById("linter-verible").classList.remove('active'); @@ -5306,6 +5328,9 @@ body.vscode-high-contrast { if (document.getElementById("btn-linter-ghdl")) { document.getElementById("btn-linter-ghdl").classList.remove('selected'); } + if (document.getElementById("btn-linter-nvc")) { + document.getElementById("btn-linter-nvc").classList.remove('selected'); + } if (document.getElementById("btn-linter-icarus")) { document.getElementById("btn-linter-icarus").classList.remove('selected'); } @@ -5503,6 +5528,12 @@ body.vscode-high-contrast { enable_tab("linter", "ghdl"); }); } + if (document.getElementById("btn-linter-nvc")) { + document.getElementById("btn-linter-nvc").addEventListener("click", function(e) { + e.preventDefault(); + enable_tab("linter", "nvc"); + }); + } if (document.getElementById("btn-linter-icarus")) { document.getElementById("btn-linter-icarus").addEventListener("click", function(e) { e.preventDefault(); @@ -5929,6 +5960,9 @@ body.vscode-high-contrast { config["linter"]["ghdl"] = {} element_value = document.getElementById("linter-ghdl-arguments").value; config["linter"]["ghdl"]["arguments"] = element_value + config["linter"]["nvc"] = {} + element_value = document.getElementById("linter-nvc-arguments").value; + config["linter"]["nvc"]["arguments"] = element_value config["linter"]["icarus"] = {} element_value = document.getElementById("linter-icarus-arguments").value; config["linter"]["icarus"]["arguments"] = element_value @@ -6931,6 +6965,9 @@ body.vscode-high-contrast { if (config["linter"] && config["linter"]["ghdl"] && config["linter"]["ghdl"]["arguments"] !== undefined) { document.getElementById("linter-ghdl-arguments").value = config["linter"]["ghdl"]["arguments"]; } + if (config["linter"] && config["linter"]["nvc"] && config["linter"]["nvc"]["arguments"] !== undefined) { + document.getElementById("linter-nvc-arguments").value = config["linter"]["nvc"]["arguments"]; + } if (config["linter"] && config["linter"]["icarus"] && config["linter"]["icarus"]["arguments"] !== undefined) { document.getElementById("linter-icarus-arguments").value = config["linter"]["icarus"]["arguments"]; } @@ -8072,6 +8109,11 @@ body.vscode-high-contrast { } document.getElementById("mark_linter-ghdl-arguments").innerHTML = mark; mark = ""; + if (projectName !== undefined && config["linter"] && config["linter"]["nvc"] && config["linter"]["nvc"]["arguments"] !== undefined) { + mark = MODIFIEDMSG; + } + document.getElementById("mark_linter-nvc-arguments").innerHTML = mark; + mark = ""; if (projectName !== undefined && config["linter"] && config["linter"]["icarus"] && config["linter"]["icarus"]["arguments"] !== undefined) { mark = MODIFIEDMSG; } diff --git a/src/colibri/config/web_config.html b/src/colibri/config/web_config.html index ccc64948..3b93b70c 100644 --- a/src/colibri/config/web_config.html +++ b/src/colibri/config/web_config.html @@ -739,6 +739,9 @@
GHDL linter
+
+ NVC linter +
Icarus linter
@@ -1558,6 +1561,7 @@ +
+ + +
@@ -5908,6 +5929,9 @@ config["linter"]["ghdl"] = {} element_value = document.getElementById("linter-ghdl-arguments").value; config["linter"]["ghdl"]["arguments"] = element_value + config["linter"]["nvc"] = {} + element_value = document.getElementById("linter-nvc-arguments").value; + config["linter"]["nvc"]["arguments"] = element_value config["linter"]["icarus"] = {} element_value = document.getElementById("linter-icarus-arguments").value; config["linter"]["icarus"]["arguments"] = element_value @@ -6910,6 +6934,9 @@ if (config["linter"] && config["linter"]["ghdl"] && config["linter"]["ghdl"]["arguments"] !== undefined) { document.getElementById("linter-ghdl-arguments").value = config["linter"]["ghdl"]["arguments"]; } + if (config["linter"] && config["linter"]["nvc"] && config["linter"]["nvc"]["arguments"] !== undefined) { + document.getElementById("linter-nvc-arguments").value = config["linter"]["nvc"]["arguments"]; + } if (config["linter"] && config["linter"]["icarus"] && config["linter"]["icarus"]["arguments"] !== undefined) { document.getElementById("linter-icarus-arguments").value = config["linter"]["icarus"]["arguments"]; } @@ -8051,6 +8078,11 @@ } document.getElementById("mark_linter-ghdl-arguments").innerHTML = mark; mark = ""; + if (projectName !== undefined && config["linter"] && config["linter"]["nvc"] && config["linter"]["nvc"]["arguments"] !== undefined) { + mark = MODIFIEDMSG; + } + document.getElementById("mark_linter-nvc-arguments").innerHTML = mark; + mark = ""; if (projectName !== undefined && config["linter"] && config["linter"]["icarus"] && config["linter"]["icarus"]["arguments"] !== undefined) { mark = MODIFIEDMSG; } diff --git a/src/colibri/linter/base_linter.ts b/src/colibri/linter/base_linter.ts index d21d96ed..ea579048 100644 --- a/src/colibri/linter/base_linter.ts +++ b/src/colibri/linter/base_linter.ts @@ -17,7 +17,7 @@ // You should have received a copy of the GNU General Public License // along with TerosHDL. If not, see . -import { create_temp_file } from "../process/utils"; +import { create_temp_file, create_temp_file_with_extension } from "../process/utils"; import { Process } from "../process/process"; import { p_options } from "../process/common"; import * as common from "./common"; @@ -50,8 +50,10 @@ export abstract class Base_linter { return errors; } - async lint_from_code(code: string, options: common.l_options) { - const temp_file = await create_temp_file(code); + async lint_from_code(code: string, options: common.l_options, source_file_path = "") { + const temp_file = source_file_path !== "" + ? await create_temp_file_with_extension(code, path_lib.extname(source_file_path)) + : await create_temp_file(code); const errors = await this.lint(temp_file, options); remove_file(temp_file); return errors; diff --git a/src/colibri/linter/linter.ts b/src/colibri/linter/linter.ts index 2fa589a3..89b396a2 100644 --- a/src/colibri/linter/linter.ts +++ b/src/colibri/linter/linter.ts @@ -28,6 +28,7 @@ import * as common from "./common"; import * as cfg from "../config/config_declaration"; import { t_file } from "../project_manager/common"; import { BinaryCheck } from "colibri/toolChecker/utils"; +import { Nvc } from "./nvc"; /** Linter */ export class Linter { @@ -61,6 +62,9 @@ export class Linter { else if (linter_name === cfg.e_linter_general_lstyle_vhdl.vsg) { return new Vsg(); } + else if (linter_name === cfg.e_linter_general_linter_vhdl.nvc) { + return new Nvc(); + } else { return new Ghdl(); } @@ -93,9 +97,10 @@ export class Linter { * @param {string} code Code to lint * @param {common.l_options} options Linter options */ - async lint_from_code(linter_name: common.t_linter_name, code: string, options: common.l_options) { + async lint_from_code(linter_name: common.t_linter_name, code: string, options: common.l_options, + source_file_path = "") { const linter = this.get_linter(linter_name); - const errors = await linter.lint_from_code(code, options); + const errors = await linter.lint_from_code(code, options, source_file_path); return errors; } diff --git a/src/colibri/linter/nvc.ts b/src/colibri/linter/nvc.ts new file mode 100644 index 00000000..f8c4f629 --- /dev/null +++ b/src/colibri/linter/nvc.ts @@ -0,0 +1,130 @@ +// NVC linter integration for TerosHDL. +// Minimum configuration for users: +// - Install NVC externally (NVC --version should work in terminal) +// - Select NVC as the VHDL linter with linter.general.linter_vhdl = "nvc" +// - If nvc is already available in the system PATH, tools.nvc.installation_path can stay empty +// - If nvc is not in PATH, tools.nvc.installation_path must point to the folder that contains +// - Additional lint-only arguments can be set in linter.nvc.arguments +// - Base NVC options such as VHDL standard, work library and syntax-check flags are taken from tools.nvc + + +import { Base_linter } from "./base_linter"; +import * as common from "./common"; + +export class Nvc extends Base_linter { + binary = "nvc"; + extra_cmd = ""; + argumentToCheck = ["--version"]; + + constructor() { + super(); + } + + delete_previus_lint() { + return true; + } + + async lint(file: string, options: common.l_options): Promise { + const result = await this.exec_linter(file, options); + return this.parse_output(result.stderr, file); + } + + get_command(file: string, options: common.l_options) { + const norm_bin = this.getToolPath(options.path); + const args = [options.argument.trim(), '-a', `"${file}"`].filter((arg) => arg !== ''); + return `${norm_bin} ${args.join(' ')}`; + } + + parse_output(output: string, file: string): common.l_error[] { + try { + const errors: common.l_error[] = []; + file = file.replace(/\\ /g, ' '); + const errors_str = output; + + // NVC diagnostic format, for example: + // ** Error: no visible declaration for STD_LOGICA + // > c:\path\file.vhd:11 + // | + // 11 | signal test : std_logica; + // | ^^^^^^^^^^ did you mean STD_LOGIC? + const nvcRegex = new RegExp( + [ + '^\\*\\*\\s+(?Error|Warning):\\s+(?.*?)\\r?\\n', + '\\s*>\\s*(?.*?):(?\\d+)\\r?\\n', + '(?:\\s*\\|\\r?\\n)?', + '(?:\\s*\\d+\\s*\\|(?.*?)\\r?\\n)?', + '(?:\\s*\\|(?.*?)(?:\\r?\\n|$))?' + ].join(''), + 'gm' + ); + let match; + while ((match = nvcRegex.exec(errors_str)) !== null) { + if (match.index === nvcRegex.lastIndex) { + nvcRegex.lastIndex++; + } + + const line = parseInt(match.groups?.line_number.trim()); + const caretLine = match.groups?.caret_line ?? ''; + const caretIndex = caretLine.indexOf('^'); + const column = caretIndex >= 0 ? caretIndex : 0; + const severity = match.groups?.severity === 'Warning' + ? common.LINTER_ERROR_SEVERITY.WARNING + : common.LINTER_ERROR_SEVERITY.ERROR; + + errors.push({ + severity: severity, + description: match.groups?.error_message.trim(), + code: '', + location: { + file: (match.groups?.filename ?? file).trim(), + position: [line - 1, column] + } + }); + } + + // Fallback for one-line formats with explicit line and column. + const fallbackRegex = new RegExp( + [ + '^(?.*):(?=\\d)(?\\d+):(?\\d+):', + '\\s*(?:(?warning:)\\s*)?(?.*)' + ].join(''), + 'gm' + ); + let fallbackMatch; + while ((fallbackMatch = fallbackRegex.exec(errors_str)) !== null) { + if (fallbackMatch.index === fallbackRegex.lastIndex) { + fallbackRegex.lastIndex++; + } + + const line = parseInt(fallbackMatch.groups?.line_number.trim()); + const column = parseInt(fallbackMatch.groups?.column_number.trim()); + const severity = fallbackMatch.groups?.is_warning !== undefined + ? common.LINTER_ERROR_SEVERITY.WARNING + : common.LINTER_ERROR_SEVERITY.ERROR; + + const duplicated = errors.some((error) => { + return error.location.file === (fallbackMatch.groups?.filename ?? file).trim() + && error.location.position[0] === line - 1 + && error.location.position[1] === column - 1 + && error.description === fallbackMatch.groups?.error_message.trim(); + }); + + if (!duplicated) { + errors.push({ + severity: severity, + description: fallbackMatch.groups?.error_message.trim(), + code: '', + location: { + file: (fallbackMatch.groups?.filename ?? file).trim(), + position: [line - 1, column - 1] + } + }); + } + } + + return errors; + } catch (error) { + return []; + } + } +} diff --git a/src/colibri/process/utils.ts b/src/colibri/process/utils.ts index a8dcb98b..439f1d63 100644 --- a/src/colibri/process/utils.ts +++ b/src/colibri/process/utils.ts @@ -112,6 +112,17 @@ export function create_temp_file(content: string): string { return temp_file.path; } +export function create_temp_file_with_extension(content: string, extension: string): string { + const normalizedExtension = extension.startsWith('.') ? extension : `.${extension}`; + const temp_file = temp.openSync({ suffix: normalizedExtension }); + if (temp_file === undefined) { + throw "Unable to create temporary file"; + } + fs.writeSync(temp_file.fd, content); + fs.closeSync(temp_file.fd); + return temp_file.path; +} + export function getTempFolder(): string { return os_lib.tmpdir(); } diff --git a/src/colibri/project_manager/export_t.ts b/src/colibri/project_manager/export_t.ts index 180348b4..dd1ab0a5 100644 --- a/src/colibri/project_manager/export_t.ts +++ b/src/colibri/project_manager/export_t.ts @@ -27,4 +27,4 @@ export * as quartusProjectManager from './tool/quartus/quartusProjectManager'; export * as sandpiperProjectManager from './tool/sandpiper/sandpiperProjectManager'; export * as quartusCommon from './tool/quartus/common'; export * as quartus from './tool/quartus/utils'; -export * as sandpiper from './tool/sandpiper/utils' \ No newline at end of file +export * as sandpiper from './tool/sandpiper/utils'; \ No newline at end of file diff --git a/src/colibri/project_manager/project_manager.ts b/src/colibri/project_manager/project_manager.ts index d200d158..772c2181 100644 --- a/src/colibri/project_manager/project_manager.ts +++ b/src/colibri/project_manager/project_manager.ts @@ -64,6 +64,7 @@ import { get } from "lodash"; import { getTaskList } from "./tool/utils"; import { runTaskGHDL } from "./tool/ghdl/taskRunners"; import { runTaskYosys } from "./tool/yosys/taskRunners"; +import { runTasknvc } from "./tool/nvc/taskRunners"; import { LoggerBase } from "colibri/logger/logger"; export const DEFAULT_LIBRARY = "teroshdlDefault"; @@ -729,6 +730,17 @@ export class Project_manager extends ConfigManager { this.emitUpdateStatus(); callback(result); }); + } else if (toolName === e_tools_general_select_tool.osvvm) { + const startTime = Date.now(); + const resultProcess = runTasknvc(taskType, this.get_project_definition(), (result: p_result) => { + const taskStatus = result.successful ? e_taskState.FINISHED : e_taskState.FAILED; + const endTime = Date.now(); + const elapsedTime = endTime - startTime; // ms + this.taskStateManager.updateTask(taskType, taskStatus, undefined, result.successful, elapsedTime); + this.emitUpdateStatus(); + callback(result); + }); + return resultProcess; } return {} as ChildProcess; } diff --git a/src/colibri/project_manager/tool/common.ts b/src/colibri/project_manager/tool/common.ts index 344d6c32..91c1f690 100644 --- a/src/colibri/project_manager/tool/common.ts +++ b/src/colibri/project_manager/tool/common.ts @@ -66,6 +66,14 @@ export enum e_taskType { SETTINGS = "Settings", CHANGEDEVICE = "Device", TCLCONSOLE = "Tcl Console", + // NVC + NVC_ANALYZE = "NVC Analyze", + NVC_ELABORATE = "NVC Elaborate", + NVC_SIMULATE = "NVC Simulate", + NVC_RUN_ALL = "NVC Run All", + NVC_SYNTHESIZE = "NVC Synthesize", + NVC_CHECK_SYNTAX = "NVC Check Syntax", + NVC_MAKEFILE = "NVC Generate Makefile", } export enum e_iconType { diff --git a/src/colibri/project_manager/tool/nvc/commandBuilder.ts b/src/colibri/project_manager/tool/nvc/commandBuilder.ts new file mode 100644 index 00000000..97312179 --- /dev/null +++ b/src/colibri/project_manager/tool/nvc/commandBuilder.ts @@ -0,0 +1,288 @@ +import { e_tools_nvc } from 'colibri/config/config_declaration'; + +/** + * Command argument building utilities for nvc + */ + +export type nvcCommandType = 'analyze' | 'elaborate' | 'run' | 'synth'; + +export interface nvcCommandArgs { + baseArgs: string[]; //antes de la entidad + runArgs: string[]; //despues de la entidad para simulacion +} + +/** + * Helper function to build nvc command arguments from configuration + * @param config nvc configuration + * @param commandType Type of command (analyze, elaborate, run, synth) + * @param additionalArgs Additional arguments specific to the command + * @returns Object with baseArgs (before entity) and runArgs (after entity for simulation) + */ + +export function buildnvcArgs( + config: e_tools_nvc, + commandType: nvcCommandType, + additionalArgs: string[] = [] +): nvcCommandArgs { + const baseArgs: string[] = []; + const runArgs: string[] = []; + + // Add verbose flag if enabled + if (config.verbose) { + baseArgs.push('-v'); + } + + // Add VHDL standard (map enum values to nvc standard values) + const standardMap: Record = { + 'vhdl87': '87', + 'vhdl93': '93', + 'vhdl02': '02', + 'vhdl08': '2008', + 'vhdl19': '2019' + }; + //Modificacion para usar el mapeo y agregar un valor por defecto si no se reconoce el estándar configurado + baseArgs.push(`--std=${config.vhdl_standard && standardMap[config.vhdl_standard] + ? standardMap[config.vhdl_standard] + : '2008'}`); // Default + + // Library / work directory + if (config.work_library && config.work_library.trim() !== '') { + baseArgs.push(`--work=${config.work_library}`); + } + + // Debug flags + if (config.debug_level) { + switch (config.debug_level) { + case 'minimal': baseArgs.push('-g'); break; + case 'full': baseArgs.push('-g', '--debug'); break; + } + } + + // Add IEEE library configuration + if (config.ieee_library !== 'standard') { + baseArgs.push(`--ieee=${config.ieee_library}`); + } + + // Add library paths + if (config.library_paths && config.library_paths.length > 0) { + config.library_paths.forEach((path: string) => { + baseArgs.push(`-P${path}`); + }); + } + + // Add assertion level + if (config.assert_level && config.assert_level !== 'error') { + if (config.assert_level === 'none') { + baseArgs.push('--assert-level=none'); + } else { + baseArgs.push(`--assert-level=${config.assert_level}`); + } + } + + // Add relaxed rules if enabled + if (config.relaxed_rules) { + baseArgs.push('--mb-comments'); + } + + // Add relaxed parsing if enabled + if (config.relaxed_parsing) { + baseArgs.push('--relaxed'); + } + + // Add PSL support if enabled + if (config.psl_enabled) { + baseArgs.push('--psl'); + } + + // Add Unicode support if enabled + if (config.unicode_support) { + baseArgs.push('--unicode'); + } + + // Add binding checks + if (!config.bind_checks) { + baseArgs.push('--no-bind-checks'); + } + + // Add VITAL checks if enabled + if (config.vital_checks) { + baseArgs.push('--vital-checks'); + } + + const warningFlags: string[] = []; + if (config.warnings_as_errors) {warningFlags.push('-Werror');} + if (config.suppress_warnings?.length) { + config.suppress_warnings.forEach(w => warningFlags.push(`-Wno-${w}`)); + } + + // Time resolution + if (config.resolution_limit?.trim() !== '') {baseArgs.push(`--time-resolution=${config.resolution_limit}`);} + + // Command-specific options + switch (commandType) { + case 'analyze': + // Solo opciones válidas para -a + baseArgs.push(...config.analyze_options); + break; + + case 'elaborate': + baseArgs.push(...config.elaborate_options); + // Flags de warnings aquí, no en analyze + baseArgs.push(...warningFlags); + break; + + case 'run': + // Añadir flags de ejecución/simulación + addSimulationArgs(config, runArgs); + runArgs.push(...config.run_options); + runArgs.push(...warningFlags); + break; + + case 'synth': + baseArgs.push(...config.synthesis_options); + break; + } + + // Extra flags generales + if (config.extra_flags?.length) {baseArgs.push(...config.extra_flags);} + + // Additional custom arguments + baseArgs.push(...additionalArgs); + + return { baseArgs, runArgs }; +} + + +/** + * Add simulation-specific arguments that go after the entity name + * @param config nvc configuration + * @param runArgs Array to append simulation arguments to + */ +function addSimulationArgs(config: e_tools_nvc, runArgs: string[]): void { + // Add waveform output configuration + // NVC uses --wave=FILE, format is inferred from the file extension (.vcd, .fst, .ghw) + if (config.waveform_enabled && config.waveform_format) { + const waveformFile = `wave.${config.waveform_format}`; + runArgs.push(`--wave=${waveformFile}`); + } + + // Add waveform-specific options + if (config.waveform_options && config.waveform_options.length > 0) { + runArgs.push(...config.waveform_options); + } + + // Add simulation time limit if specified + if (config.simulation_time && config.simulation_time.trim() !== '') { + runArgs.push(`--stop-time=${config.simulation_time}`); + } + + // Add stack size for simulation + if (config.stack_size && config.stack_size.trim() !== '') { + runArgs.push(`--stack-size=${config.stack_size}`); + } + + // Add stop delta cycles for simulation + if (config.stop_delta_cycles > 0) { + runArgs.push(`--stop-delta=${config.stop_delta_cycles}`); + } + + // Add display time option + if (config.display_time) { + runArgs.push('--disp-time'); + } + + // Add unbuffered output option + if (config.unbuffered_output) { + runArgs.push('--unbuffered'); + } + + // Add max stack allocation size + if (config.max_stack_alloc > 0) { + runArgs.push(`--max-stack-alloc=${config.max_stack_alloc}`); + } + + // Add backtrace severity level + if (config.backtrace_severity && config.backtrace_severity !== 'error') { + if (config.backtrace_severity === 'none') { + runArgs.push('--backtrace-severity=none'); + } else { + runArgs.push(`--backtrace-severity=${config.backtrace_severity}`); + } + } + + // Add IEEE assertions policy + if (config.ieee_asserts && config.ieee_asserts !== 'enable') { + runArgs.push(`--ieee-asserts=${config.ieee_asserts}`); + } + + // Add general assertions policy + if (config.asserts_policy && config.asserts_policy !== 'enable') { + runArgs.push(`--asserts=${config.asserts_policy}`); + } + + // Add SDF file for timing annotation + if (config.sdf_file && config.sdf_file.trim() !== '') { + runArgs.push(`--sdf=${config.sdf_file}`); + } + + // Add VPI modules + if (config.vpi_modules && config.vpi_modules.length > 0) { + config.vpi_modules.forEach((module: string) => { + runArgs.push(`--vpi=${module}`); + }); + } + + // Add VHPI modules + if (config.vhpi_modules && config.vhpi_modules.length > 0) { + config.vhpi_modules.forEach((module: string) => { + runArgs.push(`--vhpi=${module}`); + }); + } + + // Add VPI trace file + if (config.vpi_trace_file && config.vpi_trace_file.trim() !== '') { + runArgs.push(`--vpi-trace=${config.vpi_trace_file}`); + } + + // Add VHPI trace file + if (config.vhpi_trace_file && config.vhpi_trace_file.trim() !== '') { + runArgs.push(`--vhpi-trace=${config.vhpi_trace_file}`); + } + + // Add PSL report file + if (config.psl_report_file && config.psl_report_file.trim() !== '') { + runArgs.push(`--psl-report=${config.psl_report_file}`); + } + + // Add PSL uncovered reports + if (config.psl_report_uncovered) { + runArgs.push('--psl-report-uncovered'); + } + + // Add design hierarchy display + if (config.disp_tree && config.disp_tree !== 'none') { + runArgs.push(`--disp-tree=${config.disp_tree}`); + } + + // Add waveform generation advanced options + if (config.wave_start_time && config.wave_start_time.trim() !== '') { + runArgs.push(`--wave-start-time=${config.wave_start_time}`); + } + if (config.vcd_4states && config.waveform_format === 'vcd') { + runArgs.push('--vcd-4states'); + } + if (config.vcd_nodate && config.waveform_format === 'vcd') { + runArgs.push('--vcd-nodate'); + } + if (config.read_wave_opt && config.read_wave_opt.trim() !== '') { + runArgs.push(`--read-wave-opt=${config.read_wave_opt}`); + } + if (config.write_wave_opt && config.write_wave_opt.trim() !== '') { + runArgs.push(`--write-wave-opt=${config.write_wave_opt}`); + } + + // Add execution control options + if (config.no_run) { + runArgs.push('--no-run'); + } +} diff --git a/src/colibri/project_manager/tool/nvc/executor.ts b/src/colibri/project_manager/tool/nvc/executor.ts new file mode 100644 index 00000000..a712399e --- /dev/null +++ b/src/colibri/project_manager/tool/nvc/executor.ts @@ -0,0 +1,107 @@ +import { p_result } from 'colibri/process/common'; +import { ChildProcess } from 'child_process'; +import { e_tools_nvc } from 'colibri/config/config_declaration'; +import { Process } from 'colibri/process/process'; +import * as path from 'path'; +import * as file_utils from 'colibri/utils/file_utils'; + +/** + * Get NVC binary path from project configuration + * Uses installation_path if configured, otherwise falls back to system path + * @param config NVC configuration from project + * @returns NVC binary path + */ +export function getBinary(config: e_tools_nvc): string { + if (config.installation_path && config.installation_path.trim() !== '') { + const nvcPath = path.join(config.installation_path, 'nvc'); + const nvcExePath = path.join(config.installation_path, 'nvc.exe'); + if (file_utils.check_if_path_exist(nvcExePath)) { + return nvcExePath; + } + if (file_utils.check_if_path_exist(nvcPath)) { + return nvcPath; + } + } + // Fall back to system path + return 'nvc'; +} + +/** + * Helper function to properly quote arguments that contain spaces + * @param args Command arguments array + * @returns Array of quoted arguments + */ +export function quoteArgs(args: string[]): string[] { + return args.map((arg) => { + if (arg.includes(' ')) { + return `"${arg}"`; + } + return arg; + }); +} + +/** + * Helper function to execute a NVC command using Process class + * @param config NVC configuration + * @param args Command arguments array + * @param cwd Working directory + * @param callback Callback function to handle the result + * @returns ChildProcess instance + */ +export function executenvcCommand( + config: e_tools_nvc, + args: string[], + cwd: string, + callback: (result: p_result) => void +): ChildProcess { + // Properly quote arguments that contain spaces + const quotedArgs = quoteArgs(args); + const nvcExecutable = getBinary(config); + const command = `${nvcExecutable} ${quotedArgs.join(' ')}`; //Construccion del comando completo a ejecutar + const process = new Process(); + const options = { + cwd: cwd + }; + + return process.exec(command, options, callback); +} + +/** + * Helper function to execute a command using Process class (fallback for complex commands) + * @param command Command to execute + * @param cwd Working directory + * @param callback Callback function to handle the result + * @returns ChildProcess instance + */ +export function executeCommand(command: string, cwd: string, callback: (result: p_result) => void): ChildProcess { + const process = new Process(); + const options = { + cwd: cwd + }; + + return process.exec(command, options, callback); + +} + +/** + * Build a chained command string from multiple nvc commands + * @param config nvc configuration + * @param commandSpecs Array of command specifications + * @returns Complete command string + */ +export function buildChainedCommand( + config: e_tools_nvc, + commandSpecs: Array<{ command: string; args: string[] }> +): string { + const nvcExecutable = getBinary(config); + + const commands = commandSpecs.map((spec) => { + const commandParts = spec.command.trim() === '' ? spec.args : [spec.command, ...spec.args]; + const quotedArgs = quoteArgs(commandParts); + return `${nvcExecutable} ${quotedArgs.join(' ')}`; + }); + + return commands.join(' && '); +} + +export const executeGhdlCommand = executenvcCommand; diff --git a/src/colibri/project_manager/tool/nvc/taskRunners.ts b/src/colibri/project_manager/tool/nvc/taskRunners.ts new file mode 100644 index 00000000..a3cf50aa --- /dev/null +++ b/src/colibri/project_manager/tool/nvc/taskRunners.ts @@ -0,0 +1,74 @@ +import { p_result } from 'colibri/process/common'; +import { e_taskType } from '../common'; +import { ChildProcess } from 'child_process'; +import { t_project_definition } from 'colibri/project_manager/project_definition'; +import { + runnvcAnalyze, + runnvcElaborate, + runnvcSimulate, + runnvcAll, + runnvcSynthesize, + runnvcCheckSyntax, + runnvcMakefile +} from './tasks'; +import * as file_utils from 'colibri/utils/file_utils'; + +/** + * Main entry point for nvc task execution + */ + +/** + * Main function to run nvc tasks based on task type + * @param taskType Type of nvc task to execute + * @param projectDefinition Project definition containing files and configuration + * @param callback Callback function to handle the result + * @returns ChildProcess instance + */ +export function runTasknvc( + taskType: e_taskType, + projectDefinition: t_project_definition, + callback: (result: p_result) => void +): ChildProcess { + if (!file_utils.check_if_path_exist(projectDefinition.project_disk_path)) { + file_utils.create_directory(projectDefinition.project_disk_path); + } + + switch (taskType) { + case e_taskType.NVC_ANALYZE: + return runnvcAnalyze(projectDefinition, callback); + + case e_taskType.NVC_ELABORATE: + return runnvcElaborate(projectDefinition, callback); + + case e_taskType.NVC_SIMULATE: + return runnvcSimulate(projectDefinition, callback); + + case e_taskType.NVC_RUN_ALL: + return runnvcAll(projectDefinition, callback); + + case e_taskType.NVC_SYNTHESIZE: + return runnvcSynthesize(projectDefinition, callback); + + case e_taskType.NVC_CHECK_SYNTAX: + return runnvcCheckSyntax(projectDefinition, callback); + + case e_taskType.NVC_MAKEFILE: + return runnvcMakefile(projectDefinition, callback); + + default: + const result: p_result = { + command: '', + stdout: '', + stderr: `Unsupported nvc task type: ${taskType}`, + return_value: 1, + successful: false + }; + setTimeout(() => callback(result), 0); + return {} as ChildProcess; + } +} + +// Re-export utilities for external use if needed +export { buildnvcArgs, nvcCommandType, nvcCommandArgs } from './commandBuilder'; +export { getBinary, executenvcCommand, executeCommand } from './executor'; +export { getTopLevel, getVhdlFiles, groupFilesByLibrary } from './utils'; diff --git a/src/colibri/project_manager/tool/nvc/tasks.ts b/src/colibri/project_manager/tool/nvc/tasks.ts new file mode 100644 index 00000000..7383e93e --- /dev/null +++ b/src/colibri/project_manager/tool/nvc/tasks.ts @@ -0,0 +1,319 @@ +import { p_result } from 'colibri/process/common'; +import { ChildProcess } from 'child_process'; +import { t_project_definition } from 'colibri/project_manager/project_definition'; +import { buildnvcArgs } from './commandBuilder'; +import { executenvcCommand, executeCommand, buildChainedCommand, getBinary, quoteArgs } from './executor'; +import { getTopLevel, getVhdlFiles, groupFilesByLibrary, getRelativeFilePath } from './utils'; +import * as fs from 'fs'; +import * as path from 'path'; + +/** + * Individual nvc task implementations + */ + +/** + * Create a standard error result for common error conditions + * @param command Command name for the result + * @param errorMessage Error message + * @returns Error result object + */ +function createErrorResult(command: string, errorMessage: string): p_result { + return { + command: command, + stdout: '', + stderr: errorMessage, + return_value: 1, + successful: false + }; +} + +/** + * Executes nvc analyze task for VHDL files + * @param projectDefinition Project definition containing files and configuration + * @param callback Callback function to handle the result + * @returns ChildProcess instance + */ +export function runnvcAnalyze( + projectDefinition: t_project_definition, + callback: (result: p_result) => void +): ChildProcess { + const vhdlFiles = getVhdlFiles(projectDefinition); + const config = projectDefinition.config.tools.nvc; + + if (vhdlFiles.length === 0) { + const result = createErrorResult('nvc analyze', 'No VHDL files found in project'); + setTimeout(() => callback(result), 0); + return {} as ChildProcess; + } + + // Group files by logical library + const libraryGroups = groupFilesByLibrary(projectDefinition, config); + + // Build command chain for each library + const commandSpecs: Array<{ command: string; args: string[] }> = []; + + for (const [library, filePaths] of libraryGroups) { + // Build base arguments from configuration + const { baseArgs } = buildnvcArgs(config, 'analyze'); + // Global flags (--std, --work) must come before the command (-a) per NVC spec. + const analyzeBaseArgs = baseArgs.filter((arg) => !arg.startsWith('--work=')); + const args = [...analyzeBaseArgs, `--work=${library}`, '-a', ...filePaths]; + commandSpecs.push({ command: '', args }); + }; + + // Execute all library commands in sequence + const command = buildChainedCommand(config, commandSpecs); + return executeCommand(command, projectDefinition.project_disk_path, callback); +} + +/** + * Executes nvc elaborate task for the top level entity + * @param projectDefinition Project definition containing top level configuration + * @param callback Callback function to handle the result + * @returns ChildProcess instance + */ +export function runnvcElaborate( + projectDefinition: t_project_definition, + callback: (result: p_result) => void +): ChildProcess { + const topLevel = getTopLevel(projectDefinition); + const config = projectDefinition.config.tools.nvc; + + if (topLevel === null) { + const result = createErrorResult('nvc elaborate', 'No top level entity specified'); + setTimeout(() => callback(result), 0); + return {} as ChildProcess; + } + + // Build arguments from configuration + const { baseArgs } = buildnvcArgs(config, 'elaborate'); + const args = [...baseArgs, '-e', topLevel]; + + return executenvcCommand(config, args, projectDefinition.project_disk_path, callback); +} + +/** + * Executes nvc simulate task for the top level entity + * @param projectDefinition Project definition containing top level configuration + * @param callback Callback function to handle the result + * @returns ChildProcess instance + */ +export function runnvcSimulate( + projectDefinition: t_project_definition, + callback: (result: p_result) => void +): ChildProcess { + const topLevel = getTopLevel(projectDefinition); + const config = projectDefinition.config.tools.nvc; + + if (topLevel === null) { + const result = createErrorResult('nvc simulate', 'No top level entity specified'); + setTimeout(() => callback(result), 0); + return {} as ChildProcess; + } + + // Clean up existing waveform files before simulation + cleanupWaveformFiles(projectDefinition.project_disk_path); + + // Build arguments from configuration + const { baseArgs, runArgs } = buildnvcArgs(config, 'run'); + const args = [...baseArgs, '-r', topLevel, ...runArgs]; + + return executenvcCommand(config, args, projectDefinition.project_disk_path, callback); +} + +/** + * Executes nvc synthesis task for the top level entity + * @param projectDefinition Project definition containing top level configuration + * @param callback Callback function to handle the result + * @returns ChildProcess instance + */ +export function runnvcSynthesize( + projectDefinition: t_project_definition, + callback: (result: p_result) => void +): ChildProcess { + const topLevel = getTopLevel(projectDefinition); + const config = projectDefinition.config.tools.nvc; + + if (topLevel === null) { + const result = createErrorResult('nvc synthesize', 'No top level entity specified'); + setTimeout(() => callback(result), 0); + return {} as ChildProcess; + } + + // Build arguments from configuration + const { baseArgs } = buildnvcArgs(config, 'synth'); + const args = ['--synth', ...baseArgs, topLevel]; + + return executenvcCommand(config, args, projectDefinition.project_disk_path, callback); +} + +/** + * Executes nvc check syntax task for VHDL files + * This task analyzes files without saving compiled units, providing a fast syntax/type check + * @param projectDefinition Project definition containing files and configuration + * @param callback Callback function to handle the result + * @returns ChildProcess instance + */ +export function runnvcCheckSyntax( + projectDefinition: t_project_definition, + callback: (result: p_result) => void +): ChildProcess { + const vhdlFiles = getVhdlFiles(projectDefinition); + const config = projectDefinition.config.tools.nvc; + + if (vhdlFiles.length === 0) { + const result = createErrorResult('nvc check syntax', 'No VHDL files found in project'); + setTimeout(() => callback(result), 0); + return {} as ChildProcess; + } + + // Build arguments for syntax check using documented analysis flow. + // --no-save avoids persisting analyzed units while still reporting syntax/type errors. + const { baseArgs } = buildnvcArgs(config, 'analyze'); + const syntaxBaseArgs = baseArgs.filter((arg) => !arg.startsWith('--work=')); + + // Group files by logical library for proper syntax checking + const libraryGroups = groupFilesByLibrary(projectDefinition, config); + + // Build command specs for each library + const commandSpecs: Array<{ command: string; args: string[] }> = []; + + for (const [library, files] of libraryGroups) { + // Global flags (--std, --work) go before -a per NVC spec. + const fullArgs = [ + ...syntaxBaseArgs, + `--work=${library}`, + '-a', + '--no-save', + ...config.check_syntax_options, + ...files + ]; + commandSpecs.push({ command: '', args: fullArgs }); + } + + // Build complete command chain for syntax checking + const command = buildChainedCommand(config, commandSpecs); + + return executeCommand(command, projectDefinition.project_disk_path, callback); +} + +/** + * Generates Makefile for the nvc project + * @param projectDefinition Project definition containing files and configuration + * @param callback Callback function to handle the result + * @returns ChildProcess instance + */ +export function runnvcMakefile( + projectDefinition: t_project_definition, + callback: (result: p_result) => void +): ChildProcess { + const topLevel = getTopLevel(projectDefinition); + const config = projectDefinition.config.tools.nvc; + + if (topLevel === null) { + const result = createErrorResult('nvc makefile', 'No top level entity specified'); + setTimeout(() => callback(result), 0); + return {} as ChildProcess; + } + + // Build arguments from configuration + const { baseArgs } = buildnvcArgs(config, 'elaborate'); + const args = ['--gen-makefile', ...baseArgs, topLevel]; + + return executenvcCommand(config, args, projectDefinition.project_disk_path, callback); +} + +/** + * Executes complete nvc flow: analyze, elaborate, and simulate + * @param projectDefinition Project definition containing files and configuration + * @param callback Callback function to handle the result + * @returns ChildProcess instance + */ +export function runnvcAll( + projectDefinition: t_project_definition, + callback: (result: p_result) => void +): ChildProcess { + const vhdlFiles = getVhdlFiles(projectDefinition); + const topLevel = getTopLevel(projectDefinition); + const config = projectDefinition.config.tools.nvc; + + if (vhdlFiles.length === 0) { + const result = createErrorResult('nvc run all', 'No VHDL files found in project'); + setTimeout(() => callback(result), 0); + return {} as ChildProcess; + } + + if (topLevel === null) { + const result = createErrorResult('nvc run all', 'No top level entity specified'); + setTimeout(() => callback(result), 0); + return {} as ChildProcess; + } + + // Group files by logical library + const libraryGroups = groupFilesByLibrary(projectDefinition, config); + + // Build analyze commands for each library + const analyzeCommandSpecs: Array<{ command: string; args: string[] }> = []; + + for (const [library, filePaths] of libraryGroups) { + const { baseArgs } = buildnvcArgs(config, 'analyze'); + // Global flags (--std, --work) must come before the command (-a) per NVC spec. + const analyzeBaseArgs = baseArgs.filter((arg) => !arg.startsWith('--work=')); + const args = [...analyzeBaseArgs, `--work=${library}`, '-a', ...filePaths]; + analyzeCommandSpecs.push({ command: '', args }); + } + + // Build elaborate command + const { baseArgs: elaborateBaseArgs } = buildnvcArgs(config, 'elaborate'); + const elaborateArgs = [...elaborateBaseArgs, '-e', topLevel]; + + // Build simulate command + const { baseArgs: runBaseArgs, runArgs: simRunArgs } = buildnvcArgs(config, 'run'); + const simulateArgs = [...runBaseArgs, '-r', topLevel, ...simRunArgs]; + + // Clean up existing waveform files before simulation + cleanupWaveformFiles(projectDefinition.project_disk_path); + + // Build complete command chain using buildChainedCommand for analyze commands + const nvcExecutable = getBinary(config); + + const analyzeCommand = buildChainedCommand(config, analyzeCommandSpecs); + const elaborateCmd = `${nvcExecutable} ${quoteArgs(elaborateArgs).join(' ')}`; + const simulateCmd = `${nvcExecutable} ${quoteArgs(simulateArgs).join(' ')}`; + + // Build complete command chain: analyze all libraries + elaborate + simulate + const command = `${analyzeCommand} && ${elaborateCmd} && ${simulateCmd}`; + + return executeCommand(command, projectDefinition.project_disk_path, callback); +} + +/** + * Remove existing waveform files with basename "wave" before simulation + * @param workingDirectory Directory where to look for waveform files + */ +function cleanupWaveformFiles(workingDirectory: string): void { + try { + if (!fs.existsSync(workingDirectory)) { + return; + } + + const files = fs.readdirSync(workingDirectory); + const waveBasename = "wave"; + + for (const file of files) { + // Check if file starts with "wave" basename (wave.ghw, wave.vcd, etc.) + const fileBasename = path.basename(file, path.extname(file)); + if (fileBasename === waveBasename) { + const filePath = path.join(workingDirectory, file); + try { + fs.unlinkSync(filePath); + // File removed successfully + } catch (error) { + // Failed to remove file, continue with others + } + } + } + } catch (error) { + // Failed to cleanup waveform files, continue execution + } +} diff --git a/src/colibri/project_manager/tool/nvc/utils.ts b/src/colibri/project_manager/tool/nvc/utils.ts new file mode 100644 index 00000000..a9e0dcc4 --- /dev/null +++ b/src/colibri/project_manager/tool/nvc/utils.ts @@ -0,0 +1,78 @@ +import { t_project_definition } from 'colibri/project_manager/project_definition'; +import { LANGUAGE } from 'colibri/common/general'; +import { get_toplevel_from_path } from 'colibri/utils/hdl_utils'; +import { e_tools_nvc } from 'colibri/config/config_declaration'; +import * as path from 'path'; + +/** + * Utility functions for nvc project management + */ + +export interface FileLibraryGroup { + library: string; + files: string[]; +} + +/** + * Helper function to get the top level entity name from project definition + * @param projectDefinition Project definition containing top level configuration + * @returns Top level entity name or null if not found + */ +export function getTopLevel(projectDefinition: t_project_definition): string | null { + const topLevels = projectDefinition.toplevel_path_manager.get(); + + if (topLevels.length === 0) { + return null; + } + + const entity_name = get_toplevel_from_path(topLevels[0]); + return entity_name ? entity_name : null; +} + +/** + * Get VHDL files from project definition + * @param projectDefinition Project definition containing files + * @returns Array of VHDL files + */ +export function getVhdlFiles(projectDefinition: t_project_definition): Array<{ name: string; logical_name?: string }> { + const files = projectDefinition.file_manager.get(); + return files.filter((file) => file.file_type === LANGUAGE.VHDL); +} + +/** + * Group VHDL files by logical library + * @param projectDefinition Project definition containing files + * @param config nvc configuration + * @returns Map of library names to file arrays + */ +export function groupFilesByLibrary( + projectDefinition: t_project_definition, + config: e_tools_nvc +): Map { + const vhdlFiles = getVhdlFiles(projectDefinition); + const libraryGroups = new Map(); + + vhdlFiles.forEach((file) => { + const library = file.logical_name || config.work_library || 'work'; + const relativePath = path.relative(projectDefinition.project_disk_path, file.name); + const filePath = relativePath.startsWith('..') ? file.name : relativePath; + + if (!libraryGroups.has(library)) { + libraryGroups.set(library, []); + } + libraryGroups.get(library)!.push(filePath); + }); + + return libraryGroups; +} + +/** + * Get the relative file path for a file from project root + * @param projectDefinition Project definition + * @param fileName Full path to the file + * @returns Relative path from project root + */ +export function getRelativeFilePath(projectDefinition: t_project_definition, fileName: string): string { + const relativePath = path.relative(projectDefinition.project_disk_path, fileName); + return relativePath.startsWith('..') ? fileName : relativePath; +} diff --git a/src/colibri/project_manager/tool/quartus/quartusProjectManager.ts b/src/colibri/project_manager/tool/quartus/quartusProjectManager.ts index 4d12c48f..e66fd0ce 100644 --- a/src/colibri/project_manager/tool/quartus/quartusProjectManager.ts +++ b/src/colibri/project_manager/tool/quartus/quartusProjectManager.ts @@ -426,6 +426,13 @@ export class QuartusProjectManager extends Project_manager { [e_taskType.YOSYS_SYNTHESIS]: "", [e_taskType.YOSYS_SHOW]: "", [e_taskType.YOSYS_RESOURCE_UTILIZATION]: "", + [e_taskType.NVC_ANALYZE]: "", + [e_taskType.NVC_ELABORATE]: "", + [e_taskType.NVC_SIMULATE]: "", + [e_taskType.NVC_RUN_ALL]: "", + [e_taskType.NVC_SYNTHESIZE]: "", + [e_taskType.NVC_CHECK_SYNTAX]: "", + [e_taskType.NVC_MAKEFILE]: "", }; let reportKeys = Object.keys(reportSufix); if (reportType === e_reportType.REPORT && reportKeys.includes(taskType)) { diff --git a/src/colibri/project_manager/tool/quartus/taskRunner.ts b/src/colibri/project_manager/tool/quartus/taskRunner.ts index 66cdb1b2..dae558ac 100644 --- a/src/colibri/project_manager/tool/quartus/taskRunner.ts +++ b/src/colibri/project_manager/tool/quartus/taskRunner.ts @@ -135,7 +135,14 @@ const taskDependencies: Record = { [e_taskType.YOSYS_ELABORATE]: [], [e_taskType.YOSYS_SYNTHESIS]: [], [e_taskType.YOSYS_SHOW]: [], - [e_taskType.YOSYS_RESOURCE_UTILIZATION]: [] + [e_taskType.YOSYS_RESOURCE_UTILIZATION]: [], + [e_taskType.NVC_ANALYZE]: [], + [e_taskType.NVC_ELABORATE]: [], + [e_taskType.NVC_SIMULATE]: [], + [e_taskType.NVC_RUN_ALL]: [], + [e_taskType.NVC_SYNTHESIZE]: [], + [e_taskType.NVC_CHECK_SYNTAX]: [], + [e_taskType.NVC_MAKEFILE]: [] }; function executeCommandList(projectName: string, commands: string[], cwd: string, emitter: ProjectEmitter, @@ -235,7 +242,14 @@ export function runTask(taskType: e_taskType, taskManager: TaskStateManager, qua [e_taskType.YOSYS_ELABORATE]: "", [e_taskType.YOSYS_SYNTHESIS]: "", [e_taskType.YOSYS_SHOW]: "", - [e_taskType.YOSYS_RESOURCE_UTILIZATION]: "" + [e_taskType.YOSYS_RESOURCE_UTILIZATION]: "", + [e_taskType.NVC_ANALYZE]: "", + [e_taskType.NVC_ELABORATE]: "", + [e_taskType.NVC_SIMULATE]: "", + [e_taskType.NVC_RUN_ALL]: "", + [e_taskType.NVC_SYNTHESIZE]: "", + [e_taskType.NVC_CHECK_SYNTAX]: "", + [e_taskType.NVC_MAKEFILE]: "" }; const cmdList: string[] = []; diff --git a/src/colibri/project_manager/tool/utils.ts b/src/colibri/project_manager/tool/utils.ts index 38609de7..255f4d22 100644 --- a/src/colibri/project_manager/tool/utils.ts +++ b/src/colibri/project_manager/tool/utils.ts @@ -99,6 +99,46 @@ export function getTaskList(toolName: e_tools_general_select_tool): t_taskRep[] ] } ]; + } else if (toolName === e_tools_general_select_tool.osvvm) { + return [ + { + name: e_taskType.OPENFOLDER, + label: 'Open Project Folder', + executionType: e_taskExecutionType.OPENFOLDER + }, + { + name: e_taskType.OPEN_WAVEFORM, + label: 'Open Waveform', + executionType: e_taskExecutionType.SIMPLECOMMAND, + icon: e_iconType.WAVEFORM + }, + { + name: e_taskType.NVC_RUN_ALL, + label: 'NVC Run All', + executionType: e_taskExecutionType.COMPLEXCOMMAND, + status: e_taskState.IDLE, + children: [ + { + name: e_taskType.NVC_ANALYZE, + label: 'NVC Analyze', + executionType: e_taskExecutionType.COMPLEXCOMMAND, + status: e_taskState.IDLE + }, + { + name: e_taskType.NVC_ELABORATE, + label: 'NVC Elaborate', + executionType: e_taskExecutionType.COMPLEXCOMMAND, + status: e_taskState.IDLE + }, + { + name: e_taskType.NVC_SIMULATE, + label: 'NVC Simulate', + executionType: e_taskExecutionType.COMPLEXCOMMAND, + status: e_taskState.IDLE + } + ] + } + ]; } return []; } diff --git a/src/colibri/project_manager/utils/utils.ts b/src/colibri/project_manager/utils/utils.ts index 9d9ad700..ac49935d 100644 --- a/src/colibri/project_manager/utils/utils.ts +++ b/src/colibri/project_manager/utils/utils.ts @@ -81,7 +81,7 @@ export function get_edam_json(prj: t_project_definition, top_level_list: undefin } return file.file_type.toString(); - } + }; const edam_file: t_edam_file = { name: file.name, @@ -92,7 +92,7 @@ export function get_edam_json(prj: t_project_definition, top_level_list: undefin }; return edam_file; - }) + }); const edam_json = { name: prj.name, diff --git a/src/colibri/yosys/yosys.ts b/src/colibri/yosys/yosys.ts index 727a5576..09d85310 100644 --- a/src/colibri/yosys/yosys.ts +++ b/src/colibri/yosys/yosys.ts @@ -187,7 +187,7 @@ async function getGHDLCommnand(preArgument: string, yosysPath: string) : Promise const endOfScriptStdout = result.stdout.toLowerCase().includes("end of script"); const runningStdout = result.stdout.toLowerCase().includes("running command"); - console.log(result.stdout); + //console.log(result.stdout); if (result.successful && (endOfScriptStdout || runningStdout)) { return "-m ghdl"; @@ -252,7 +252,7 @@ export async function runYosysStandalone(config: e_config, topTevel: string, sou callback(schematicResult); } catch (error) { - console.log(error); + //console.log(error); const schematicResult = { schematic: "", error_msg: "Error running Yosys", diff --git a/src/teroshdl/extension.ts b/src/teroshdl/extension.ts index b017d82e..5dca1937 100644 --- a/src/teroshdl/extension.ts +++ b/src/teroshdl/extension.ts @@ -47,7 +47,7 @@ export async function activate(context: vscode.ExtensionContext) { await releaseNotesView.show(); } } catch (e) { - console.log(e); + debugLogger.error(e); } teroshdl = new Teroshdl(context); diff --git a/src/teroshdl/features/configChecker/externalTools.ts b/src/teroshdl/features/configChecker/externalTools.ts index d2f75c12..2b41e2ff 100644 --- a/src/teroshdl/features/configChecker/externalTools.ts +++ b/src/teroshdl/features/configChecker/externalTools.ts @@ -24,6 +24,8 @@ import { } from 'colibri/config/config_declaration'; import { appendMsg, buildTitle, INTROICON, replaceByResult } from './utils'; import { checkBinary } from 'colibri/toolChecker/utils'; +import * as fs from 'fs'; +import * as path_lib from 'path'; const HELP = 'https://terostechnology.github.io/terosHDLdoc/docs/external_tools/'; @@ -49,18 +51,48 @@ export async function checkExternalToolManager(currentConfig: e_config) { // Check external tool msg += `${INTROICON} Selected external tool: ${selectedTool.toLocaleUpperCase()}. Installation path: "${installationPath}"\n`; - // Default to '--version' if no custom argument is specified - const versionArgument = customVersionArgs[selectedTool] || '--version'; + let result: any; - let binaryName : string | string[] = - selectedTool === e_tools_general_select_tool.rivierapro ? ['rivierapro', 'riviera'] : selectedTool; - binaryName = binaryName === e_tools_general_select_tool.icarus ? 'iverilog' : binaryName; + if (selectedTool === e_tools_general_select_tool.osvvm) { + const osvv_pro_path = path_lib.join(installationPath, 'OsvvmLibraries.pro'); + const scripts_path = path_lib.join(installationPath, 'Scripts'); + const start_nvc_tcl = path_lib.join(scripts_path, 'StartNVC.tcl'); + const tclsh = currentConfig.tools.osvvm.tclsh_binary || 'tclsh'; - let result = await checkBinary(selectedTool, installationPath, binaryName, [versionArgument]); - msg = appendMsg(result, msg, selectedTool.toLocaleUpperCase()); - msg += '\n'; - if (!result.successfulConfig) { - isOk = false; + if (!fs.existsSync(osvv_pro_path)) { + msg += `${INTROICON} ❌ OSVVM installation path invalid: cannot find OsvvmLibraries.pro at "${osvv_pro_path}"\n`; + msg += `${INTROICON} Please set the path to the OSVVM root containing OsvvmLibraries.pro and Scripts/.\n`; + isOk = false; + } else if (!fs.existsSync(scripts_path)) { + msg += `${INTROICON} ❌ OSVVM installation path invalid: cannot find Scripts folder at "${scripts_path}"\n`; + msg += `${INTROICON} Please set the path to the OSVVM root containing OsvvmLibraries.pro and Scripts/.\n`; + isOk = false; + } else if (!fs.existsSync(start_nvc_tcl)) { + msg += `${INTROICON} ❌ OSVVM installation path invalid: cannot find StartNVC.tcl at "${start_nvc_tcl}"\n`; + msg += `${INTROICON} Please set simulator_name to nvc and ensure the OSVVM Scripts folder is present.\n`; + isOk = false; + } else { + msg += `${INTROICON} ✅ OSVVM installation path looks valid. Found OsvvmLibraries.pro and Scripts/StartNVC.tcl\n`; + const tcl_result = await checkBinary('tclsh', '', tclsh, ['--version']); + msg = appendMsg(tcl_result, msg, 'Tclsh'); + if (!tcl_result.successfulConfig) { + isOk = false; + } + } + } else { + // Default to '--version' if no custom argument is specified + const versionArgument = customVersionArgs[selectedTool] || '--version'; + + let binaryName : string | string[] = + selectedTool === e_tools_general_select_tool.rivierapro ? ['rivierapro', 'riviera'] : selectedTool; + binaryName = binaryName === e_tools_general_select_tool.icarus ? 'iverilog' : binaryName; + + let result = await checkBinary(selectedTool, installationPath, binaryName, [versionArgument]); + msg = appendMsg(result, msg, selectedTool.toLocaleUpperCase()); + msg += '\n'; + if (!result.successfulConfig) { + isOk = false; + } } // Check execution mode diff --git a/src/teroshdl/features/language_provider/lsp/verible.ts b/src/teroshdl/features/language_provider/lsp/verible.ts index c7037075..d486388e 100644 --- a/src/teroshdl/features/language_provider/lsp/verible.ts +++ b/src/teroshdl/features/language_provider/lsp/verible.ts @@ -106,11 +106,12 @@ export class Verilbe_lsp { console.log(`[colibri][info] Linting with command: ${command}`); const exec = require('child_process').exec; return new Promise((resolve) => { - exec(command, (err, stdout: string, stderr) => { + exec(command, (err, stdout: string, stderr: string) => { if (stderr !== '') { - console.log(`[verible][error] ${stderr}`); + console.log(`[verible][info] ${stderr}`); } - if (err !== null || !stdout.toLowerCase().includes('version')) { + const combined = (stdout + stderr).toLowerCase(); + if (err !== null || !combined.includes('version')) { resolve(false); } else { resolve(true); diff --git a/src/teroshdl/features/linter.ts b/src/teroshdl/features/linter.ts index 2c7f3763..16b6d1ec 100644 --- a/src/teroshdl/features/linter.ts +++ b/src/teroshdl/features/linter.ts @@ -23,8 +23,14 @@ import * as utils from './utils/utils'; import { LANGUAGE } from '../../colibri/common/general'; import * as linterManager from '../../colibri/linter/linter'; import { l_options, LINTER_ERROR_SEVERITY } from '../../colibri/linter/common'; -import { e_linter_general_linter_verilog, e_linter_general_linter_vhdl, e_linter_general_lstyle_verilog, e_linter_general_lstyle_vhdl } from '../../colibri/config/config_declaration'; +import { + e_linter_general_linter_verilog, + e_linter_general_linter_vhdl, + e_linter_general_lstyle_verilog, + e_linter_general_lstyle_vhdl +} from '../../colibri/config/config_declaration'; import { get_language_from_extension } from '../../colibri/utils/file_utils'; +import { buildnvcArgs } from '../../colibri/project_manager/tool/nvc/commandBuilder'; enum LINTER_MODE { STYLE = "style", @@ -34,6 +40,8 @@ enum LINTER_MODE { class Linter { protected diagnostic_collection = vscode.languages.createDiagnosticCollection(); private uri_collections: vscode.Uri[] = []; + private linter_availability_cache = new Map(); + private notified_unavailable_linter = new Set(); public mode: LINTER_MODE; private manager: Multi_project_manager; @@ -49,6 +57,64 @@ class Linter { this.lang = lang; } + private build_nvc_lint_arguments(config: ReturnType): string { + const { baseArgs } = buildnvcArgs(config.tools.nvc, 'analyze'); + const syntaxBaseArgs = baseArgs.filter((arg) => !arg.startsWith('--work=')); + const customArguments = config.linter.nvc.arguments.trim(); + return [...syntaxBaseArgs, ...config.tools.nvc.check_syntax_options, customArguments] + .filter((arg) => arg !== '') + .join(' '); + } + + private get_linter_cache_key(language: LANGUAGE): string { + const linter_name = this.get_linter_name(); + const options = this.get_options(language); + return `${linter_name}|${options.path}`; + } + + private show_linter_unavailable_message(linter_name: string, installation_path: string) { + if (linter_name === e_linter_general_linter_vhdl.nvc) { + const configuredPath = installation_path === '' ? 'PATH del sistema' : installation_path; + const message = 'TerosHDL no puede encontrar NVC. ' + + 'Configura tools.nvc.installation_path ' + + `o asegúrate de que nvc esté disponible en el ${configuredPath}.`; + vscode.window.showWarningMessage( + message + ); + return; + } + + vscode.window.showWarningMessage( + `TerosHDL no puede encontrar el linter ${linter_name}. Revisa su installation_path o el PATH del sistema.` + ); + } + + private async ensure_linter_available(language: LANGUAGE): Promise { + const linter_name = this.get_linter_name(); + const options = this.get_options(language); + const cacheKey = this.get_linter_cache_key(language); + + const cachedAvailability = this.linter_availability_cache.get(cacheKey); + if (cachedAvailability !== undefined) { + return cachedAvailability; + } + + const result = await this.linter.checkLinterConfiguration(linter_name, options.path); + this.linter_availability_cache.set(cacheKey, result.successfulConfig); + + if (result.successfulConfig === false && this.notified_unavailable_linter.has(cacheKey) === false) { + this.notified_unavailable_linter.add(cacheKey); + this.show_linter_unavailable_message(linter_name, options.path); + } + + return result.successfulConfig; + } + + public clear_linter_availability_cache() { + this.linter_availability_cache.clear(); + this.notified_unavailable_linter.clear(); + } + //////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Configuration //////////////////////////////////////////////////////////////////////////////////////////////////////////////////// @@ -116,6 +182,10 @@ class Linter { path = config.tools.verible.installation_path; argument = config.linter.verible.arguments; } + else if (linter_name === e_linter_general_linter_vhdl.nvc){ + path = config.tools.nvc.installation_path; + argument = this.build_nvc_lint_arguments(config); + } const options: l_options = { path: path, @@ -133,7 +203,7 @@ class Linter { this.lint_from_uri(this.uri_collections[i]); } } - catch (e) { console.log(e); } + catch (e) { /* empty */ } } public check_lang(document_lang:LANGUAGE) :boolean{ @@ -147,7 +217,7 @@ class Linter { return false; } - public async lint(doc: vscode.TextDocument) { + public async lint(doc: vscode.TextDocument, use_document_text = false) { const linter_name = this.get_linter_name(); if (linter_name === 'none' || linter_name === 'disabled') { @@ -161,14 +231,19 @@ class Linter { if (this.check_lang(lang) === false) { return; } + if (await this.ensure_linter_available(lang) === false) { + this.diagnostic_collection.set(doc.uri, []); + return; + } let current_path = doc.uri.fsPath; //Save the uri linted this.add_uri_to_collections(doc.uri); - console.log(`[terosHDL] Linting ${current_path}`); - - let errors = await this.linter.lint_from_file(linter_name, current_path, this.get_options(lang),); + const options = this.get_options(lang); + const errors = use_document_text || doc.isDirty + ? await this.linter.lint_from_code(linter_name, doc.getText(), options, current_path) + : await this.linter.lint_from_file(linter_name, current_path, options); let diagnostics: vscode.Diagnostic[] = []; for (var i = 0; i < errors.length; ++i) { @@ -197,6 +272,10 @@ class Linter { const linter_name = this.get_linter_name(); const lang = get_language_from_extension(current_path); + if (await this.ensure_linter_available(lang) === false) { + this.diagnostic_collection.set(uri, []); + return; + } let errors = await this.linter.lint_from_file(linter_name, current_path, this.get_options(lang)); let diagnostics: vscode.Diagnostic[] = []; @@ -279,6 +358,7 @@ class Linter { export class Linter_manager { protected manager: Multi_project_manager; private linter_list: Linter[] = []; + private lint_timeout_by_uri = new Map(); public vhdlErrorLinter: Linter; public verilogErrorLinter: Linter; public vhdlStyleLinter: Linter; @@ -292,9 +372,13 @@ export class Linter_manager { this.manager = manager; vscode.commands.registerCommand(`teroshdl.linter.refresh`, () => this.refresh_lint()); - vscode.commands.registerCommand(`teroshdl.config.change_config`, () => this.refresh_lint()); + vscode.commands.registerCommand(`teroshdl.config.change_config`, () => { + this.clear_linter_availability_cache(); + this.refresh_lint(); + }); vscode.workspace.onDidOpenTextDocument((e) => this.lint(e)); + vscode.workspace.onDidChangeTextDocument((e) => this.schedule_lint(e)); vscode.workspace.onDidSaveTextDocument((e) => this.lint(e)); vscode.workspace.onDidCloseTextDocument((e) => this.remove_file_diagnostics(e)); @@ -333,12 +417,39 @@ export class Linter_manager { }); } + private schedule_lint(event: vscode.TextDocumentChangeEvent) { + if (event.contentChanges.length === 0) { + return; + } + + const uri = event.document.uri.toString(); + const currentTimeout = this.lint_timeout_by_uri.get(uri); + if (currentTimeout !== undefined) { + clearTimeout(currentTimeout); + } + + const timeout = setTimeout(() => { + this.lint_timeout_by_uri.delete(uri); + this.linter_list.forEach(linter => { + linter.lint(event.document, true); + }); + }, 250); + + this.lint_timeout_by_uri.set(uri, timeout); + } + async refresh_lint() { this.linter_list.forEach(linter => { linter.refresh_lint(); }); } + private clear_linter_availability_cache() { + this.linter_list.forEach(linter => { + linter.clear_linter_availability_cache(); + }); + } + lint_active_document() { let open_files = vscode.workspace.textDocuments; diff --git a/tests/linter_nvc/nvc.spec.ts b/tests/linter_nvc/nvc.spec.ts new file mode 100644 index 00000000..786f1cb6 --- /dev/null +++ b/tests/linter_nvc/nvc.spec.ts @@ -0,0 +1,69 @@ +import { Nvc } from '../../src/colibri/linter/nvc'; +import { LINTER_ERROR_SEVERITY } from '../../src/colibri/linter/common'; + +describe('NVC parser', () => { + it('parses multiline diagnostics with caret column', () => { + const parser = new Nvc(); + const output = [ + '** Error: no visible declaration for STD_LOGICA', + ' > c:\\test_04022026\\test_test.vhd:11', + ' |', + ' 11 | signal test : std_logica;', + ' | ^^^^^^^^^^ did you mean STD_LOGIC?' + ].join('\n'); + + const result = parser.parse_output(output, 'c:\\test_04022026\\test_test.vhd'); + + expect(result).toHaveLength(1); + expect(result[0]).toEqual({ + severity: LINTER_ERROR_SEVERITY.ERROR, + description: 'no visible declaration for STD_LOGICA', + code: '', + location: { + file: 'c:\\test_04022026\\test_test.vhd', + position: [10, 16] + } + }); + }); + + it('parses multiline warnings without caret as column zero', () => { + const parser = new Nvc(); + const output = [ + '** Warning: declaration of FOO hides previous declaration', + ' > c:\\test_04022026\\test_test.vhd:7', + ' |', + ' 7 | signal foo : std_logic;' + ].join('\n'); + + const result = parser.parse_output(output, 'c:\\test_04022026\\test_test.vhd'); + + expect(result).toHaveLength(1); + expect(result[0]).toEqual({ + severity: LINTER_ERROR_SEVERITY.WARNING, + description: 'declaration of FOO hides previous declaration', + code: '', + location: { + file: 'c:\\test_04022026\\test_test.vhd', + position: [6, 0] + } + }); + }); + + it('parses one-line fallback diagnostics with explicit column', () => { + const parser = new Nvc(); + const output = 'c:\\test_04022026\\test_test.vhd:13:7: warning: identifier expected'; + + const result = parser.parse_output(output, 'c:\\test_04022026\\test_test.vhd'); + + expect(result).toHaveLength(1); + expect(result[0]).toEqual({ + severity: LINTER_ERROR_SEVERITY.WARNING, + description: 'identifier expected', + code: '', + location: { + file: 'c:\\test_04022026\\test_test.vhd', + position: [12, 6] + } + }); + }); +}); \ No newline at end of file diff --git a/tests/tsconfig.json b/tests/tsconfig.json index 03aa48fb..519580b0 100644 --- a/tests/tsconfig.json +++ b/tests/tsconfig.json @@ -2,7 +2,8 @@ "extends": "../tsconfig.json", "compilerOptions": { "types": ["node", "jest"], - "noEmit": true + "noEmit": true, + "rootDir": ".." }, "include": ["./**/*.ts"] } diff --git a/tests/yosys/yosys.spec.ts b/tests/yosys/yosys.spec.ts index 1eb1178e..a2694dc4 100644 --- a/tests/yosys/yosys.spec.ts +++ b/tests/yosys/yosys.spec.ts @@ -21,15 +21,11 @@ import * as path_lib from 'path'; import { e_source_type, t_file } from "../../src/colibri/project_manager/common"; import { LANGUAGE, VERILOG_LANG_VERSION, VHDL_LANG_VERSION } from '../../src/colibri/common/general'; import { e_schematic_general_backend, get_default_config } from "../../src/colibri/config/config_declaration"; -import { fileURLToPath } from 'url'; function getFileList(language: LANGUAGE) : t_file[]{ const langFolder = language === LANGUAGE.VHDL ? 'vhdl' : 'verilog'; const extension = language === LANGUAGE.VHDL ? '.vhd' : '.v'; - const __filename = fileURLToPath(import.meta.url); - const __dirname = path_lib.dirname(__filename); - const basePath = path_lib.join(__dirname, 'helpers', langFolder); const filePath0 = path_lib.join(basePath, 'mylib', `counter_logic${extension}`); const filePath1 = path_lib.join(basePath, `counter_top${extension}`); diff --git a/tsconfig.json b/tsconfig.json index 10f52d69..cdb9dace 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -11,6 +11,7 @@ "lib": ["ES2019"], "types": ["node"], "moduleResolution": "node", + "ignoreDeprecations": "6.0", "sourceMap": true, "rootDir": "./src", "strict": false, diff --git a/venv/Scripts/Activate.ps1 b/venv/Scripts/Activate.ps1 new file mode 100644 index 00000000..d7ed8946 --- /dev/null +++ b/venv/Scripts/Activate.ps1 @@ -0,0 +1,472 @@ +<# +.Synopsis +Activate a Python virtual environment for the current PowerShell session. + +.Description +Pushes the python executable for a virtual environment to the front of the +$Env:PATH environment variable and sets the prompt to signify that you are +in a Python virtual environment. Makes use of the command line switches as +well as the `pyvenv.cfg` file values present in the virtual environment. + +.Parameter VenvDir +Path to the directory that contains the virtual environment to activate. The +default value for this is the parent of the directory that the Activate.ps1 +script is located within. + +.Parameter Prompt +The prompt prefix to display when this virtual environment is activated. By +default, this prompt is the name of the virtual environment folder (VenvDir) +surrounded by parentheses and followed by a single space (ie. '(.venv) '). + +.Example +Activate.ps1 +Activates the Python virtual environment that contains the Activate.ps1 script. + +.Example +Activate.ps1 -Verbose +Activates the Python virtual environment that contains the Activate.ps1 script, +and shows extra information about the activation as it executes. + +.Example +Activate.ps1 -VenvDir C:\Users\MyUser\Common\.venv +Activates the Python virtual environment located in the specified location. + +.Example +Activate.ps1 -Prompt "MyPython" +Activates the Python virtual environment that contains the Activate.ps1 script, +and prefixes the current prompt with the specified string (surrounded in +parentheses) while the virtual environment is active. + +.Notes +On Windows, it may be required to enable this Activate.ps1 script by setting the +execution policy for the user. You can do this by issuing the following PowerShell +command: + +PS C:\> Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser + +For more information on Execution Policies: +https://go.microsoft.com/fwlink/?LinkID=135170 + +#> +Param( + [Parameter(Mandatory = $false)] + [String] + $VenvDir, + [Parameter(Mandatory = $false)] + [String] + $Prompt +) + +<# Function declarations --------------------------------------------------- #> + +<# +.Synopsis +Remove all shell session elements added by the Activate script, including the +addition of the virtual environment's Python executable from the beginning of +the PATH variable. + +.Parameter NonDestructive +If present, do not remove this function from the global namespace for the +session. + +#> +function global:deactivate ([switch]$NonDestructive) { + # Revert to original values + + # The prior prompt: + if (Test-Path -Path Function:_OLD_VIRTUAL_PROMPT) { + Copy-Item -Path Function:_OLD_VIRTUAL_PROMPT -Destination Function:prompt + Remove-Item -Path Function:_OLD_VIRTUAL_PROMPT + } + + # The prior PYTHONHOME: + if (Test-Path -Path Env:_OLD_VIRTUAL_PYTHONHOME) { + Copy-Item -Path Env:_OLD_VIRTUAL_PYTHONHOME -Destination Env:PYTHONHOME + Remove-Item -Path Env:_OLD_VIRTUAL_PYTHONHOME + } + + # The prior PATH: + if (Test-Path -Path Env:_OLD_VIRTUAL_PATH) { + Copy-Item -Path Env:_OLD_VIRTUAL_PATH -Destination Env:PATH + Remove-Item -Path Env:_OLD_VIRTUAL_PATH + } + + # Just remove the VIRTUAL_ENV altogether: + if (Test-Path -Path Env:VIRTUAL_ENV) { + Remove-Item -Path env:VIRTUAL_ENV + } + + # Just remove VIRTUAL_ENV_PROMPT altogether. + if (Test-Path -Path Env:VIRTUAL_ENV_PROMPT) { + Remove-Item -Path env:VIRTUAL_ENV_PROMPT + } + + # Just remove the _PYTHON_VENV_PROMPT_PREFIX altogether: + if (Get-Variable -Name "_PYTHON_VENV_PROMPT_PREFIX" -ErrorAction SilentlyContinue) { + Remove-Variable -Name _PYTHON_VENV_PROMPT_PREFIX -Scope Global -Force + } + + # Leave deactivate function in the global namespace if requested: + if (-not $NonDestructive) { + Remove-Item -Path function:deactivate + } +} + +<# +.Description +Get-PyVenvConfig parses the values from the pyvenv.cfg file located in the +given folder, and returns them in a map. + +For each line in the pyvenv.cfg file, if that line can be parsed into exactly +two strings separated by `=` (with any amount of whitespace surrounding the =) +then it is considered a `key = value` line. The left hand string is the key, +the right hand is the value. + +If the value starts with a `'` or a `"` then the first and last character is +stripped from the value before being captured. + +.Parameter ConfigDir +Path to the directory that contains the `pyvenv.cfg` file. +#> +function Get-PyVenvConfig( + [String] + $ConfigDir +) { + Write-Verbose "Given ConfigDir=$ConfigDir, obtain values in pyvenv.cfg" + + # Ensure the file exists, and issue a warning if it doesn't (but still allow the function to continue). + $pyvenvConfigPath = Join-Path -Resolve -Path $ConfigDir -ChildPath 'pyvenv.cfg' -ErrorAction Continue + + # An empty map will be returned if no config file is found. + $pyvenvConfig = @{ } + + if ($pyvenvConfigPath) { + + Write-Verbose "File exists, parse `key = value` lines" + $pyvenvConfigContent = Get-Content -Path $pyvenvConfigPath + + $pyvenvConfigContent | ForEach-Object { + $keyval = $PSItem -split "\s*=\s*", 2 + if ($keyval[0] -and $keyval[1]) { + $val = $keyval[1] + + # Remove extraneous quotations around a string value. + if ("'""".Contains($val.Substring(0, 1))) { + $val = $val.Substring(1, $val.Length - 2) + } + + $pyvenvConfig[$keyval[0]] = $val + Write-Verbose "Adding Key: '$($keyval[0])'='$val'" + } + } + } + return $pyvenvConfig +} + + +<# Begin Activate script --------------------------------------------------- #> + +# Determine the containing directory of this script +$VenvExecPath = Split-Path -Parent $MyInvocation.MyCommand.Definition +$VenvExecDir = Get-Item -Path $VenvExecPath + +Write-Verbose "Activation script is located in path: '$VenvExecPath'" +Write-Verbose "VenvExecDir Fullname: '$($VenvExecDir.FullName)" +Write-Verbose "VenvExecDir Name: '$($VenvExecDir.Name)" + +# Set values required in priority: CmdLine, ConfigFile, Default +# First, get the location of the virtual environment, it might not be +# VenvExecDir if specified on the command line. +if ($VenvDir) { + Write-Verbose "VenvDir given as parameter, using '$VenvDir' to determine values" +} +else { + Write-Verbose "VenvDir not given as a parameter, using parent directory name as VenvDir." + $VenvDir = $VenvExecDir.Parent.FullName.TrimEnd("\\/") + Write-Verbose "VenvDir=$VenvDir" +} + +# Next, read the `pyvenv.cfg` file to determine any required value such +# as `prompt`. +$pyvenvCfg = Get-PyVenvConfig -ConfigDir $VenvDir + +# Next, set the prompt from the command line, or the config file, or +# just use the name of the virtual environment folder. +if ($Prompt) { + Write-Verbose "Prompt specified as argument, using '$Prompt'" +} +else { + Write-Verbose "Prompt not specified as argument to script, checking pyvenv.cfg value" + if ($pyvenvCfg -and $pyvenvCfg['prompt']) { + Write-Verbose " Setting based on value in pyvenv.cfg='$($pyvenvCfg['prompt'])'" + $Prompt = $pyvenvCfg['prompt']; + } + else { + Write-Verbose " Setting prompt based on parent's directory's name. (Is the directory name passed to venv module when creating the virtual environment)" + Write-Verbose " Got leaf-name of $VenvDir='$(Split-Path -Path $venvDir -Leaf)'" + $Prompt = Split-Path -Path $venvDir -Leaf + } +} + +Write-Verbose "Prompt = '$Prompt'" +Write-Verbose "VenvDir='$VenvDir'" + +# Deactivate any currently active virtual environment, but leave the +# deactivate function in place. +deactivate -nondestructive + +# Now set the environment variable VIRTUAL_ENV, used by many tools to determine +# that there is an activated venv. +$env:VIRTUAL_ENV = $VenvDir + +if (-not $Env:VIRTUAL_ENV_DISABLE_PROMPT) { + + Write-Verbose "Setting prompt to '$Prompt'" + + # Set the prompt to include the env name + # Make sure _OLD_VIRTUAL_PROMPT is global + function global:_OLD_VIRTUAL_PROMPT { "" } + Copy-Item -Path function:prompt -Destination function:_OLD_VIRTUAL_PROMPT + New-Variable -Name _PYTHON_VENV_PROMPT_PREFIX -Description "Python virtual environment prompt prefix" -Scope Global -Option ReadOnly -Visibility Public -Value $Prompt + + function global:prompt { + Write-Host -NoNewline -ForegroundColor Green "($_PYTHON_VENV_PROMPT_PREFIX) " + _OLD_VIRTUAL_PROMPT + } + $env:VIRTUAL_ENV_PROMPT = $Prompt +} + +# Clear PYTHONHOME +if (Test-Path -Path Env:PYTHONHOME) { + Copy-Item -Path Env:PYTHONHOME -Destination Env:_OLD_VIRTUAL_PYTHONHOME + Remove-Item -Path Env:PYTHONHOME +} + +# Add the venv to the PATH +Copy-Item -Path Env:PATH -Destination Env:_OLD_VIRTUAL_PATH +$Env:PATH = "$VenvExecDir$([System.IO.Path]::PathSeparator)$Env:PATH" + +# SIG # Begin signature block +# MIIpiQYJKoZIhvcNAQcCoIIpejCCKXYCAQExDzANBglghkgBZQMEAgEFADB5Bgor +# BgEEAYI3AgEEoGswaTA0BgorBgEEAYI3AgEeMCYCAwEAAAQQH8w7YFlLCE63JNLG +# KX7zUQIBAAIBAAIBAAIBAAIBADAxMA0GCWCGSAFlAwQCAQUABCBnL745ElCYk8vk +# dBtMuQhLeWJ3ZGfzKW4DHCYzAn+QB6CCDi8wggawMIIEmKADAgECAhAIrUCyYNKc +# TJ9ezam9k67ZMA0GCSqGSIb3DQEBDAUAMGIxCzAJBgNVBAYTAlVTMRUwEwYDVQQK +# EwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5jb20xITAfBgNV +# BAMTGERpZ2lDZXJ0IFRydXN0ZWQgUm9vdCBHNDAeFw0yMTA0MjkwMDAwMDBaFw0z +# NjA0MjgyMzU5NTlaMGkxCzAJBgNVBAYTAlVTMRcwFQYDVQQKEw5EaWdpQ2VydCwg +# SW5jLjFBMD8GA1UEAxM4RGlnaUNlcnQgVHJ1c3RlZCBHNCBDb2RlIFNpZ25pbmcg +# UlNBNDA5NiBTSEEzODQgMjAyMSBDQTEwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAw +# ggIKAoICAQDVtC9C0CiteLdd1TlZG7GIQvUzjOs9gZdwxbvEhSYwn6SOaNhc9es0 +# JAfhS0/TeEP0F9ce2vnS1WcaUk8OoVf8iJnBkcyBAz5NcCRks43iCH00fUyAVxJr +# Q5qZ8sU7H/Lvy0daE6ZMswEgJfMQ04uy+wjwiuCdCcBlp/qYgEk1hz1RGeiQIXhF +# LqGfLOEYwhrMxe6TSXBCMo/7xuoc82VokaJNTIIRSFJo3hC9FFdd6BgTZcV/sk+F +# LEikVoQ11vkunKoAFdE3/hoGlMJ8yOobMubKwvSnowMOdKWvObarYBLj6Na59zHh +# 3K3kGKDYwSNHR7OhD26jq22YBoMbt2pnLdK9RBqSEIGPsDsJ18ebMlrC/2pgVItJ +# wZPt4bRc4G/rJvmM1bL5OBDm6s6R9b7T+2+TYTRcvJNFKIM2KmYoX7BzzosmJQay +# g9Rc9hUZTO1i4F4z8ujo7AqnsAMrkbI2eb73rQgedaZlzLvjSFDzd5Ea/ttQokbI +# YViY9XwCFjyDKK05huzUtw1T0PhH5nUwjewwk3YUpltLXXRhTT8SkXbev1jLchAp +# QfDVxW0mdmgRQRNYmtwmKwH0iU1Z23jPgUo+QEdfyYFQc4UQIyFZYIpkVMHMIRro +# OBl8ZhzNeDhFMJlP/2NPTLuqDQhTQXxYPUez+rbsjDIJAsxsPAxWEQIDAQABo4IB +# WTCCAVUwEgYDVR0TAQH/BAgwBgEB/wIBADAdBgNVHQ4EFgQUaDfg67Y7+F8Rhvv+ +# YXsIiGX0TkIwHwYDVR0jBBgwFoAU7NfjgtJxXWRM3y5nP+e6mK4cD08wDgYDVR0P +# AQH/BAQDAgGGMBMGA1UdJQQMMAoGCCsGAQUFBwMDMHcGCCsGAQUFBwEBBGswaTAk +# BggrBgEFBQcwAYYYaHR0cDovL29jc3AuZGlnaWNlcnQuY29tMEEGCCsGAQUFBzAC +# hjVodHRwOi8vY2FjZXJ0cy5kaWdpY2VydC5jb20vRGlnaUNlcnRUcnVzdGVkUm9v +# dEc0LmNydDBDBgNVHR8EPDA6MDigNqA0hjJodHRwOi8vY3JsMy5kaWdpY2VydC5j +# b20vRGlnaUNlcnRUcnVzdGVkUm9vdEc0LmNybDAcBgNVHSAEFTATMAcGBWeBDAED +# MAgGBmeBDAEEATANBgkqhkiG9w0BAQwFAAOCAgEAOiNEPY0Idu6PvDqZ01bgAhql +# +Eg08yy25nRm95RysQDKr2wwJxMSnpBEn0v9nqN8JtU3vDpdSG2V1T9J9Ce7FoFF +# UP2cvbaF4HZ+N3HLIvdaqpDP9ZNq4+sg0dVQeYiaiorBtr2hSBh+3NiAGhEZGM1h +# mYFW9snjdufE5BtfQ/g+lP92OT2e1JnPSt0o618moZVYSNUa/tcnP/2Q0XaG3Ryw +# YFzzDaju4ImhvTnhOE7abrs2nfvlIVNaw8rpavGiPttDuDPITzgUkpn13c5Ubdld +# AhQfQDN8A+KVssIhdXNSy0bYxDQcoqVLjc1vdjcshT8azibpGL6QB7BDf5WIIIJw +# 8MzK7/0pNVwfiThV9zeKiwmhywvpMRr/LhlcOXHhvpynCgbWJme3kuZOX956rEnP +# LqR0kq3bPKSchh/jwVYbKyP/j7XqiHtwa+aguv06P0WmxOgWkVKLQcBIhEuWTatE +# QOON8BUozu3xGFYHKi8QxAwIZDwzj64ojDzLj4gLDb879M4ee47vtevLt/B3E+bn +# KD+sEq6lLyJsQfmCXBVmzGwOysWGw/YmMwwHS6DTBwJqakAwSEs0qFEgu60bhQji +# WQ1tygVQK+pKHJ6l/aCnHwZ05/LWUpD9r4VIIflXO7ScA+2GRfS0YW6/aOImYIbq +# yK+p/pQd52MbOoZWeE4wggd3MIIFX6ADAgECAhAHHxQbizANJfMU6yMM0NHdMA0G +# CSqGSIb3DQEBCwUAMGkxCzAJBgNVBAYTAlVTMRcwFQYDVQQKEw5EaWdpQ2VydCwg +# SW5jLjFBMD8GA1UEAxM4RGlnaUNlcnQgVHJ1c3RlZCBHNCBDb2RlIFNpZ25pbmcg +# UlNBNDA5NiBTSEEzODQgMjAyMSBDQTEwHhcNMjIwMTE3MDAwMDAwWhcNMjUwMTE1 +# MjM1OTU5WjB8MQswCQYDVQQGEwJVUzEPMA0GA1UECBMGT3JlZ29uMRIwEAYDVQQH +# EwlCZWF2ZXJ0b24xIzAhBgNVBAoTGlB5dGhvbiBTb2Z0d2FyZSBGb3VuZGF0aW9u +# MSMwIQYDVQQDExpQeXRob24gU29mdHdhcmUgRm91bmRhdGlvbjCCAiIwDQYJKoZI +# hvcNAQEBBQADggIPADCCAgoCggIBAKgc0BTT+iKbtK6f2mr9pNMUTcAJxKdsuOiS +# YgDFfwhjQy89koM7uP+QV/gwx8MzEt3c9tLJvDccVWQ8H7mVsk/K+X+IufBLCgUi +# 0GGAZUegEAeRlSXxxhYScr818ma8EvGIZdiSOhqjYc4KnfgfIS4RLtZSrDFG2tN1 +# 6yS8skFa3IHyvWdbD9PvZ4iYNAS4pjYDRjT/9uzPZ4Pan+53xZIcDgjiTwOh8VGu +# ppxcia6a7xCyKoOAGjvCyQsj5223v1/Ig7Dp9mGI+nh1E3IwmyTIIuVHyK6Lqu35 +# 2diDY+iCMpk9ZanmSjmB+GMVs+H/gOiofjjtf6oz0ki3rb7sQ8fTnonIL9dyGTJ0 +# ZFYKeb6BLA66d2GALwxZhLe5WH4Np9HcyXHACkppsE6ynYjTOd7+jN1PRJahN1oE +# RzTzEiV6nCO1M3U1HbPTGyq52IMFSBM2/07WTJSbOeXjvYR7aUxK9/ZkJiacl2iZ +# I7IWe7JKhHohqKuceQNyOzxTakLcRkzynvIrk33R9YVqtB4L6wtFxhUjvDnQg16x +# ot2KVPdfyPAWd81wtZADmrUtsZ9qG79x1hBdyOl4vUtVPECuyhCxaw+faVjumapP +# Unwo8ygflJJ74J+BYxf6UuD7m8yzsfXWkdv52DjL74TxzuFTLHPyARWCSCAbzn3Z +# Ily+qIqDAgMBAAGjggIGMIICAjAfBgNVHSMEGDAWgBRoN+Drtjv4XxGG+/5hewiI +# ZfROQjAdBgNVHQ4EFgQUt/1Teh2XDuUj2WW3siYWJgkZHA8wDgYDVR0PAQH/BAQD +# AgeAMBMGA1UdJQQMMAoGCCsGAQUFBwMDMIG1BgNVHR8Ega0wgaowU6BRoE+GTWh0 +# dHA6Ly9jcmwzLmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydFRydXN0ZWRHNENvZGVTaWdu +# aW5nUlNBNDA5NlNIQTM4NDIwMjFDQTEuY3JsMFOgUaBPhk1odHRwOi8vY3JsNC5k +# aWdpY2VydC5jb20vRGlnaUNlcnRUcnVzdGVkRzRDb2RlU2lnbmluZ1JTQTQwOTZT +# SEEzODQyMDIxQ0ExLmNybDA+BgNVHSAENzA1MDMGBmeBDAEEATApMCcGCCsGAQUF +# BwIBFhtodHRwOi8vd3d3LmRpZ2ljZXJ0LmNvbS9DUFMwgZQGCCsGAQUFBwEBBIGH +# MIGEMCQGCCsGAQUFBzABhhhodHRwOi8vb2NzcC5kaWdpY2VydC5jb20wXAYIKwYB +# BQUHMAKGUGh0dHA6Ly9jYWNlcnRzLmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydFRydXN0 +# ZWRHNENvZGVTaWduaW5nUlNBNDA5NlNIQTM4NDIwMjFDQTEuY3J0MAwGA1UdEwEB +# /wQCMAAwDQYJKoZIhvcNAQELBQADggIBABxv4AeV/5ltkELHSC63fXAFYS5tadcW +# TiNc2rskrNLrfH1Ns0vgSZFoQxYBFKI159E8oQQ1SKbTEubZ/B9kmHPhprHya08+ +# VVzxC88pOEvz68nA82oEM09584aILqYmj8Pj7h/kmZNzuEL7WiwFa/U1hX+XiWfL +# IJQsAHBla0i7QRF2de8/VSF0XXFa2kBQ6aiTsiLyKPNbaNtbcucaUdn6vVUS5izW +# OXM95BSkFSKdE45Oq3FForNJXjBvSCpwcP36WklaHL+aHu1upIhCTUkzTHMh8b86 +# WmjRUqbrnvdyR2ydI5l1OqcMBjkpPpIV6wcc+KY/RH2xvVuuoHjlUjwq2bHiNoX+ +# W1scCpnA8YTs2d50jDHUgwUo+ciwpffH0Riq132NFmrH3r67VaN3TuBxjI8SIZM5 +# 8WEDkbeoriDk3hxU8ZWV7b8AW6oyVBGfM06UgkfMb58h+tJPrFx8VI/WLq1dTqMf +# ZOm5cuclMnUHs2uqrRNtnV8UfidPBL4ZHkTcClQbCoz0UbLhkiDvIS00Dn+BBcxw +# /TKqVL4Oaz3bkMSsM46LciTeucHY9ExRVt3zy7i149sd+F4QozPqn7FrSVHXmem3 +# r7bjyHTxOgqxRCVa18Vtx7P/8bYSBeS+WHCKcliFCecspusCDSlnRUjZwyPdP0VH +# xaZg2unjHY3rMYIasDCCGqwCAQEwfTBpMQswCQYDVQQGEwJVUzEXMBUGA1UEChMO +# RGlnaUNlcnQsIEluYy4xQTA/BgNVBAMTOERpZ2lDZXJ0IFRydXN0ZWQgRzQgQ29k +# ZSBTaWduaW5nIFJTQTQwOTYgU0hBMzg0IDIwMjEgQ0ExAhAHHxQbizANJfMU6yMM +# 0NHdMA0GCWCGSAFlAwQCAQUAoIHEMBkGCSqGSIb3DQEJAzEMBgorBgEEAYI3AgEE +# MBwGCisGAQQBgjcCAQsxDjAMBgorBgEEAYI3AgEVMC8GCSqGSIb3DQEJBDEiBCBn +# AZ6P7YvTwq0fbF62o7E75R0LxsW5OtyYiFESQckLhjBYBgorBgEEAYI3AgEMMUow +# SKBGgEQAQgB1AGkAbAB0ADoAIABSAGUAbABlAGEAcwBlAF8AdgAzAC4AMQAwAC4A +# OABfADIAMAAyADIAMQAwADEAMQAuADAAMTANBgkqhkiG9w0BAQEFAASCAgBvrB2R +# d/6IKRT9evXFap+DPx3SGj8fyHcvBdlvQ2lxX3+DQrZTmcmH7qH0SzAgYSjckeK1 +# JjyomHebFxthV+jZDJf2NVL3NSm1KwD6eUVYNYrjPMpJryqMX12JKLZzWWQAbNbk +# BQPqr5dsWQJB+D9DnAj6ahLJ/YdQQ/R9F5lH2XAmqQpON0/9g2qb2wPzUeHDBGgQ +# jBLhiswdvhyLvBSglbx7SfMyRQ8QWzBqSJe4RpxVH/Or5DQ9oarC3BQJfNJH8tuf +# wB3IZNmlNvoIPfZknHnxFhQm9uNbk4VS4jPc7YyBc06qpeTg3zk0ohb03DfB/Qw+ +# njwWEEVXIRM5helnhPcbGHJLLk1NHjy8UmsSCCeqrMs6PASvIGK7y97x4s0b12HP +# GvRaLLK1KSytFK0zWHnqqN/bu1QNzhwxf2SQ1akLVRDgJWMD5AboyBPiYNn32hTD +# lLNoG6KlYBKFtL4eEvHONTPb1uMQFerIj9DgpwJ6OLDyBC6VCOGlrJp0ZQNKAhMy +# vjxOGQpxaL9CiYNXkQlG/PNxF54ex1+2fqjalrNhLRyh9DWe5MmISsYwPjLJAWWN +# axtPHt/v0lUyIoIpJijbrDEO5w0/AEF2EZ26kWxZnIrkD/bo5kVhC3c6EeLvODVY +# 38U153hZPcjJfhZYEFPCHeumsqOxV6aElXjEnaGCFz0wghc5BgorBgEEAYI3AwMB +# MYIXKTCCFyUGCSqGSIb3DQEHAqCCFxYwghcSAgEDMQ8wDQYJYIZIAWUDBAIBBQAw +# dwYLKoZIhvcNAQkQAQSgaARmMGQCAQEGCWCGSAGG/WwHATAxMA0GCWCGSAFlAwQC +# AQUABCCJNX6iKhZvpzctf3+4+Ju6k4+1R6+i/GOszaNWLkM2wgIQSm7Y+oQkne0J +# RSIXmPMifRgPMjAyMjEwMTExNjU1MjlaoIITBzCCBsAwggSooAMCAQICEAxNaXJL +# lPo8Kko9KQeAPVowDQYJKoZIhvcNAQELBQAwYzELMAkGA1UEBhMCVVMxFzAVBgNV +# BAoTDkRpZ2lDZXJ0LCBJbmMuMTswOQYDVQQDEzJEaWdpQ2VydCBUcnVzdGVkIEc0 +# IFJTQTQwOTYgU0hBMjU2IFRpbWVTdGFtcGluZyBDQTAeFw0yMjA5MjEwMDAwMDBa +# Fw0zMzExMjEyMzU5NTlaMEYxCzAJBgNVBAYTAlVTMREwDwYDVQQKEwhEaWdpQ2Vy +# dDEkMCIGA1UEAxMbRGlnaUNlcnQgVGltZXN0YW1wIDIwMjIgLSAyMIICIjANBgkq +# hkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAz+ylJjrGqfJru43BDZrboegUhXQzGias +# 0BxVHh42bbySVQxh9J0Jdz0Vlggva2Sk/QaDFteRkjgcMQKW+3KxlzpVrzPsYYrp +# pijbkGNcvYlT4DotjIdCriak5Lt4eLl6FuFWxsC6ZFO7KhbnUEi7iGkMiMbxvuAv +# fTuxylONQIMe58tySSgeTIAehVbnhe3yYbyqOgd99qtu5Wbd4lz1L+2N1E2VhGjj +# gMtqedHSEJFGKes+JvK0jM1MuWbIu6pQOA3ljJRdGVq/9XtAbm8WqJqclUeGhXk+ +# DF5mjBoKJL6cqtKctvdPbnjEKD+jHA9QBje6CNk1prUe2nhYHTno+EyREJZ+TeHd +# wq2lfvgtGx/sK0YYoxn2Off1wU9xLokDEaJLu5i/+k/kezbvBkTkVf826uV8Mefz +# wlLE5hZ7Wn6lJXPbwGqZIS1j5Vn1TS+QHye30qsU5Thmh1EIa/tTQznQZPpWz+D0 +# CuYUbWR4u5j9lMNzIfMvwi4g14Gs0/EH1OG92V1LbjGUKYvmQaRllMBY5eUuKZCm +# t2Fk+tkgbBhRYLqmgQ8JJVPxvzvpqwcOagc5YhnJ1oV/E9mNec9ixezhe7nMZxMH +# msF47caIyLBuMnnHC1mDjcbu9Sx8e47LZInxscS451NeX1XSfRkpWQNO+l3qRXMc +# hH7XzuLUOncCAwEAAaOCAYswggGHMA4GA1UdDwEB/wQEAwIHgDAMBgNVHRMBAf8E +# AjAAMBYGA1UdJQEB/wQMMAoGCCsGAQUFBwMIMCAGA1UdIAQZMBcwCAYGZ4EMAQQC +# MAsGCWCGSAGG/WwHATAfBgNVHSMEGDAWgBS6FtltTYUvcyl2mi91jGogj57IbzAd +# BgNVHQ4EFgQUYore0GH8jzEU7ZcLzT0qlBTfUpwwWgYDVR0fBFMwUTBPoE2gS4ZJ +# aHR0cDovL2NybDMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0VHJ1c3RlZEc0UlNBNDA5 +# NlNIQTI1NlRpbWVTdGFtcGluZ0NBLmNybDCBkAYIKwYBBQUHAQEEgYMwgYAwJAYI +# KwYBBQUHMAGGGGh0dHA6Ly9vY3NwLmRpZ2ljZXJ0LmNvbTBYBggrBgEFBQcwAoZM +# aHR0cDovL2NhY2VydHMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0VHJ1c3RlZEc0UlNB +# NDA5NlNIQTI1NlRpbWVTdGFtcGluZ0NBLmNydDANBgkqhkiG9w0BAQsFAAOCAgEA +# VaoqGvNG83hXNzD8deNP1oUj8fz5lTmbJeb3coqYw3fUZPwV+zbCSVEseIhjVQlG +# OQD8adTKmyn7oz/AyQCbEx2wmIncePLNfIXNU52vYuJhZqMUKkWHSphCK1D8G7We +# CDAJ+uQt1wmJefkJ5ojOfRu4aqKbwVNgCeijuJ3XrR8cuOyYQfD2DoD75P/fnRCn +# 6wC6X0qPGjpStOq/CUkVNTZZmg9U0rIbf35eCa12VIp0bcrSBWcrduv/mLImlTgZ +# iEQU5QpZomvnIj5EIdI/HMCb7XxIstiSDJFPPGaUr10CU+ue4p7k0x+GAWScAMLp +# WnR1DT3heYi/HAGXyRkjgNc2Wl+WFrFjDMZGQDvOXTXUWT5Dmhiuw8nLw/ubE19q +# tcfg8wXDWd8nYiveQclTuf80EGf2JjKYe/5cQpSBlIKdrAqLxksVStOYkEVgM4Dg +# I974A6T2RUflzrgDQkfoQTZxd639ouiXdE4u2h4djFrIHprVwvDGIqhPm73YHJpR +# xC+a9l+nJ5e6li6FV8Bg53hWf2rvwpWaSxECyIKcyRoFfLpxtU56mWz06J7UWpjI +# n7+NuxhcQ/XQKujiYu54BNu90ftbCqhwfvCXhHjjCANdRyxjqCU4lwHSPzra5eX2 +# 5pvcfizM/xdMTQCi2NYBDriL7ubgclWJLCcZYfZ3AYwwggauMIIElqADAgECAhAH +# Nje3JFR82Ees/ShmKl5bMA0GCSqGSIb3DQEBCwUAMGIxCzAJBgNVBAYTAlVTMRUw +# EwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5jb20x +# ITAfBgNVBAMTGERpZ2lDZXJ0IFRydXN0ZWQgUm9vdCBHNDAeFw0yMjAzMjMwMDAw +# MDBaFw0zNzAzMjIyMzU5NTlaMGMxCzAJBgNVBAYTAlVTMRcwFQYDVQQKEw5EaWdp +# Q2VydCwgSW5jLjE7MDkGA1UEAxMyRGlnaUNlcnQgVHJ1c3RlZCBHNCBSU0E0MDk2 +# IFNIQTI1NiBUaW1lU3RhbXBpbmcgQ0EwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAw +# ggIKAoICAQDGhjUGSbPBPXJJUVXHJQPE8pE3qZdRodbSg9GeTKJtoLDMg/la9hGh +# RBVCX6SI82j6ffOciQt/nR+eDzMfUBMLJnOWbfhXqAJ9/UO0hNoR8XOxs+4rgISK +# Ihjf69o9xBd/qxkrPkLcZ47qUT3w1lbU5ygt69OxtXXnHwZljZQp09nsad/ZkIdG +# AHvbREGJ3HxqV3rwN3mfXazL6IRktFLydkf3YYMZ3V+0VAshaG43IbtArF+y3kp9 +# zvU5EmfvDqVjbOSmxR3NNg1c1eYbqMFkdECnwHLFuk4fsbVYTXn+149zk6wsOeKl +# SNbwsDETqVcplicu9Yemj052FVUmcJgmf6AaRyBD40NjgHt1biclkJg6OBGz9vae +# 5jtb7IHeIhTZgirHkr+g3uM+onP65x9abJTyUpURK1h0QCirc0PO30qhHGs4xSnz +# yqqWc0Jon7ZGs506o9UD4L/wojzKQtwYSH8UNM/STKvvmz3+DrhkKvp1KCRB7UK/ +# BZxmSVJQ9FHzNklNiyDSLFc1eSuo80VgvCONWPfcYd6T/jnA+bIwpUzX6ZhKWD7T +# A4j+s4/TXkt2ElGTyYwMO1uKIqjBJgj5FBASA31fI7tk42PgpuE+9sJ0sj8eCXbs +# q11GdeJgo1gJASgADoRU7s7pXcheMBK9Rp6103a50g5rmQzSM7TNsQIDAQABo4IB +# XTCCAVkwEgYDVR0TAQH/BAgwBgEB/wIBADAdBgNVHQ4EFgQUuhbZbU2FL3Mpdpov +# dYxqII+eyG8wHwYDVR0jBBgwFoAU7NfjgtJxXWRM3y5nP+e6mK4cD08wDgYDVR0P +# AQH/BAQDAgGGMBMGA1UdJQQMMAoGCCsGAQUFBwMIMHcGCCsGAQUFBwEBBGswaTAk +# BggrBgEFBQcwAYYYaHR0cDovL29jc3AuZGlnaWNlcnQuY29tMEEGCCsGAQUFBzAC +# hjVodHRwOi8vY2FjZXJ0cy5kaWdpY2VydC5jb20vRGlnaUNlcnRUcnVzdGVkUm9v +# dEc0LmNydDBDBgNVHR8EPDA6MDigNqA0hjJodHRwOi8vY3JsMy5kaWdpY2VydC5j +# b20vRGlnaUNlcnRUcnVzdGVkUm9vdEc0LmNybDAgBgNVHSAEGTAXMAgGBmeBDAEE +# AjALBglghkgBhv1sBwEwDQYJKoZIhvcNAQELBQADggIBAH1ZjsCTtm+YqUQiAX5m +# 1tghQuGwGC4QTRPPMFPOvxj7x1Bd4ksp+3CKDaopafxpwc8dB+k+YMjYC+VcW9dt +# h/qEICU0MWfNthKWb8RQTGIdDAiCqBa9qVbPFXONASIlzpVpP0d3+3J0FNf/q0+K +# LHqrhc1DX+1gtqpPkWaeLJ7giqzl/Yy8ZCaHbJK9nXzQcAp876i8dU+6WvepELJd +# 6f8oVInw1YpxdmXazPByoyP6wCeCRK6ZJxurJB4mwbfeKuv2nrF5mYGjVoarCkXJ +# 38SNoOeY+/umnXKvxMfBwWpx2cYTgAnEtp/Nh4cku0+jSbl3ZpHxcpzpSwJSpzd+ +# k1OsOx0ISQ+UzTl63f8lY5knLD0/a6fxZsNBzU+2QJshIUDQtxMkzdwdeDrknq3l +# NHGS1yZr5Dhzq6YBT70/O3itTK37xJV77QpfMzmHQXh6OOmc4d0j/R0o08f56PGY +# X/sr2H7yRp11LB4nLCbbbxV7HhmLNriT1ObyF5lZynDwN7+YAN8gFk8n+2BnFqFm +# ut1VwDophrCYoCvtlUG3OtUVmDG0YgkPCr2B2RP+v6TR81fZvAT6gt4y3wSJ8ADN +# XcL50CN/AAvkdgIm2fBldkKmKYcJRyvmfxqkhQ/8mJb2VVQrH4D6wPIOK+XW+6kv +# RBVK5xMOHds3OBqhK/bt1nz8MIIFjTCCBHWgAwIBAgIQDpsYjvnQLefv21DiCEAY +# WjANBgkqhkiG9w0BAQwFADBlMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNl +# cnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQuY29tMSQwIgYDVQQDExtEaWdp +# Q2VydCBBc3N1cmVkIElEIFJvb3QgQ0EwHhcNMjIwODAxMDAwMDAwWhcNMzExMTA5 +# MjM1OTU5WjBiMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkw +# FwYDVQQLExB3d3cuZGlnaWNlcnQuY29tMSEwHwYDVQQDExhEaWdpQ2VydCBUcnVz +# dGVkIFJvb3QgRzQwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC/5pBz +# aN675F1KPDAiMGkz7MKnJS7JIT3yithZwuEppz1Yq3aaza57G4QNxDAf8xukOBbr +# VsaXbR2rsnnyyhHS5F/WBTxSD1Ifxp4VpX6+n6lXFllVcq9ok3DCsrp1mWpzMpTR +# EEQQLt+C8weE5nQ7bXHiLQwb7iDVySAdYyktzuxeTsiT+CFhmzTrBcZe7FsavOvJ +# z82sNEBfsXpm7nfISKhmV1efVFiODCu3T6cw2Vbuyntd463JT17lNecxy9qTXtyO +# j4DatpGYQJB5w3jHtrHEtWoYOAMQjdjUN6QuBX2I9YI+EJFwq1WCQTLX2wRzKm6R +# AXwhTNS8rhsDdV14Ztk6MUSaM0C/CNdaSaTC5qmgZ92kJ7yhTzm1EVgX9yRcRo9k +# 98FpiHaYdj1ZXUJ2h4mXaXpI8OCiEhtmmnTK3kse5w5jrubU75KSOp493ADkRSWJ +# tppEGSt+wJS00mFt6zPZxd9LBADMfRyVw4/3IbKyEbe7f/LVjHAsQWCqsWMYRJUa +# dmJ+9oCw++hkpjPRiQfhvbfmQ6QYuKZ3AeEPlAwhHbJUKSWJbOUOUlFHdL4mrLZB +# dd56rF+NP8m800ERElvlEFDrMcXKchYiCd98THU/Y+whX8QgUWtvsauGi0/C1kVf +# nSD8oR7FwI+isX4KJpn15GkvmB0t9dmpsh3lGwIDAQABo4IBOjCCATYwDwYDVR0T +# AQH/BAUwAwEB/zAdBgNVHQ4EFgQU7NfjgtJxXWRM3y5nP+e6mK4cD08wHwYDVR0j +# BBgwFoAUReuir/SSy4IxLVGLp6chnfNtyA8wDgYDVR0PAQH/BAQDAgGGMHkGCCsG +# AQUFBwEBBG0wazAkBggrBgEFBQcwAYYYaHR0cDovL29jc3AuZGlnaWNlcnQuY29t +# MEMGCCsGAQUFBzAChjdodHRwOi8vY2FjZXJ0cy5kaWdpY2VydC5jb20vRGlnaUNl +# cnRBc3N1cmVkSURSb290Q0EuY3J0MEUGA1UdHwQ+MDwwOqA4oDaGNGh0dHA6Ly9j +# cmwzLmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydEFzc3VyZWRJRFJvb3RDQS5jcmwwEQYD +# VR0gBAowCDAGBgRVHSAAMA0GCSqGSIb3DQEBDAUAA4IBAQBwoL9DXFXnOF+go3Qb +# PbYW1/e/Vwe9mqyhhyzshV6pGrsi+IcaaVQi7aSId229GhT0E0p6Ly23OO/0/4C5 +# +KH38nLeJLxSA8hO0Cre+i1Wz/n096wwepqLsl7Uz9FDRJtDIeuWcqFItJnLnU+n +# BgMTdydE1Od/6Fmo8L8vC6bp8jQ87PcDx4eo0kxAGTVGamlUsLihVo7spNU96LHc +# /RzY9HdaXFSMb++hUD38dglohJ9vytsgjTVgHAIDyyCwrFigDkBjxZgiwbJZ9VVr +# zyerbHbObyMt9H5xaiNrIv8SuFQtJ37YOtnwtoeW/VvRXKwYw02fc7cBqZ9Xql4o +# 4rmUMYIDdjCCA3ICAQEwdzBjMQswCQYDVQQGEwJVUzEXMBUGA1UEChMORGlnaUNl +# cnQsIEluYy4xOzA5BgNVBAMTMkRpZ2lDZXJ0IFRydXN0ZWQgRzQgUlNBNDA5NiBT +# SEEyNTYgVGltZVN0YW1waW5nIENBAhAMTWlyS5T6PCpKPSkHgD1aMA0GCWCGSAFl +# AwQCAQUAoIHRMBoGCSqGSIb3DQEJAzENBgsqhkiG9w0BCRABBDAcBgkqhkiG9w0B +# CQUxDxcNMjIxMDExMTY1NTI5WjArBgsqhkiG9w0BCRACDDEcMBowGDAWBBTzhyJN +# hjOCkjWplLy9j5bp/hx8czAvBgkqhkiG9w0BCQQxIgQgyYu+TmGN84kebkxfXnD3 +# cJyRaLRzBepBR07r7/BkPlMwNwYLKoZIhvcNAQkQAi8xKDAmMCQwIgQgx/ThvjIo +# iSCr4iY6vhrE/E/meBwtZNBMgHVXoCO1tvowDQYJKoZIhvcNAQEBBQAEggIAd+QW +# gPb2LX2KRaw6fzUGJN6PPpzRFV3OVkHKYy8/oHAYW9TZ+dgzZMmO7AraUhYwc7Qg +# WjgWgMLR8p95BhbXJvWauBHRFC8SdCtvVrkQ74oZI5Exdoljv/FL/SawklZwLSQh +# 9j+y+DxamK8PZbb9SuRsJkETc/HUxrfm1NPmPx6YXzxnKdVWA9FxNUuy0SHkBFee +# UHf12MM25re7kFKfVLQBtBHmjyOiHc3u5RLI3EHygL3BV85w94yZQSYRkJSWea3z +# OLdZqDqhGqim0hedFHiBwkEg6NfndntQtg5e9OPwInQBf8fRW4zWr2so3ovTgxoZ +# 1nOiPB+YO+OcaB0i2KDWF2rWY/8eydaEx+XDpZuUTG9q8qIt6dAdB7fFlkkL4S9h +# nNy9Sr5OsLUu2ahDElLZWeXvjJl0xpV/bW4QUcWgj1AfhWXif9NcVcba0nz4Ggno +# S/gKqhZW7q6o5cGHMvR2FD1Ucqr03I3K60aInN0UuoqWcHuD/qgoFezLgpPVTRee +# jm3RVn4Ic9KDBQKtMckB5ux6zrn7QNchzvItlDAf0A/PLUaKQlpC9PZg4u687i55 +# 1Z7XKoZoJZfIfneJvF3WyurE7JVBPxA2NoOsVI7cWh/PtzcKv7OTLqEi5hlDa8ko +# aS2jLT+AHbQCW1HzEAVodyqGKItpgePd5x0f0kE= +# SIG # End signature block diff --git a/venv/Scripts/activate b/venv/Scripts/activate new file mode 100644 index 00000000..88ae0976 --- /dev/null +++ b/venv/Scripts/activate @@ -0,0 +1,69 @@ +# This file must be used with "source bin/activate" *from bash* +# you cannot run it directly + +deactivate () { + # reset old environment variables + if [ -n "${_OLD_VIRTUAL_PATH:-}" ] ; then + PATH="${_OLD_VIRTUAL_PATH:-}" + export PATH + unset _OLD_VIRTUAL_PATH + fi + if [ -n "${_OLD_VIRTUAL_PYTHONHOME:-}" ] ; then + PYTHONHOME="${_OLD_VIRTUAL_PYTHONHOME:-}" + export PYTHONHOME + unset _OLD_VIRTUAL_PYTHONHOME + fi + + # This should detect bash and zsh, which have a hash command that must + # be called to get it to forget past commands. Without forgetting + # past commands the $PATH changes we made may not be respected + if [ -n "${BASH:-}" -o -n "${ZSH_VERSION:-}" ] ; then + hash -r 2> /dev/null + fi + + if [ -n "${_OLD_VIRTUAL_PS1:-}" ] ; then + PS1="${_OLD_VIRTUAL_PS1:-}" + export PS1 + unset _OLD_VIRTUAL_PS1 + fi + + unset VIRTUAL_ENV + unset VIRTUAL_ENV_PROMPT + if [ ! "${1:-}" = "nondestructive" ] ; then + # Self destruct! + unset -f deactivate + fi +} + +# unset irrelevant variables +deactivate nondestructive + +VIRTUAL_ENV="C:\Users\Marina\vscode-terosHDL\venv" +export VIRTUAL_ENV + +_OLD_VIRTUAL_PATH="$PATH" +PATH="$VIRTUAL_ENV/Scripts:$PATH" +export PATH + +# unset PYTHONHOME if set +# this will fail if PYTHONHOME is set to the empty string (which is bad anyway) +# could use `if (set -u; : $PYTHONHOME) ;` in bash +if [ -n "${PYTHONHOME:-}" ] ; then + _OLD_VIRTUAL_PYTHONHOME="${PYTHONHOME:-}" + unset PYTHONHOME +fi + +if [ -z "${VIRTUAL_ENV_DISABLE_PROMPT:-}" ] ; then + _OLD_VIRTUAL_PS1="${PS1:-}" + PS1="(venv) ${PS1:-}" + export PS1 + VIRTUAL_ENV_PROMPT="(venv) " + export VIRTUAL_ENV_PROMPT +fi + +# This should detect bash and zsh, which have a hash command that must +# be called to get it to forget past commands. Without forgetting +# past commands the $PATH changes we made may not be respected +if [ -n "${BASH:-}" -o -n "${ZSH_VERSION:-}" ] ; then + hash -r 2> /dev/null +fi diff --git a/venv/Scripts/activate.bat b/venv/Scripts/activate.bat new file mode 100644 index 00000000..a4055f7a --- /dev/null +++ b/venv/Scripts/activate.bat @@ -0,0 +1,34 @@ +@echo off + +rem This file is UTF-8 encoded, so we need to update the current code page while executing it +for /f "tokens=2 delims=:." %%a in ('"%SystemRoot%\System32\chcp.com"') do ( + set _OLD_CODEPAGE=%%a +) +if defined _OLD_CODEPAGE ( + "%SystemRoot%\System32\chcp.com" 65001 > nul +) + +set VIRTUAL_ENV=C:\Users\Marina\vscode-terosHDL\venv + +if not defined PROMPT set PROMPT=$P$G + +if defined _OLD_VIRTUAL_PROMPT set PROMPT=%_OLD_VIRTUAL_PROMPT% +if defined _OLD_VIRTUAL_PYTHONHOME set PYTHONHOME=%_OLD_VIRTUAL_PYTHONHOME% + +set _OLD_VIRTUAL_PROMPT=%PROMPT% +set PROMPT=(venv) %PROMPT% + +if defined PYTHONHOME set _OLD_VIRTUAL_PYTHONHOME=%PYTHONHOME% +set PYTHONHOME= + +if defined _OLD_VIRTUAL_PATH set PATH=%_OLD_VIRTUAL_PATH% +if not defined _OLD_VIRTUAL_PATH set _OLD_VIRTUAL_PATH=%PATH% + +set PATH=%VIRTUAL_ENV%\Scripts;%PATH% +set VIRTUAL_ENV_PROMPT=(venv) + +:END +if defined _OLD_CODEPAGE ( + "%SystemRoot%\System32\chcp.com" %_OLD_CODEPAGE% > nul + set _OLD_CODEPAGE= +) diff --git a/venv/Scripts/cocotb-config.exe b/venv/Scripts/cocotb-config.exe new file mode 100644 index 00000000..388479ef Binary files /dev/null and b/venv/Scripts/cocotb-config.exe differ diff --git a/venv/Scripts/deactivate.bat b/venv/Scripts/deactivate.bat new file mode 100644 index 00000000..44dae495 --- /dev/null +++ b/venv/Scripts/deactivate.bat @@ -0,0 +1,22 @@ +@echo off + +if defined _OLD_VIRTUAL_PROMPT ( + set "PROMPT=%_OLD_VIRTUAL_PROMPT%" +) +set _OLD_VIRTUAL_PROMPT= + +if defined _OLD_VIRTUAL_PYTHONHOME ( + set "PYTHONHOME=%_OLD_VIRTUAL_PYTHONHOME%" + set _OLD_VIRTUAL_PYTHONHOME= +) + +if defined _OLD_VIRTUAL_PATH ( + set "PATH=%_OLD_VIRTUAL_PATH%" +) + +set _OLD_VIRTUAL_PATH= + +set VIRTUAL_ENV= +set VIRTUAL_ENV_PROMPT= + +:END diff --git a/venv/Scripts/el_docker b/venv/Scripts/el_docker new file mode 100644 index 00000000..78b1b4d9 --- /dev/null +++ b/venv/Scripts/el_docker @@ -0,0 +1,148 @@ +#!C:\Users\Marina\vscode-terosHDL\venv\Scripts\python.exe +import os +import shutil +import subprocess +import sys +import logging +import shlex + +logger = logging.getLogger(__name__) +symbiflow_init = "bash -lec {}" + +# fmt: off +containers = [ + {'tool': 'ghdl', 'image': 'ghdl/ghdl:buster-llvm-7', 'init': '', 'vendor': '', 'part': ''}, + {'tool': 'verilator', 'image': 'verilator/verilator', 'init': '', 'vendor': '', 'part': ''}, + {'tool': 'flow.tcl', 'image': 'edalize/openlane-sky130:mpw4', 'init': '', 'vendor': '', 'part': ''}, + {'tool': 'mill', 'image': 'adoptopenjdk:8u282-b08-jre-hotspot', 'init': '', 'vendor': '', 'part': ''}, + {'tool': 'sbt', 'image': 'adoptopenjdk:8u282-b08-jre-hotspot', 'init': '', 'vendor': '', 'part': ''}, + {'tool': 'yosys', 'image': 'hdlc/yosys', 'init': '', 'vendor': '', 'part': ''}, + {'tool': 'nextpnr-ice40', 'image': 'hdlc/nextpnr', 'init': '', 'vendor': '', 'part': ''}, + {'tool': 'nextpnr-ecp5', 'image': 'hdlc/nextpnr', 'init': '', 'vendor': '', 'part': ''}, + {'tool': 'nextpnr-nexus', 'image': 'hdlc/nextpnr', 'init': '', 'vendor': '', 'part': ''}, + {'tool': 'icepack', 'image': 'hdlc/icestorm', 'init': '', 'vendor': '', 'part': ''}, + {'tool': 'iverilog', 'image': 'hdlc/iverilog', 'init': '', 'vendor': '', 'part': ''}, + {'tool': 'vvp', 'image': 'hdlc/iverilog', 'init': '', 'vendor': '', 'part': ''}, + {'tool': 'ecppack', 'image': 'hdlc/prjtrellis', 'init': '', 'vendor': '', 'part': ''}, + {'tool': 'icetime', 'image': 'hdlc/icestorm', 'init': '', 'vendor': '', 'part': ''}, + {'tool': 'icebox_stat', 'image': 'hdlc/icestorm', 'init': '', 'vendor': '', 'part': ''}, + {'tool': 'icepll', 'image': 'hdlc/icestorm', 'init': '', 'vendor': '', 'part': ''}, + {'tool': 'ecppll', 'image': 'hdlc/prjtrellis', 'init': '', 'vendor': '', 'part': ''}, + # For Quicklogic EOS S3 + {'tool': 'ql_symbiflow', 'image': 'gcr.io/hdl-containers/conda/symbiflow/eos-s3', 'init': symbiflow_init, 'vendor': 'quicklogic', 'part': 'ql-eos-s3'}, + {'tool': 'symbiflow_synth', 'image': 'gcr.io/hdl-containers/conda/symbiflow/eos-s3', 'init': symbiflow_init, 'vendor': 'quicklogic', 'part': 'ql-eos-s3'}, + {'tool': 'symbiflow_pack', 'image': 'gcr.io/hdl-containers/conda/symbiflow/eos-s3', 'init': symbiflow_init, 'vendor': 'quicklogic', 'part': 'ql-eos-s3'}, + {'tool': 'symbiflow_place', 'image': 'gcr.io/hdl-containers/conda/symbiflow/eos-s3', 'init': symbiflow_init, 'vendor': 'quicklogic', 'part': 'ql-eos-s3'}, + {'tool': 'symbiflow_route', 'image': 'gcr.io/hdl-containers/conda/symbiflow/eos-s3', 'init': symbiflow_init, 'vendor': 'quicklogic', 'part': 'ql-eos-s3'}, + {'tool': 'symbiflow_write_fasm', 'image': 'gcr.io/hdl-containers/conda/symbiflow/eos-s3', 'init': symbiflow_init, 'vendor': 'quicklogic', 'part': 'ql-eos-s3'}, + {'tool': 'symbiflow_write_bitstream', 'image': 'gcr.io/hdl-containers/conda/symbiflow/eos-s3', 'init': symbiflow_init, 'vendor': 'quicklogic', 'part': 'ql-eos-s3'}, + {'tool': 'symbiflow_write_binary', 'image': 'gcr.io/hdl-containers/conda/symbiflow/eos-s3', 'init': symbiflow_init, 'vendor': 'quicklogic', 'part': 'ql-eos-s3'}, + {'tool': 'symbiflow_write_bitheader', 'image': 'gcr.io/hdl-containers/conda/symbiflow/eos-s3', 'init': symbiflow_init, 'vendor': 'quicklogic', 'part': 'ql-eos-s3'}, + # For Xilinx xc7a35/50t + {'tool': 'symbiflow_synth', 'image': 'gcr.io/hdl-containers/conda/symbiflow/xc7/a50t', 'init': symbiflow_init, 'vendor': 'xilinx', 'part': 'xc7a50t'}, + {'tool': 'symbiflow_pack', 'image': 'gcr.io/hdl-containers/conda/symbiflow/xc7/a50t', 'init': symbiflow_init, 'vendor': 'xilinx', 'part': 'xc7a50t'}, + {'tool': 'symbiflow_place', 'image': 'gcr.io/hdl-containers/conda/symbiflow/xc7/a50t', 'init': symbiflow_init, 'vendor': 'xilinx', 'part': 'xc7a50t'}, + {'tool': 'symbiflow_route', 'image': 'gcr.io/hdl-containers/conda/symbiflow/xc7/a50t', 'init': symbiflow_init, 'vendor': 'xilinx', 'part': 'xc7a50t'}, + {'tool': 'symbiflow_write_fasm', 'image': 'gcr.io/hdl-containers/conda/symbiflow/xc7/a50t', 'init': symbiflow_init, 'vendor': 'xilinx', 'part': 'xc7a50t'}, + {'tool': 'symbiflow_write_bitstream', 'image': 'gcr.io/hdl-containers/conda/symbiflow/xc7/a50t', 'init': symbiflow_init, 'vendor': 'xilinx', 'part': 'xc7a50t'}, + # For Xilinx xc7a100t + {'tool': 'symbiflow_synth', 'image': 'gcr.io/hdl-containers/conda/symbiflow/xc7/a100t', 'init': symbiflow_init, 'vendor': 'xilinx', 'part': 'xc7a100t'}, + {'tool': 'symbiflow_pack', 'image': 'gcr.io/hdl-containers/conda/symbiflow/xc7/a100t', 'init': symbiflow_init, 'vendor': 'xilinx', 'part': 'xc7a100t'}, + {'tool': 'symbiflow_place', 'image': 'gcr.io/hdl-containers/conda/symbiflow/xc7/a100t', 'init': symbiflow_init, 'vendor': 'xilinx', 'part': 'xc7a100t'}, + {'tool': 'symbiflow_route', 'image': 'gcr.io/hdl-containers/conda/symbiflow/xc7/a100t', 'init': symbiflow_init, 'vendor': 'xilinx', 'part': 'xc7a100t'}, + {'tool': 'symbiflow_write_fasm', 'image': 'gcr.io/hdl-containers/conda/symbiflow/xc7/a100t', 'init': symbiflow_init, 'vendor': 'xilinx', 'part': 'xc7a100t'}, + {'tool': 'symbiflow_write_bitstream', 'image': 'gcr.io/hdl-containers/conda/symbiflow/xc7/a100t', 'init': symbiflow_init, 'vendor': 'xilinx', 'part': 'xc7a100t'}, + # For Xilinx xc7a200t + {'tool': 'symbiflow_synth', 'image': 'gcr.io/hdl-containers/conda/symbiflow/xc7/a200t', 'init': symbiflow_init, 'vendor': 'xilinx', 'part': 'xc7a200t'}, + {'tool': 'symbiflow_pack', 'image': 'gcr.io/hdl-containers/conda/symbiflow/xc7/a200t', 'init': symbiflow_init, 'vendor': 'xilinx', 'part': 'xc7a200t'}, + {'tool': 'symbiflow_place', 'image': 'gcr.io/hdl-containers/conda/symbiflow/xc7/a200t', 'init': symbiflow_init, 'vendor': 'xilinx', 'part': 'xc7a200t'}, + {'tool': 'symbiflow_route', 'image': 'gcr.io/hdl-containers/conda/symbiflow/xc7/a200t', 'init': symbiflow_init, 'vendor': 'xilinx', 'part': 'xc7a200t'}, + {'tool': 'symbiflow_write_fasm', 'image': 'gcr.io/hdl-containers/conda/symbiflow/xc7/a200t', 'init': symbiflow_init, 'vendor': 'xilinx', 'part': 'xc7a200t'}, + {'tool': 'symbiflow_write_bitstream', 'image': 'gcr.io/hdl-containers/conda/symbiflow/xc7/a200t', 'init': symbiflow_init, 'vendor': 'xilinx', 'part': 'xc7a200t'}, + # For Xilinx xc7z010 + {'tool': 'symbiflow_synth', 'image': 'gcr.io/hdl-containers/conda/symbiflow/xc7/z010', 'init': symbiflow_init, 'vendor': 'xilinx', 'part': 'xc7z010'}, + {'tool': 'symbiflow_pack', 'image': 'gcr.io/hdl-containers/conda/symbiflow/xc7/z010', 'init': symbiflow_init, 'vendor': 'xilinx', 'part': 'xc7z010'}, + {'tool': 'symbiflow_place', 'image': 'gcr.io/hdl-containers/conda/symbiflow/xc7/z010', 'init': symbiflow_init, 'vendor': 'xilinx', 'part': 'xc7z010'}, + {'tool': 'symbiflow_route', 'image': 'gcr.io/hdl-containers/conda/symbiflow/xc7/z010', 'init': symbiflow_init, 'vendor': 'xilinx', 'part': 'xc7z010'}, + {'tool': 'symbiflow_write_fasm', 'image': 'gcr.io/hdl-containers/conda/symbiflow/xc7/z010', 'init': symbiflow_init, 'vendor': 'xilinx', 'part': 'xc7z010'}, + {'tool': 'symbiflow_write_bitstream', 'image': 'gcr.io/hdl-containers/conda/symbiflow/xc7/z010', 'init': symbiflow_init, 'vendor': 'xilinx', 'part': 'xc7z010'}, + # For Xilinx xc7z020 + {'tool': 'symbiflow_synth', 'image': 'gcr.io/hdl-containers/conda/symbiflow/xc7/z020', 'init': symbiflow_init, 'vendor': 'xilinx', 'part': 'xc7z020'}, + {'tool': 'symbiflow_pack', 'image': 'gcr.io/hdl-containers/conda/symbiflow/xc7/z020', 'init': symbiflow_init, 'vendor': 'xilinx', 'part': 'xc7z020'}, + {'tool': 'symbiflow_place', 'image': 'gcr.io/hdl-containers/conda/symbiflow/xc7/z020', 'init': symbiflow_init, 'vendor': 'xilinx', 'part': 'xc7z020'}, + {'tool': 'symbiflow_route', 'image': 'gcr.io/hdl-containers/conda/symbiflow/xc7/z020', 'init': symbiflow_init, 'vendor': 'xilinx', 'part': 'xc7z020'}, + {'tool': 'symbiflow_write_fasm', 'image': 'gcr.io/hdl-containers/conda/symbiflow/xc7/z020', 'init': symbiflow_init, 'vendor': 'xilinx', 'part': 'xc7z020'}, + {'tool': 'symbiflow_write_bitstream', 'image': 'gcr.io/hdl-containers/conda/symbiflow/xc7/z020', 'init': symbiflow_init, 'vendor': 'xilinx', 'part': 'xc7z020'}, +] +# fmt: on + +tool = sys.argv[1] +toolname = os.path.basename(tool) + +# If it's in the container list, wrap with Docker +if [c for c in containers if c["tool"] == toolname]: + (build_root, work) = os.path.split(os.getcwd()) + dockerEnv = "" + for k in os.environ: + dockerEnv = dockerEnv + "-e " + k + "=" " + os.environ[k] + " " " + + runtool = os.path.relpath(os.path.realpath(tool), os.getcwd()) + for c in containers: + # Vendor neutral + if c["tool"] == toolname and c["vendor"] == "": + image = c["image"] + init = c["init"] + break + # Vendor specific toolchain + elif ( + c["tool"] == toolname + and c["vendor"] == os.environ.get("EDALIZE_VENDOR") + and os.environ.get("EDALIZE_PART") in c["part"] + ): + image = c["image"] + init = c["init"] + break + else: + image = "" + init = "" + + if image: + logger.info("INFO: Will use image '{}' with init '{}'".format(image, init)) + else: + logger.error("ERROR: Tool {} not found in container list.".format(toolname)) + exit(1) + + _extra = os.environ.get("EDALIZE_EXTRA_DOCKER_FLAGS") + extra = _extra.split(" ") if _extra else [] + + prefix = ( + [ + "docker", + "run", + "--rm", + "-v", + build_root + ":/src", + # '-e', dockerEnv, + ] + + extra + + [ + "-u", + f"{os.getuid()}:{os.getgid()}", + "-w", + "/src/" + work, + image, + ] + ) + if init: + c = init.format(shlex.quote(runtool + " " + shlex.join(sys.argv[2:]))) + elif tool == "verilator": + c = shlex.join(sys.argv[2:]) + else: + c = runtool + " " + shlex.join(sys.argv[2:]) + cmd = prefix + shlex.split(c) +# Otherwise, run it locally +else: + cmd = sys.argv[1:] + +logger.info("INFO: Wrapper Command: ".format(" ".join(cmd))) +sys.exit(subprocess.call(cmd, env=os.environ)) diff --git a/venv/Scripts/find_libpython.exe b/venv/Scripts/find_libpython.exe new file mode 100644 index 00000000..182ed1e1 Binary files /dev/null and b/venv/Scripts/find_libpython.exe differ diff --git a/venv/Scripts/pip.exe b/venv/Scripts/pip.exe new file mode 100644 index 00000000..c1f5cfd1 Binary files /dev/null and b/venv/Scripts/pip.exe differ diff --git a/venv/Scripts/pip3.10.exe b/venv/Scripts/pip3.10.exe new file mode 100644 index 00000000..c1f5cfd1 Binary files /dev/null and b/venv/Scripts/pip3.10.exe differ diff --git a/venv/Scripts/pip3.exe b/venv/Scripts/pip3.exe new file mode 100644 index 00000000..c1f5cfd1 Binary files /dev/null and b/venv/Scripts/pip3.exe differ diff --git a/venv/Scripts/python.exe b/venv/Scripts/python.exe new file mode 100644 index 00000000..a23dfcdb Binary files /dev/null and b/venv/Scripts/python.exe differ diff --git a/venv/Scripts/pythonw.exe b/venv/Scripts/pythonw.exe new file mode 100644 index 00000000..512209a0 Binary files /dev/null and b/venv/Scripts/pythonw.exe differ diff --git a/venv/Scripts/vsg.exe b/venv/Scripts/vsg.exe new file mode 100644 index 00000000..b0e57595 Binary files /dev/null and b/venv/Scripts/vsg.exe differ diff --git a/venv/Scripts/yosys.exe b/venv/Scripts/yosys.exe new file mode 100644 index 00000000..d5bfd207 Binary files /dev/null and b/venv/Scripts/yosys.exe differ diff --git a/venv/Scripts/yowasp-sby.exe b/venv/Scripts/yowasp-sby.exe new file mode 100644 index 00000000..bf82c10e Binary files /dev/null and b/venv/Scripts/yowasp-sby.exe differ diff --git a/venv/Scripts/yowasp-yosys-smtbmc.exe b/venv/Scripts/yowasp-yosys-smtbmc.exe new file mode 100644 index 00000000..4be53ee1 Binary files /dev/null and b/venv/Scripts/yowasp-yosys-smtbmc.exe differ diff --git a/venv/Scripts/yowasp-yosys-witness.exe b/venv/Scripts/yowasp-yosys-witness.exe new file mode 100644 index 00000000..1815fa07 Binary files /dev/null and b/venv/Scripts/yowasp-yosys-witness.exe differ diff --git a/venv/Scripts/yowasp-yosys.exe b/venv/Scripts/yowasp-yosys.exe new file mode 100644 index 00000000..723c2fd9 Binary files /dev/null and b/venv/Scripts/yowasp-yosys.exe differ diff --git a/venv/pyvenv.cfg b/venv/pyvenv.cfg new file mode 100644 index 00000000..55417d34 --- /dev/null +++ b/venv/pyvenv.cfg @@ -0,0 +1,3 @@ +home = C:\Program Files\Python310 +include-system-site-packages = false +version = 3.10.8 diff --git a/work/_NVC_LIB b/work/_NVC_LIB new file mode 100644 index 00000000..6dc44545 --- /dev/null +++ b/work/_NVC_LIB @@ -0,0 +1 @@ +nvc 1.18.1