What Is Verdi and Why It's the Industry Standard
Verdi (formerly by SpringSoft, acquired by Synopsys) is the debug platform used in virtually every professional ASIC tape-out flow. Where a generic waveform viewer shows you what a signal's value is, Verdi shows you why — tracing causality backward through logic, time, and clock domains to the exact root cause of a bug.
Launch Commands — Every Variant You Need
# Minimal: just open FSDB (no cross-probe, no schematic)
verdi -ssf sim_dump.fsdb &
# With RTL sources — enables full cross-probe to source code
verdi -sverilog -f flist.f -ssf sim_dump.fsdb &
# With KDB (fastest; reuses compiled design database)
verdi -kdb sim.kdb -ssf sim_dump.fsdb &
# Specify top module explicitly
verdi -sverilog design.v tb.v -top tb_top -ssf sim_dump.fsdb &
# Restore a saved session (loads signals, groups, radix)
verdi -ssf sim_dump.fsdb -nologo -play wave_session.tcl &
# Open with multiple FSDB files (compare runs side-by-side)
verdi -ssf run1.fsdb run2.fsdb &
# Batch mode — run Tcl script without GUI (for CI/automation)
verdi -batch -play check_signals.tcl -ssf sim_dump.fsdb
~/.bashrc or ~/.tcshrc:alias vd='verdi -kdb sim.kdb -ssf sim_dump.fsdb -play wave_session.tcl &'One command to instantly re-open your last debug state.
FSDB Setup — Getting the Right Waveform Data
FSDB (Fast Signal DataBase) is Synopsys's waveform format. Compared to VCD, it is 5–10× smaller, supports incremental loading (view while sim runs), and uniquely supports multi-dimensional arrays, SVA results, and UVM transactions. Always prefer FSDB over VCD when using VCS + Verdi.
Step 1 — Compile with FSDB PLI support
vcs -full64 -sverilog \
-debug_access+all \ # enables full signal visibility
-kdb \ # build knowledge database for Verdi
-lca \ # required for KDB
-P $VERDI_HOME/share/PLI/VCS/LINUX64/novas.tab \
$VERDI_HOME/share/PLI/VCS/LINUX64/pli.a \
-f flist.f \
-o simv
Step 2 — Add FSDB dump calls to testbench
initial begin
// Basic: dump all signals from tb_top downward, all hierarchy
$fsdbDumpfile("sim_dump.fsdb");
$fsdbDumpvars(0, tb_top); // 0 = all levels of hierarchy
// Dump multi-dimensional arrays (memories, packed arrays)
$fsdbDumpMDA();
// Dump SVA assertion pass/fail events
$fsdbDumpSVA();
// Dump interface signals (SystemVerilog interfaces)
$fsdbDumpvars(0, tb_top.u_axi_if);
// Optional: stop dumping after N ns to limit file size
#5_000_000;
$fsdbDumpoff;
end
// Selective scope dump — only signals under dut, 1 level deep
initial begin
$fsdbDumpfile("dut_only.fsdb");
$fsdbDumpvars(1, tb_top.u_dut); // 1 = top level of u_dut only
end
$fsdbDumpvars, use $fsdbDumpoff/$fsdbDumpon to pause during idle time, and use depth=1 for modules you only need to inspect at the top level.FSDB vs VCD at a Glance
| Feature | FSDB | VCD |
|---|---|---|
| File size | 5–10× smaller | Large |
| Multi-dim arrays | $fsdbDumpMDA | Not supported |
| SVA results | $fsdbDumpSVA | Not supported |
| UVM transactions | Supported | Not supported |
| Incremental load | Yes (view while simulating) | No |
| Reload in Verdi | Fast | Slow |
nWave — Mastering the Waveform Viewer
nWave is Verdi's primary waveform window. Most engineers know how to scroll and zoom — here's everything else.
Adding Signals
- Drag signals from the Signal panel (left side) into nWave
- Right-click in nWave → Get Signals → type a hierarchical path
- Type partial signal name in the Signal panel search bar to filter
- Drag a scope/module from the hierarchy to add all its signals at once
Signal Groups
- Signal → New Group — creates a collapsible group with a label
- Drag signals into a group to organize by function (clocks, data, status)
- Right-click group → Collapse/Expand — keeps nWave clean during long sessions
- Groups are saved in
wave_session.tcl— Ctrl+W to save
Radix & Display Format
| Right-click → Radix | What it shows |
|---|---|
| Hex | Default for buses — compact, shows all bits |
| Dec / Signed Dec | Unsigned or 2's complement integer value |
| Bin | Full bit-by-bit view — good for small buses |
| Oct | Octal — useful for 3-bit groups |
| ASCII | Text view — perfect for byte streams and UART data |
| Analog | Draws as a line graph — great for ADC outputs and counters |
Cursors & Markers
- Primary cursor: Click anywhere on the waveform
- Delta cursor: Shift+Click — shows time difference from primary
- Add marker: Ctrl+M — name it (e.g. "TX_START") for later reference
- Jump to marker: Ctrl+Shift+M cycles through markers
- Markers are saved with the session — use them to bookmark key events
Zoom Controls
- F — fit entire simulation in view
- Z — zoom in at cursor position
- z or Shift+Z — zoom out
- Ctrl+← / Ctrl+→ — jump to previous/next edge of selected signal
- Type a time value directly in the zoom bar (top) to go to exact timestamp
Temporal Flow View — Root-Cause Debug in Seconds
TFV is Verdi's most powerful feature and the one most engineers underuse. It answers the question "This signal is wrong — what drove it to this value, through what logic, starting when?" automatically.
How to Open TFV
TFV for X-Propagation Debug
X-propagation is one of the most common RTL bugs — an undefined value spreads through the design and corrupts output. TFV makes tracing it mechanical:
- Find a signal driven to X — right-click → Trace X Value
- TFV shows the exact gate whose output is X, and all its inputs at that time
- Common sources: uninitialized register at reset, missing
defaultincase, multi-driver conflict, interface not driven during idle - TFV annotates each source with color: red = X, green = 0/1
TFV for CDC Debug
When a signal crosses a clock domain and its synchronized value is wrong, TFV traces backward through the synchronizer flip-flop chain to the original source domain — across the asynchronous boundary — to show exactly which source-domain value was (or wasn't) captured.
Cross-Probing — Waveform ↔ Source ↔ Schematic
Cross-probing is what turns Verdi from a waveform viewer into a full debug environment. Any click in one window instantly highlights the corresponding element in all other open windows.
| Action in… | Result in… |
|---|---|
| Click signal name in nWave | nTrace highlights the RTL assignment driving the signal |
| Click a net in nSchema | nWave highlights that signal; nTrace shows its RTL |
| Click a line in nTrace (source) | nWave highlights the signal; nSchema shows it in context |
| Right-click signal → "Find in Source" | nTrace opens at the exact assignment or port declaration |
| Right-click signal → "Show in Schema" | nSchema opens with the signal's gate/RTL context |
-sverilog -f flist.f) or a KDB (-kdb sim.kdb) for cross-probe to work. Without source, only waveform viewing is available.nTrace — Source Code Viewer
- Shows the RTL source with syntax highlighting
- The active line (driving the cross-probed signal) is highlighted
- Click a module instantiation → jumps to that module's definition
- Ctrl+F to search across all source files
- Annotates signal values at cursor time directly in the source margin
nSchema — Schematic View
nSchema renders your RTL or gate-level netlist as an interactive schematic, with all nets annotated with their values at the current cursor time. It's the fastest way to understand unknown logic without reading code.
- Open: Tools → nSchema, or right-click a signal → "Show in Schema"
- Active value overlay: every net shows its value (0/1/X/Z) at the cursor time — no need to switch to nWave
- Trace forward: right-click a net → "Trace Forward" — follows logic toward outputs
- Trace backward: right-click → "Trace Backward" — follows logic toward inputs
- Hierarchy navigation: double-click a module to descend into it
- Highlight path: select start and end net → "Highlight Path" — marks all logic between them
UVM Transaction Debug
For UVM testbenches, Verdi can display transactions as bars in nWave — above the raw signal waveforms — showing what protocol traffic occurred, at what time, with all field values visible on click.
Enable Transaction Recording in UVM
// In test or env: enable recording for all components
uvm_config_db#(uvm_object_wrapper)::set(
this, "*", "recording_detail", UVM_FULL);
// In driver/monitor: record each transaction
task run_phase(uvm_phase phase);
my_seq_item txn;
forever begin
seq_item_port.get_next_item(txn);
void'(begin_tr(txn, "my_driver")); // start transaction record
drive_item(txn);
end_tr(txn); // end transaction record
seq_item_port.item_done();
end
endtask
// In testbench top: add transaction FSDB recording
initial begin
$fsdbDumpfile("sim_dump.fsdb");
$fsdbDumpvars(0, tb_top);
$fsdbDumpon;
// UVM transaction bars appear automatically in nWave
end
Using Transaction Debug in nWave
- Transaction bars appear as colored horizontal bars above signal waveforms
- Click a transaction bar → a panel shows all field values (addr, data, strb, resp…)
- Filter by type: right-click transaction row → Filter → select specific transaction types
- Sequence viewer: Tools → Sequence Viewer — shows the ordering and nesting of sequences
- Color by field: color-code transactions by response type or error status for instant scan
Tcl Automation — Script Your Debug Setup
Every action in Verdi's GUI can be scripted in Tcl. The killer workflow: write a wave_session.tcl that loads all your key signals with groups and radix settings, then launch Verdi with -play wave_session.tcl. Instant consistent debug environment every run.
## wave_session.tcl — auto-generated session for tb_top
# ── Clocks & Reset ───────────────────────────────────────────────
wvCreateGroup -win $_nWave0 "Clocks & Reset"
wvGetSignal -win $_nWave0 {tb_top.clk}
wvGetSignal -win $_nWave0 {tb_top.rst_n}
wvSetColor -win $_nWave0 -signal {tb_top.clk} -color yellow
# ── AXI Master Interface ─────────────────────────────────────────
wvCreateGroup -win $_nWave0 "AXI Write Address"
wvGetSignal -win $_nWave0 {tb_top.awvalid}
wvGetSignal -win $_nWave0 {tb_top.awready}
wvGetSignal -win $_nWave0 {tb_top.awaddr[31:0]}
wvSetRadix -win $_nWave0 -signal {tb_top.awaddr[31:0]} -hex
wvCreateGroup -win $_nWave0 "AXI Write Data"
wvGetSignal -win $_nWave0 {tb_top.wvalid}
wvGetSignal -win $_nWave0 {tb_top.wready}
wvGetSignal -win $_nWave0 {tb_top.wdata[31:0]}
wvGetSignal -win $_nWave0 {tb_top.wstrb[3:0]}
wvSetRadix -win $_nWave0 -signal {tb_top.wdata[31:0]} -hex
wvSetRadix -win $_nWave0 -signal {tb_top.wstrb[3:0]} -bin
# ── DUT Internal State ───────────────────────────────────────────
wvCreateGroup -win $_nWave0 "DUT State Machine"
wvGetSignal -win $_nWave0 {tb_top.u_dut.state[3:0]}
wvSetRadix -win $_nWave0 -signal {tb_top.u_dut.state[3:0]} -dec
# ── Zoom and go to start ─────────────────────────────────────────
wvZoomFull -win $_nWave0
wvGoToTime -win $_nWave0 0ns
# Save after loading (so -play wave_session.tcl + Ctrl+W works)
# wvSaveFile -win $_nWave0 -file wave_session.tcl
Essential Tcl Commands
| Command | What it does |
|---|---|
| wvOpenFile -win $_nWave0 dump.fsdb | Load an FSDB file into nWave |
| wvCloseFile -win $_nWave0 | Close current FSDB (before reload) |
| wvGetSignal -win $_nWave0 {path.sig} | Add a signal to nWave |
| wvCreateGroup -win $_nWave0 "Label" | Create a collapsible group |
| wvSetRadix -win $_nWave0 -signal {sig} -hex | Set radix: -hex / -dec / -bin / -oct / -ascii |
| wvSetColor -win $_nWave0 -signal {sig} -color yellow | Set signal color |
| wvZoomFull -win $_nWave0 | Fit all waveforms in view |
| wvGoToTime -win $_nWave0 500ns | Move cursor to timestamp |
| wvAddMarker -win $_nWave0 1000ns "TX_START" | Add a named marker |
| wvSaveFile -win $_nWave0 -file wave.tcl | Save current layout as Tcl script |
| wvSelectSignal -win $_nWave0 {sig} | Select a signal (for batch ops) |
wave_session.tcl.Keyboard Shortcuts — Complete Cheat Sheet
nWave Navigation
Signal Management
Debug & Cross-Probe
Pro Tips — What Most Engineers Never Discover
1. Reload FSDB Without Restarting Verdi
After a re-run, you don't need to close and reopen Verdi. Use F5 or File → Reload FSDB. Your signal groups, radix, colors, and markers are preserved. In Tcl:
wvCloseFile -win $_nWave0
wvOpenFile -win $_nWave0 sim_dump.fsdb
2. Delta Cycle View for Reset Debug
At time 0, many signals transition in the same simulation timestep through delta cycles. Enable View → Show Delta Cycle to see these sub-step transitions — essential for debugging X→0 initialization issues at reset release.
3. KDB Reuse Across Sessions
The KDB (sim.kdb/ directory) is generated once during compile. Reuse it without recompiling by launching: verdi -kdb sim.kdb -ssf new_dump.fsdb. Only recompile when RTL changes.
4. Value Change Search
Instead of scrolling to find when a signal changed: right-click the signal → Search Value Change → specify direction and value. Verdi jumps cursor to the next transition matching your criteria. Critical for finding the first assertion of an error flag in a long simulation.
5. Compare Two Simulation Runs
Load two FSDB files simultaneously: verdi -ssf run1.fsdb run2.fsdb. Both sets of signals appear in the signal panel — add corresponding signals from each run into adjacent rows in nWave to visually diff behavior between a passing and failing simulation.
6. Annotate RTL with Simulation Values
In nTrace (source viewer), go to View → Annotate Values. Every signal declaration in the source file is annotated with its value at the current cursor time — like a live linting of your RTL with actual runtime data.
7. Assertion Debug with $fsdbDumpSVA
When you dump SVA results with $fsdbDumpSVA(), assertion pass/fail events appear as special markers in nWave. Click a failing assertion marker → TFV shows exactly what signal violated the property and when.
FAQ
FSDB is Synopsys's proprietary waveform format — 5–10× smaller than VCD, supports multi-dimensional arrays ($fsdbDumpMDA), SVA assertion pass/fail events ($fsdbDumpSVA), and UVM transaction data. FSDB also supports incremental loading, so Verdi can display waveforms while simulation is still running. Always prefer FSDB when using VCS + Verdi; use VCD only when sharing waveforms with tools that don't support FSDB.
TFV is Verdi's root-cause debug engine. Place your cursor at the bad timestamp, right-click the suspicious signal, and select "Trace X Value" (for X) or "Show Driver" (for 0/1). Verdi opens a flow diagram showing the entire logic cone that produced the bad value — working backward through gates and flip-flops, across clock cycles, to the original source. Click any node to trace further. It's the fastest way to find X propagation sources and unexpected logic values.
Press F5 or use File → Reload FSDB. In Tcl: wvCloseFile -win $_nWave0 then wvOpenFile -win $_nWave0 sim_dump.fsdb. Your signal groups, radix, colors, and markers remain intact. A common workflow: have a shell alias that re-runs the simulation and sends a Tcl reload command to the running Verdi session.
KDB (Knowledge DataBase) is a compiled design representation stored to disk by VCS when you pass -kdb at compile time. Instead of re-parsing RTL source files every time you open Verdi, you point to the KDB with verdi -kdb sim.kdb for instant startup. KDB also enables better cross-probe accuracy and is required for some advanced Verdi features like formal result viewing. Recompile KDB only when RTL changes; reuse it across all debug sessions for the same build.
Use depth-limited scope dumps: $fsdbDumpvars(1, tb.dut) dumps only the top level of dut, not its sub-modules. Call $fsdbDumpoff during simulation phases you don't need (e.g., memory initialization). For targeted debug, dump only the module hierarchy relevant to your bug. You can also add multiple selective $fsdbDumpvars calls covering specific sub-modules at full depth while keeping everything else shallow.
Find the output signal with an unexpected X, right-click the X waveform region → "Trace X Value". Verdi opens TFV and shows exactly which gate or flip-flop is driving X, with all its inputs annotated. Common X sources: uninitialized registers (add initial blocks or check reset), case without default (all outputs need explicit assignment), multi-driver conflicts (check multiple assign driving same net), or interface signals not driven during reset. Enable View → Show Delta Cycle to see X→0 transitions at reset release.
Yes. Verdi reads VCD (produced by any simulator), and can read FSDB from Cadence Xcelium and Mentor Questa via their respective PLI/DPI integrations. The Novas PLI library (novas.tab + pli.a) can be linked into most simulators to enable FSDB dumping. Cross-probe works best with VCS+KDB. With other simulators you can still use nWave for waveform viewing and TFV for logic tracing, but the source-level cross-probe requires the design to be loaded separately with -sverilog -f flist.f.