VHDL (GHDL) — Highlight, Debug, Signals
A VS Code extension for VHDL built around GHDL:
- 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.

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 to Next Simulation Time (Ctrl+F10) |
advances to the next time with activity |
| Run Simulation For… |
advances by a duration such as 100 ns |
| 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": "VHDL: 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
VHDL: 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.
- VHDL: 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 VHDL: 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 subscription, $5 a month, after a 14-day trial that starts with the
first use. Subscribe in the viewer opens the checkout in your browser; the
license key that arrives by email goes into the field below it, or into VHDL:
Enter Signal Viewer License Key. Keys are verified offline, so the viewer
works without a connection. VHDL: Manage Signal Viewer Subscription shows the
state of the subscription.
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
npm test # end-to-end: real GHDL + GDB + agent, driven over the Debug Adapter Protocol
F5 in this folder starts an Extension Development Host on
examples/counter. The architecture is described in docs/DESIGN.md.
| |