Soft Forge HDL Studio
VHDL development on GHDL and Vivado: highlighting, a debugger that steps through processes and through simulation time in both directions, a signal viewer for live simulations and GHW/VCD files, a Vivado flow and a block design editor. This is a VS Code extension built around GHDL; today (0.1.0) it provides:
- Syntax highlighting in Aurora, the palette of
<code-preview>, plus the
matching editor theme, snippets, indentation and folding.
- Debugging: source breakpoints and stepping inside processes, and
simulation-time control — pause, step to the next time step, run for a
duration, break when a signal changes, break on assertion failures.
- Signal viewer, drawn with WebGL: every signal of the elaborated design,
streamed in realtime while the simulation runs — and the same viewer for
GHW and VCD waveform files, with enumerations, integers, reals and
analog traces.

Features
- Workspace dashboard: a
<name>.hdl-workspace file opened as a settings-like page (sources, testbenches, top, part, board, toolchains); F5 runs the default testbench.
- Debugger on GHDL + GDB with simulation-time control, run-for, step time, data breakpoints, and time travel: step back, reverse continue and Run Back To (restart and run forward, ~0.1 s on the examples).
- Signal viewer (Pro): WebGL waveforms of the live simulation and of
.ghw / .vcd files, cursor, debugger marker, future shading, radix, analog rows.
- Vivado flow: synthesis, implementation, bitstream and xsim as VS Code tasks with a Flow view, reports (WNS, utilisation, DRC) and a Hardware view that programs the board through
hw_server.
- Block design editor:
.vbd event-log files, an SVG canvas, validation, ELK layout, VHDL wrapper and Vivado export.
hdl command line on the terminal PATH (--json everywhere), a bridge to the running session, a Claude skill (hdl skill --install) and language model tools.
- Subscription: the signal viewer is part of HDL Studio Pro ($35 per seat per month) after a 30-minute trial; everything else is free.
Quick start
- Open a folder with your VHDL sources (try
examples/counter).
- Open the testbench and press F5 — or click Debug Current File as
Testbench in the editor title. No
launch.json is needed: the extension
analyses every *.vhd/*.vhdl of the folder and elaborates the entity of
the open file.
- The simulation pauses at 0 fs and the signal viewer opens beside the editor.
Set breakpoints, press Continue, or type
run 100 ns in the Debug Console.
Requirements
| Tool |
Needed for |
| GHDL, any backend, with VPI |
everything |
A C compiler (gcc) |
building the debug agent, once per work directory |
| GHDL GCC or LLVM backend + GDB |
source breakpoints, stepping, call stacks |
With the mcode backend you still get the signal viewer and every
simulation-time feature; only source-level debugging is unavailable, because
mcode produces no executable for GDB to drive.
Debugging
| Action |
What it does |
| Breakpoint in a process or subprogram |
stops there; supports conditions and hit counts |
| Step Over / Into / Out |
sequential statements; leaving a process moves to the next time step |
| Step Time (Ctrl+F10, debug toolbar) |
advances to the next time with activity, or by the step set with HDL Studio: Set Step Time… |
| Run For… (Ctrl+Shift+F11, debug toolbar) |
advances by a duration such as 100 ns |
| Step Back (Ctrl+Shift+F10) and HDL Studio: Run Back To… |
rewinds a recorded session |
| Variables → Signals |
the design hierarchy with current values; edit a value to deposit it |
| Variables → right-click a signal → Break on Value Change |
a data breakpoint; give it a condition such as x"5" to stop on that value only |
| Breakpoints → Assertion Failures |
stops where an assert fails, with the failing line on top of the stack |
| Hover / Watch |
any signal name, or a hierarchical suffix such as dut.value |
Debug Console commands: run <time>, step, force <signal> <value>,
gdb <command>, help.
launch.json
{
"type": "ghdl",
"request": "launch",
"name": "HDL Studio: counter_tb",
"top": "counter_tb", // entity to simulate
"files": ["src/**/*.vhdl", "tb/*.vhdl"], // paths or globs; GHDL orders the analysis
"std": "08",
"ghdlArgs": ["-fsynopsys"], // analysis / elaboration options
"simArgs": ["--assert-level=error"], // run-time options
"stopTime": "1 ms",
"stopOnEntry": true
}
Building with CMake
With cmake-language-vhdl
a testbench is an ordinary add_executable(). Let CMake build it and point
program at the result instead of listing files; the Debug build type
passes -g, which source breakpoints need:
{ "type": "ghdl", "request": "launch", "name": "dds_tb (CMake)",
"top": "dds_tb", "program": "${workspaceFolder}/build/dds_tb",
"preLaunchTask": "cmake: build" }
examples/cmake is a complete project: CMakeLists.txt,
presets for an installed package or a checkout next to this repository, the
tasks and launch configurations, and a waves target that leaves
build/dds_tb.ghw and build/dds_tb.vcd to open in the viewer.
Signal viewer
HDL Studio: Open Signal Viewer, or automatically with each session.

- The left pane is the design hierarchy; expanding a scope adds its signals.
- Ctrl+wheel zooms around the pointer, Shift+wheel or drag pans, double-click zooms in.
- Click places the cursor: values in the left pane are those at the cursor.
←/→ jump between edges of the selected signal, Esc removes the cursor.
- F fits the whole run, L toggles Live (follow the simulation).
- Double-click a signal name to deposit a value. VCD exports the recording for GTKWave.
- HDL Studio: Simulate Current File with Live Signals runs without the debugger.
- A, or the ∿ next to a name, turns the selected signal into an
analog trace: off, steps, lines. Vectors are read as unsigned, or as two's
complement with the signed radix.
Open a .ghw or .vcd file — from the explorer, or with HDL Studio: Open Waveform
File — and it shows in the same viewer. The file is watched: simulate again
and the view follows, keeping its zoom and the expanded scopes.
|
GHW (--wave=file.ghw) |
VCD (--vcd=file.vcd) |
| Bits and vectors |
yes, with the VHDL type (signed vectors plot as signed) |
yes |
| Integers, reals |
yes |
integers as 32-bit vectors, reals |
| Enumerations, booleans, physical values |
yes, by name |
no |
| Records, arrays of vectors |
yes, as expandable groups |
no |
| Strings |
yes |
no |
| Written by |
GHDL |
any simulator |
Prefer GHW for a GHDL design: it is what makes a state machine readable. A GHW
can be gzipped. Add either option to simArgs of a launch configuration to
record while debugging.
Subscription
Highlighting, the theme, snippets and the debugger are free. The signal viewer
is a monthly subscription, after a 30-minute trial that starts the first time a
viewer opens. HDL Studio: See Plans (Client Portal) opens the plans in your
browser; HDL Studio: Sign In to Soft Forge uses the account's plan, and a
license key from an email goes into HDL Studio: Enter License Key…. Keys are
verified offline, so the viewer works without a connection. HDL Studio: Manage
Subscription shows the state of the subscription (docs/licensing.md).
Limits
- Signals are read through GHDL's VPI, which exposes bits,
std_logic,
booleans and vectors of them. Integers, reals, enumerations and records do
not appear (GHDL's VCD writer has the same view of the design).
- Process variables are shown raw, as GDB sees them; GHDL's DWARF does not
describe VHDL types.
- Linux and macOS (the agent talks over a unix socket).
- The viewer needs WebGL 2, which every VS Code build has. Times are exact up to
2^53 time units: about nine seconds of simulated time at GHDL's 1 fs, beyond
which edges are placed to the nearest representable time.
Development
npm install
npm run compile # tsc into out/, then esbuild bundles out of src/ into dist/ (with source maps)
npm test # end-to-end: real GHDL + GDB + agent, driven over the Debug Adapter Protocol
npm run package # the vsix: minified, obfuscated bundles, checked by scripts/check-package.cjs
F5 in this folder starts an Extension Development Host on
examples/counter. The extension runs from dist/ (main), which npm run compile
rebuilds from the TypeScript sources; out/ is the tsc output the unit tests, the e2e
and npm run dev use, and the webview pages load as plain modules from media/. The
package replaces the bundles with obfuscated ones and the pages with media/dist/index.js
(see docs/architecture.md §7), so a published vsix carries no readable
source. The architecture is described in docs/DESIGN.md.
| |