Waveform Viewer (rb wave)
Integration type: Integrated tool.
rb waveis built around Surfer today; Vaporview / VS Code support is on the roadmap — tracked in issue #84.External binary required: Surfer, built from the
rtl-buddy/surferfork on thertl-buddybranch. Mainline Surfer works for basic FST viewing but not for WCP signal-value annotation. See Surfer build.Editor integration: nvim for the full annotation round-trip (declaration jump + live signal values + add-from-editor). Any editor can be configured via
editor-cmdfor one-way "open at line".See also: Installation — External tools by feature.
rb wave opens the Surfer waveform viewer for a test and connects it to your editor via the WCP (Waveform Client Protocol). When you right-click a signal in Surfer and choose Go to declaration, rtl-buddy:
- Resolves the signal to its source file and line number
- Opens (or reuses) your editor at that location
- Annotates the signal's waveform value at the current cursor position as inline virtual text
Basic usage
cd verif/sandbox
uv run rb wave basic # runs debug sim if no FST exists, then opens Surfer
uv run rb wave basic --resim # force re-run of debug sim
Signal layout files are loaded automatically: if basic.surfer exists next to tests.yaml, Surfer opens with those signals pre-loaded.
Configuration
Add a cfg-surfer section to root_config.yaml:
cfg-surfer:
- name: "surfer-default"
path: "../surfer/target/release/surfer" # or bare name on PATH
wcp-port: 0 # 0 = OS assigns a free port
editor-cmd: "nvim +%l %f" # %f = file, %l = line
editor-terminal: "tmux" # tmux | iterm2 | terminal | ""
editor-sock: "~/.local/share/rtl-buddy/wave-nvim.sock" # enables nvim reuse
ctrl-sock: "~/.local/share/rtl-buddy/wave-ctrl.sock" # enables nvim → Surfer
See YAML Formats for all fields.
Signal value annotation
How it works
When a goto_declaration event arrives from Surfer, rtl-buddy:
- Reads the signal value at the cursor timestamp from the FST via pywellen
- Enumerates all other signals in the same module scope using the FST hierarchy
- Runs a single bulk grep across the SV source files to map every signal to its declaration line (result cached for the session)
- Pushes all values to the editor as EOL virtual text
Moving the Surfer time cursor fires a cursor_moved WCP event, which re-reads all scope signal values and updates the annotations live — no interaction required.
Two signals declared on the same source line are combined into one annotation:
logic a, b; ▶ a=8'h0a b=8'h05 [i_dut]
logic clk; ▶ 1'b0 [i_dut]
Active scope
Clicking any signal in Surfer's signal list sets the active scope — the module instance used to resolve signal names. rtl-buddy updates the scope cache automatically via the scope_changed WCP event, so annotation context is always current without requiring a "Go to declaration".
nvim setup
The annotation feature requires a small nvim plugin. Install it once:
rb wave-install-nvim
This copies rtl_buddy_wave.lua to ~/.local/share/nvim/site/plugin/, which nvim auto-sources at startup. No init.lua changes are needed. Reinstall after rtl-buddy upgrades with --force:
rb wave-install-nvim --force
If the plugin is missing when rb wave starts with editor-sock configured, a warning is shown:
WARNING nvim plugin not installed — run "rb wave-install-nvim" to enable wave annotations
Adding signals to Surfer from nvim
With ctrl-sock configured, place the cursor on any signal name in nvim and press <Space>wa (<leader>wa) to add it to Surfer's waveform view.
The signal is resolved using the active scope — click a signal in Surfer first to establish the instance context (e.g. clicking tb_top.i_dut.clk sets scope tb_top.i_dut), then add signals freely from nvim.
nvim: cursor on "rst" → <Space>wa → Surfer adds tb_top.i_dut.rst to waveform
The keymap requires ctrl-sock to be set in cfg-surfer and rb wave to be running. A warning is shown if the socket is unreachable.
Single-signal mode
To annotate only the signal you right-clicked (not the whole scope):
uv run rb wave basic --focused-signal
Editor socket reuse
When editor-sock is set, rtl-buddy launches nvim with --listen <sock> on first use. Subsequent goto_declaration and cursor_moved events reuse the running instance via --remote-expr nvim_exec2(...) — no new windows, no command-line flicker.
The socket is probed with a 300 ms timeout. If the socket is stale (nvim has been closed), the next goto_declaration opens a fresh nvim window.
Surfer build
The annotation features require Surfer built from the rtl-buddy branch:
git clone https://github.com/rtl-buddy/surfer.git ../surfer
cd ../surfer && git checkout rtl-buddy
cargo build --release
Point cfg-surfer.path at ../surfer/target/release/surfer (relative to root_config.yaml) or install the binary on PATH.