Stop Rebuilding Your Verdi Waveform Setup — Make Your RC File Reusable Forever
BY ABHI VORA
Ever spent 30 minutes re-adding hundreds of signals into Verdi's nWave — only to do it all over again when your IP lands inside an SoC? What if one single line change could bring your entire debug environment back in seconds? It can. Here's how.
A practical guide for ASIC verification engineers · Synopsys Verdi / nWave
Introduction
Verdi's RC file is a powerful mechanism that saves and restores your entire waveform debug environment. Most engineers only use it at the surface level: save it, reload it, hope it works. But when hierarchy changes — as it always does between IP and SoC simulation — the RC file breaks. Every signal vanishes and you start from scratch.
An IP sign-off duty. A clean, portable RC file is part of delivering an IP — not an afterthought. When your block moves into an SoC, the integration team should be able to bring up your full waveform view in seconds instead of reverse-engineering your signal list. Treat the RC file as a sign-off deliverable, and every downstream team inherits your debug knowledge for free.
What you will learn:
· What an RC file really is
· Why hierarchy breaks the RC file
· The waveDefine + include + ${TOP} fix that makes RC files portable across IP, subsystem, and SoC
· Best practices when delivering IP to SoC teams as part of sign-off
What Is an RC File?
When you debug in nWave, you carefully arrange signals into groups, pick display formats (HEX, BIN, DEC), set row heights, and get everything organised. An RC file remembers all of that — so the next time you open Verdi, your full debug setup comes back instantly.
· FSDB file → stores actual signal values — the waveform transitions and data
· RC file → stores how you arranged and displayed those signals
The RC file stores:
· Signal group names and structure
· Which signals are added, and in what order
· Display format for each signal — HEX, BIN, DEC
· Signal row heights and spacing
· Window layout and column widths
· Cursor position and named time markers
· Zoom level — which time window is visible
· FSDB file path associations
Important: An RC file does NOT store signal values. It only stores the display layout. All actual waveform data lives in the FSDB file.
The Problem: Why Your RC File Breaks
You spend real effort building a clean waveform view at IP level — groups, formats, row heights, markers — and save it to an RC file. Weeks later the same IP is instantiated inside an SoC, you reload the RC file… and nothing appears. Every group is empty. Every signal is gone.
The RC file itself is fine. The problem is that it points at signals using paths that no longer exist.
The Hierarchy Problem — Why RC Files Break at SoC Level
When Verdi saves an RC file, it writes the full absolute hierarchy path of every signal:
addSignal -h 15 -HEX /tb_wrapper/dut_top_u/ahb_if/haddr[31:0]
addSignal -h 15 -HEX /tb_wrapper/dut_top_u/axi_if/awaddr[31:0]
This path is specific to your IP testbench. The moment that same IP is placed inside an SoC, the path changes completely — e.g. to /chip_top/soc_subsystem/top/ahb_if/haddr — and Verdi cannot find any of those signals.
If your IP has 200 signals across the AHB and AXI interfaces, you just lost all of them. The entire RC file would need to be rebuilt from scratch — unless you use the pattern below.
The Fix: waveDefine + include + ${TOP}
Instead of hardcoding the path in every signal line, define the hierarchy root once as a variable at the top of a loader file. All template files use that variable. To move from IP to SoC, you change exactly one line.
Step 1 — Set the hierarchy root with waveDefine
# This single line tells Verdi where your IP lives in this simulation
waveDefine TOP /tb_wrapper/dut_top_u
Step 2 — Write template files using ${TOP}
# template/ahb.rc — written once, never changed again
addGroup "AHB_INTERFACE" -e FALSE
addSignal -h 20 ${TOP}/ahb_if/hclk
addSignal -h 15 ${TOP}/ahb_if/hresetn
addSignal -HEX ${TOP}/ahb_if/haddr[31:0]
${TOP} is substituted with whatever waveDefine set. The template file never needs to know the actual path — that is the loader's job.
Step 3 — Loader files include the templates
# tx_ip.rc — used during standalone IP simulation
waveDefine TOP /tb_wrapper/dut_top_u
include "template/ahb.rc"
include "template/axi.rc"
# tx_soc.rc — used when IP is inside the SoC (only the TOP path differs!)
waveDefine TOP /chip_top/soc_subsystem/top
include "template/ahb.rc"
include "template/axi.rc"
Key insight: Template files define the WHAT (which signals, groups, formats). Loader files define the WHERE (the hierarchy path). Only the WHERE ever changes between IP and SoC.
IP Delivery Checklist
When handing off your IP to an SoC team, include:
✅ template/ folder with both .rc template files (ahb.rc, axi.rc)
✅ tx_soc_template.rc — an SoC loader with one clearly marked line to update
✅ README — one sentence saying which line to change and how to find the SoC hierarchy path
# tx_soc_template.rc — hand this file to your SoC team
# ----
# UPDATE the line below with your SoC path to the TX IP instance.
# ----
waveDefine TOP /REPLACE_WITH_YOUR_SOC_PATH/top
include "template/ahb.rc"
include "template/axi.rc"
Result: The SoC team changes exactly one line. Every group, every AHB and AXI signal, every display format just works.
A Complete Real-World Example
Recommended File Structure
project_debug/
├── template/ # reusable, path-free (never change)
│ ├── ahb.rc # AHB interface signals
│ └── axi.rc # AXI interface signals
├── tx_main.rc # main loader, IP level
├── tx_ip.rc # standalone IP simulation
└── tx_soc.rc # same IP inside the SoC
template/ahb.rc — AHB Interface Signals
addGroup "AHB_INTERFACE" -e FALSE
addSignal -h 20 ${TOP}/ahb_if/hclk
addSignal -h 15 ${TOP}/ahb_if/hresetn
addSignal -HEX ${TOP}/ahb_if/haddr[31:0]
addSignal -HEX ${TOP}/ahb_if/hwdata[31:0]
addSignal -HEX ${TOP}/ahb_if/hrdata[31:0]
addSignal -h 15 ${TOP}/ahb_if/hwrite
addSignal -h 15 ${TOP}/ahb_if/hready
addSignal -BIN ${TOP}/ahb_if/hresp[1:0]
template/axi.rc — AXI Interface Signals
addGroup "AXI_INTERFACE" -e TRUE
addSignal -h 20 ${TOP}/axi_if/aclk
addSignal -h 15 ${TOP}/axi_if/aresetn
addSignal -h 15 ${TOP}/axi_if/awvalid
addSignal -h 15 ${TOP}/axi_if/awready
addSignal -HEX ${TOP}/axi_if/awaddr[31:0]
addSignal -HEX ${TOP}/axi_if/wdata[63:0]
addSignal -BIN ${TOP}/axi_if/bresp[1:0]
tx_main.rc — The Main Loader File
# Full debug view for TX IP — IP level
waveDefine TOP /tb_wrapper/dut_top_u
include "../template/ahb.rc"
include "../template/axi.rc"
Bonus: Two IP Instances Side by Side
# tx_soc_inst0.rc
waveDefine TOP /chip_top/soc_subsystem/top
include "template/ahb.rc"
include "template/axi.rc"
# tx_soc_inst1.rc
waveDefine TOP /chip_top/soc_subsystem/top1
include "template/ahb.rc"
include "template/axi.rc"
Load both files in the same nWave session and see both instances side by side — perfect for spotting asymmetric bugs between instances.
Conclusion
The RC file is one of the most underappreciated tools in the Verdi ecosystem. With the waveDefine + include + ${TOP} pattern, it stops being a personal convenience and becomes a reusable IP debug asset — one that works at IP level, subsystem level, and full-chip SoC level without any rework.
The idea is simple: separate the WHAT (signals and groups) from the WHERE (the hierarchy path). Templates own the what. Loaders own the where. Change one line, and the full debug environment follows the IP wherever it goes.
Make this part of your sign-off routine. A portable RC file saves real time — not just for you, but for every SoC integration engineer who would otherwise reconstruct your IP's signal structure from scratch.
Let's explore the most commonly used RC file commands and understand what each one does.
Inside the RC File — Every Switch Explained
Here's every section of a real RC file, and whether to keep or remove it when handing off to an SoC team.
1. Window Layout — viewport
viewport 0 25 1920 491 407 65
Format: viewport x y window width window height signal col width value col width. Stores the nWave window size and column widths — great for team debug reviews.
✅ Keep it — no hierarchy dependency.
2. FSDB File Path — openDirFile
openDirFile -d / "" "/data/sim/run_sv/test.fsdb"
activeDirFile "/data/sim/run_sv/test.fsdb"
Stores the FSDB path that was open when the RC file was saved. The problem is that IP and SoC simulations use completely different FSDB paths.
❌ Remove for IP delivery — let the SoC engineer open their own FSDB first (verdi -ssf soc.fsdb), then restore your RC file on top.
3. Signal Spacing
signalSpacing 5
Vertical gap between waveform rows. Values between 5 and 12 give good readability. No hierarchy dependency.
4. Zoom — Time Window
zoom 0.0000 2098748437.50000
For bug sharing: keep — puts the receiver directly at the failure window. For general IP delivery: remove — SoC simulations run at very different timescales.
5. Cursor and Markers
cursor 10000
userMarker 50000 AW_START
userMarker 80000 WR_DONE
Named markers tell the debug story instantly. For general IP delivery: remove. For bug handoff: keep — extremely communicative.
6. Events — Search Conditions
addEvent WR_START {awvalid && awready}
addEvent WR_DONE {bvalid && bready}
Waveform bookmarks — jump between every occurrence of a condition. Keep them if your signal names stay consistent across IP and SoC.
7. Groups — addGroup
addGroup "AHB_INTERFACE" -e FALSE
addGroup "AXI_INTERFACE" -e TRUE
Groups are the single biggest productivity benefit of RC files. -e TRUE opens the group expanded; -e FALSE keeps it collapsed — use collapsed for large signal sets.
✅ Always keep — groups are 100% hierarchy-independent.
8. Placing Signals — addSignal
addSignal -h 15 -UNSIGNED -HEX ${TOP}/ahb_if/haddr[31:0]
| Option | Best used for |
| -h 20 | Row height in pixels. Use 20–25 for clocks so they stand out. |
| -HEX | Address buses, data buses, register values. |
| -BIN | Control signals, FSM state bits, flag registers. |
| -DEC | Counters, burst lengths, integer counts. |
| -UNSIGNED | Unsigned integers — most common for addresses and data. |
| -SIGNED | Signed two's complement — signed offsets or arithmetic. |