ROHD VS Code ExtensionA VS Code extension for the ROHD hardware design framework. It provides context-aware Dart code snippets, cross-probe source navigation from ROHD viewers (schematic, waveform), and automatic port-forwarded URI display for the Dart Tooling Daemon (DTD) and VM Service. Features
On activation the extension prints:
SnippetsSnippets are registered for Dart files. Open a VS Code does not always expand snippets from
The extension also has context-aware completion snippets, such as showing
After changing extension settings or installing a new VSIX, reload the VS Code window with Developer: Reload Window. Static snippetsThese snippets are contributed by VS Code's snippet system. Context-aware completions below narrow the ROHD-specific options by cursor location.
Context-aware — file scopeThese appear only at file/top level (not inside a function or class body).
Context-aware — module body scopeThese appear when the cursor is inside a
Context-aware — inside
|
| Prefix | Expands to | Description |
|---|---|---|
If |
If(cond, then: […], orElse: […]) |
Inline if/else (most common) |
ifthen |
If(cond, then: […]) |
Simple conditional guard |
ifnested, iforelse |
If(a, then: …, orElse: [If(b, …)]) |
Nested if / else-if / else chain |
If.block, ifblock |
If.block([Iff(…), ElseIf(…), Else(…)]) |
Flat if/else-if/else block chain |
Iff, iff |
If.block([Iff(…), ElseIf(…), Else(…)]) |
Complete if/elseif/else block using Iff as the first clause |
Else, else |
Else([…]) |
Final clause in If.block |
Case |
Case(expr, [CaseItem(…)], …) |
case / unique case / priority case |
CaseZ, casez |
CaseZ(expr, [CaseItem(…)]) |
Don't-care matching with z syntax |
CaseItem, caseitem |
CaseItem(value, […]) |
Single arm inside Case/CaseZ |
assign |
out < expr, |
Conditional assignment (inside _Always) |
Note: bare
Iff(two f's) is not a standalone conditional. It is the first entry in anIf.block([…])chain. TheIffsnippet expands to the fullIf.blockform so it can be inserted directly insideSequentialorCombinational.
Context-aware — test/ directory
These appear only in Dart files under a test/ directory.
| Prefix | Expands to | Description |
|---|---|---|
test, Test |
test('description', () async { … }) |
Async package:test case |
group, Group |
group('description', () { test(…) }) |
Test group with an async test inside |
tearDown, resetTest |
tearDown(() async { await Simulator.reset(); }) |
Reset ROHD simulation state between tests |
rohdtest, simtest, testsim |
Clock/reset/DUT build/Simulator.run() scaffold |
ROHD simulation test flow based on common ROHD-HCL tests |
FLC Cross-Probing
FLC (File, Line, Column) data maps every signal and submodule in the generated output back to the Dart source location where it was constructed. The extension uses FLC data to navigate from a schematic or waveform viewer directly to the ROHD Dart source.
FLC JSON Format (v6)
An .flc.json file uses a shared ROHD source file table plus a per-module
trie of source frames. Each trie leaf is a compact symbol string for a
signal or submodule instance:
{
"version": 6,
"files": [
"lib/src/my_module.dart",
"lib/src/modules/gates.dart"
],
"modules": {
"Top": {
"outputFiles": {
"sv": ["Top.sv"],
"sc": ["Top.cpp"]
},
"tree": [
[
"0:6:20",
["0:15:9", "a@sv:2:19,8:7;sc:44:5"],
["0:16:15", "b@sv:3:20~originalB"],
["1:22:3", "*inner@sv:7:1"]
]
]
}
}
}
version— v6 is the current format. The extension can still parse v5; other explicit versions are rejected.files— array of ROHD source paths, indexed by the first number in each trie frame.outputFiles— map from output language to generated file list, for example"sv": ["Top.sv"]or"sc": ["Top.cpp"]. The first file for each language is the canonical lookup target.tree— list of trie root nodes. Each node starts with a source frame string, then contains child nodes and/or symbol strings that share that source-frame prefix."0:15:9"— ROHD source frame: file index 0, line 15, column 9. The column is optional and defaults to 1."a@sv:2:19,8:7;sc:44:5"— signala, with two SystemVerilog output positions and one SystemC output position. Output-language groups are separated by semicolons; entries within one language are separated by commas. The language tag appears on the first entry in the group, sosv:2:19,8:7meanssv:2:19andsv:8:7."b@sv:3:20~originalB"— canonical signal nameb, original source nameoriginalB. Lookups may use either name."*inner@sv:7:1"— submodule instanceinner. Instance symbols are prefixed with*; signal symbols are not.
Source frames accumulate along the trie path from outermost to innermost. When the extension opens ROHD source frames, it presents them innermost first so the construction site closest to the signal or instance is selected first.
Commands
| Command | Title |
|---|---|
rohd.openSourceLocation |
Go to Source Location |
rohd.openSourceLocations |
Go to Source Locations (multi-frame) |
rohd.nextSourceLocation |
Next Source Frame |
rohd.prevSourceLocation |
Previous Source Frame |
rohd.connectDtd |
Connect to Dart Tooling Daemon |
rohd.showForwardedUris |
Show Forwarded DTD/VM URIs |
Settings
| Setting | Default | Description |
|---|---|---|
rohd.enableCompletions |
true |
Enable context-aware ROHD completions. Set false to disable the provider. |
rohd.dtdUri |
"" |
WebSocket URI of the Dart Tooling Daemon. Leave empty for auto-discovery. |
Prerequisites
Node.js >= 22 for the pinned VSIX packaging tool (CI uses Node 24):
nvm install nvm use node --versionnpm (comes with Node)
Build
cd rohd_extension
npm ci
npm run compile # produces out/extension.js
Local Installation
Package as VSIX
cd rohd_extension
npm run package
This produces rohd-0.1.0.vsix.
Install
code --install-extension rohd-0.1.0.vsix --force
Then reload the VS Code window (Developer: Reload Window).
One-liner (build + install)
cd rohd_extension \
&& npm ci \
&& npm run package \
&& code --install-extension rohd-0.1.0.vsix --force \
&& echo "Done — reload the VS Code window to activate."
Remote Installation (Dev Containers / SSH)
Extensions that interact with the Dart debug adapter must be installed on the remote side (inside the container or on the SSH host).
Option 1: devcontainer.json (recommended)
Place the extension source in your repo and build it on container creation:
// .devcontainer/devcontainer.json
{
"postCreateCommand": "cd rohd_extension && npm ci && npm run package && code --install-extension rohd-0.1.0.vsix --force"
}
Option 2: Pre-built VSIX
Build the .vsix on your host or in CI, then install at container start:
{
"postStartCommand": "code --install-extension rohd_extension/rohd-0.1.0.vsix --force"
}
Option 3: Install via CLI while connected
code --install-extension rohd-0.1.0.vsix --force
The code CLI inside a remote session targets the VS Code Server
automatically.
Option 4: Install via VS Code UI
- Connect to the remote host / container.
- Open Extensions (
Ctrl+Shift+X). - Click
...→ Install from VSIX... and select the.vsixfile. - Reload the window.
Option 5: Copy directly into .vscode-server/extensions/
If the code CLI is not available (e.g. in a Dockerfile RUN step):
mkdir -p ~/.vscode-server/extensions/rohd.rohd-0.1.0
cp -r rohd_extension/{package.json,out,snippets,resources} \
~/.vscode-server/extensions/rohd.rohd-0.1.0/
The directory name must follow the pattern <publisher>.<name>-<version>.
File Structure
rohd_extension/
├── package.json # Extension manifest
├── tsconfig.json # TypeScript configuration
├── src/
│ ├── extension.ts # Entry point — activates all modules
│ ├── source_navigator.ts # Cross-probe → editor navigation
│ ├── dtd_bridge.ts # DTD JSON-RPC bridge
│ ├── debug_tracker.ts # Debug adapter tracker (DTD/VM URIs)
│ └── conditional_completions.ts # Context-aware conditional snippets
├── out/ # Compiled JS (generated)
├── snippets/
│ └── rohd.json # ROHD Dart snippets
└── resources/
└── rohd_icon.png # Extension icon
License
BSD-3-Clause — see the repository root LICENSE file.