How to Use the ruckus VS Code Extension
Goal: Browse, build, and simulate a ruckus firmware project from VS Code.
The extension shows the design hierarchy, the files every ruckus.tcl
loads, and the make targets of the selected top level.
The extension lives in the vscode-plugin/ directory of the ruckus
repository. It is versioned with ruckus because it copies the behavior of the
ruckus loader procedures (loadRuckusTcl, loadSource, …) and parses the
system_*.mk files.
Note
Opening and browsing a project does not need Vivado. The extension runs
the ruckus.tcl tree with plain tclsh, using stub versions of the
ruckus procedures. You only need Vivado (or GHDL, Icarus Verilog, …) to
run make.
Features
Design Hierarchy: instance tree of the synthesis and simulation tops, parsed from the HDL loaded by
ruckus.tcl.Sources and Libraries & Categories: every file each
ruckus.tclloads, with its library,simtag and the line that loaded it.Make Targets: run
make bit,make xsim, … as VS Code tasks, after sourcing the firmware setup script with the selected Vivado version.Simulate Current File: simulate the testbench open in the editor.
Build reports (bottom panel): Log Report (filterable Vivado messages), Timing (slack summary, failing clocks and paths) and Resources (utilization, also per instance).
Set Up Workspace:
.vscodesettings and tasks, andvhdl_ls.tomlfor the VHDL language server.
Prerequisites
VS Code 1.90 or newer.
tclshon PATH (or setruckus.tclsh). macOS and most Linux distributions already include it.To build the extension from source: Node.js 18 or newer and
npm. If the system Node.js is older, install one with conda:conda create -y -n node20 -c conda-forge nodejs=20 conda activate node20 node -v && npm -v
Build and Install
The extension runs where the firmware is: on your machine for a local checkout, on the server for VS Code Remote (SSH, containers, WSL). Build the package there:
cd ruckus/vscode-plugin
./scripts/build.sh # npm install, compile, package slac-ruckus-plugin-<version>.vsix
./scripts/build.sh --compile # compile only (out/), no package
Then install it, with one of:
./scripts/install.sh(builds if needed, then runscode --install-extension)../scripts/install.sh --uninstallremoves it.The Extensions view:
...> Install from VSIX…, then pick the.vsixfile.
Run Developer: Reload Window afterwards. CI builds the same .vsix in
the vscode_plugin job of ruckus_ci.yml and uploads it as an artifact,
so you can also download it instead of building.
Tip
VS Code Remote: connect to the server first, then run install.sh
in a VS Code integrated terminal. That terminal provides a code
command that installs on the server. A plain SSH shell has no code
command: use Install from VSIX… while connected instead (the
.vsix can be built on either side). The Extensions view lists the
extension under SSH: <host> - Installed. tclsh, make and Vivado
must be available on the server.
Select a Top Level
Open the firmware repository (the folder that contains firmware/) in VS
Code. The extension starts when the workspace contains a ruckus.tcl file.
If there is only one target, the extension selects it. If not, click the
status-bar item or run Ruckus: Select Top Level. A top level is a
directory with a Makefile that includes a ruckus system_*.mk file, plus
a ruckus.tcl, usually firmware/targets/<Target>. You can also
right-click a folder and choose Ruckus: Use as Top Level.
The extension evaluates the target Makefile (TOP_DIR, PRJ_PART,
shared_version.mk, the system_*.mk include, …) without running
make. Then it runs ruckus.tcl with those variables in the environment.
getFpgaArch is derived from PRJ_PART, so family-dependent branches
pick the same files as a real build.
Views
The tree views are in the Ruckus activity-bar container (the build reports are panel tabs, see Build Reports).
- Design Hierarchy
The tree of instances under the synthesis top (
set_property top, otherwisePROJECT) and the simulation top (sim_1). It shows instances, generate blocks, and processes. Instances are resolved using the-liblibraries. Units that cannot be found are flagged. Generics are not elaborated, so the tree shows every branch of anif generateand shows eachfor generateonce.- Sources (ruckus.tcl)
The
loadRuckusTcltree, with one node perruckus.tcl. For each loaded file it shows the library, thesimtag, and theruckus.tcl:linethat loaded it. Load problems also appear in the Problems panel: a missing directory, a bad extension, a Tcl error, anexitcall (where a real build aborts), and a relative-pathor-dir(Vivado resolves it againstOUT_DIR, not the source tree; use$::DIR_PATH). The view also lists the project’s hook scripts (see Hook Script Reference).- Libraries & Categories
Top modules, submodules, HDL libraries, VHDL/SV packages, constraints, IP cores, block designs, netlists, simulation sources, and C/C++ files.
- Make Targets
The targets of the selected top level, mostly from the ruckus
system_*.mkfiles (see Makefile Reference). Clicking ▶ runsmake <target>as a VS Code task in a dedicated terminal. Run with Variables… adds variables such asVIVADO_PROJECT_SIM=MyTb.
Run make
Before make, every task sources the firmware’s setup_env_slac.sh (or
ruckus.setupScript). The Vivado version is read from the script, for
example from source .../2026.1/Vivado/2026.1/settings64.sh, and the scan
uses it as VIVADO_VERSION. To choose another version, click the Vivado
item in the status bar. The selection is passed to the script as its first
argument, which is opt-in: it only changes the Vivado used by make if
the script reads $1 (for example VIVADO_VERSION=${1:-2025.1}).
Otherwise the status bar shows a warning, and both make and the scan
use the script’s own version. The make output is also saved to
build/logs/<target>_<goal>.log. To tail that log, or any Vivado log in
the build directory, run
Ruckus: Follow Build Log….
The problem matcher depends on the backend, so errors and warnings with a file location appear in the Problems panel:
Backend |
Parsed output |
|---|---|
Vivado |
|
GHDL |
|
Icarus Verilog |
|
Verilator |
|
Build Reports
Three tabs in the bottom panel, next to the terminal, show the results of
the last build of the selected top level. They refresh while visible and
when a ruckus task ends. Run Ruckus: Show Log Report,
Ruckus: Show Timing Summary or Ruckus: Show Resource Utilization
to open them.
- Ruckus: Log Report
The messages of
vivado.logand thesynth_1/impl_1runme.logfiles, like the Vivado Messages window. Toggle errors, critical warnings, warnings and infos independently, filter by text (a-wordexcludes), and group by message ID, build step or source file. The Logs menu also offers the out-of-context IP runs and the savedmake xsim/vcs/msimoutput. Click a message to open its source location; Alt-click opens the log line. For GHDL, Icarus Verilog and Verilator targets the view reads the make output saved inbuild/logs/.- Ruckus: Timing
impl_1/<top>_timing_summary_routed.rpt: WNS/TNS, WHS/THS and WPWS/TPWS, the check_timing issues, the intra-clock table (generated clocks indented below their master), inter-clock and path-group tables, and the worst paths sorted by slack. Negative slack, failing clocks and violated paths are highlighted, and Only failing hides the rest. Click a path to open its detail in the report.- Ruckus: Resources
The placed (Implementation) and Synthesis utilization reports, with the headline resources as bars, sorted by utilization, and every report table. The Hierarchy tab shows utilization per instance. Vivado does not write that report during the build, so Generate hierarchical utilization (also Ruckus: Generate Hierarchical Utilization) runs Vivado in batch mode on the routed checkpoint (
report_utilization -hierarchical, depth set byruckus.hierUtilizationDepth) and writesbuild/<target>/<target>_utilization_hierarchical.rpt.
Simulate the Current File
To simulate the testbench in the active editor, open it and click the beaker icon in the editor title bar. You can also run Ruckus: Simulate Current File from the command palette or the editor context menu. The extension finds the entity or module defined in the file, and prefers testbench units when the file has several. It then runs the target’s simulation flow with that unit as the top:
Backend |
Command |
|---|---|
Vivado |
|
GHDL |
|
Icarus Verilog |
|
Verilator |
|
For Vivado targets, ruckus.simulateTarget selects xsim, vcs, or
msim. Simulate Current File with Variables… asks for extra
variables, such as VIVADO_PROJECT_SIM_TIME=10us or
GHDL_STOP_TIME=1us.
The file must be loaded by the selected target’s ruckus.tcl, usually
with loadSource -sim_only. Otherwise the simulator cannot find the unit.
Note
GHDL derives OUT_DIR from PROJECT, so each simulated unit gets its
own build/<unit> directory.
Set Up the Workspace
Ruckus: Set Up Workspace (in the Sources view ... menu) writes
project files that are also useful without the extension:
.vscode/settings.jsonpython.analysis.extraPathsandPYTHONPATHfor the integrated terminal. They list everysubmodules/<name>/pythondirectory (for examplesurf/python) and the repository’spython/orsoftware/python/directory. Pylance can then resolveimport surfand the project’s Rogue device trees.Excludes the Vivado
build/tree and.Xilfrom the file watcher and search. These directories hold hundreds of thousands of files.Opens
ruckus.tcland.xdcfiles in Tcl mode.
.vscode/tasks.jsonruckustasks for the selected target: the default build task (bit, ortbfor simulation-only backends, which runs with Ctrl+Shift+B), simulate current file, a variant that asks for extra variables, andclean.vhdl_ls.toml(optional)The VHDL library mapping of every loaded file, for the VHDL-LS / rust_hdl language server. VHDL-LS reserves
work, so files loaded without-libgo toxil_defaultlib, the Vivado default library. Theunisim,unimacroandxpmlibraries map to the VHDL sources of the Vivado installation (ruckus.vivadoPath, otherwise$XILINX_VIVADO, thesettings64.shsourced by the setup script, orruckus.vivadoVersionunder the usual install roots).
The command never changes existing settings or tasks. It only adds missing keys and tasks with new labels, so you can run it again after you add a submodule. If a file contains comments, the command does not rewrite it. Instead, it opens the proposed entries in an editor so you can merge them by hand.
You can also write ruckus tasks by hand. dir and args support
${workspaceFolder}, ${topDir}, ${targetDir}, ${file} and
${fileBasenameNoExtension}. An ${input:...} argument is passed to the
shell without quotes, so a prompt can hold several VAR=value words:
{
"label": "xsim this file",
"type": "ruckus",
"target": "xsim",
"dir": "${workspaceFolder}/firmware/targets/MyTarget",
"args": ["VIVADO_PROJECT_SIM=${fileBasenameNoExtension}", "${input:ruckusMakeVars}"],
"group": "test"
}
Settings
Setting |
Default |
Description |
|---|---|---|
|
|
Tcl shell used for the scan |
|
(empty) |
Script sourced before |
|
|
Source |
|
(empty) |
Vivado version for the setup script and scan |
|
(empty) |
Vivado install used for |
|
|
Extra variables for the scan, e.g.
|
|
|
Copy make output to |
|
|
Depth of the hierarchical utilization report |
|
|
Vivado simulator for Simulate Current File |
|
bit, … |
Order of the Common make targets |
|
hierarchy |
Sources view grouping |
|
|
Show |
Limitations
Logic that depends on real Vivado state, such as
get_filesresults or IP properties, evaluates as empty during the scan.$(shell ...)in Makefiles is not executed.To scan a different branch of a conditional
ruckus.tcl, override variables withruckus.env.
Maintaining the Extension
The scanner vscode-plugin/resources/ruckus_scan.tcl replaces every public
loader procedure with a recorder. When you add a loader procedure or option
to vivado/proc/code_loading.tcl, add the same procedure or option to the
scanner in the same change. Otherwise the extension reports
unknown option warnings or misses files. When you add a make target that
needs a description, add it to RUCKUS_TARGET_DOCS in
vscode-plugin/src/core/project.ts.
Development commands, run in vscode-plugin/:
npm install
npm run compile # or: npm run watch
npm test # unit tests on test/fixtures/ (also run by CI)
node out/test/smoke.js <target dir> # print the project model, no VS Code needed
npm run test:vscode -- <firmware dir> # integration test inside VS Code
To start an Extension Development Host, open vscode-plugin/ in VS Code
and press F5.