|
CocoTB Framework · Verification Infrastructure for RTL Testing GitHub · Documentation Index · MIT License |
WaveDrom Quick Start Guide¶
Get timing diagrams in 5 minutes
Prerequisites¶
# Install wavedrom-cli for PNG/SVG generation
npm install -g wavedrom-cli
# Verify installation
wavedrom-cli --version
Wavedrom User Examples
The protocol-specific wavedrom user examples (gaxi.py, apb.py, etc.) are located in the RTLDesignSherpa repository under tbclasses/wavedrom_user/.
Method 1: Template Class (Easiest)¶
GAXI Protocol¶
import cocotb
from cocotb.clock import Clock
from cocotb.triggers import RisingEdge
# Import from the RTLDesignSherpa main repo (tbclasses/wavedrom_user/gaxi.py)
from CocoTBFramework.tbclasses.wavedrom_user.gaxi import GAXIWaveDromTemplate
@cocotb.test()
async def gaxi_test(dut):
# Start clock
clock = Clock(dut.axi_aclk, 10, units="ns")
cocotb.start_soon(clock.start())
# Reset
dut.axi_aresetn.value = 0
await RisingEdge(dut.axi_aclk)
dut.axi_aresetn.value = 1
await RisingEdge(dut.axi_aclk)
# === ONE LINE SETUP ===
gaxi_wave = GAXIWaveDromTemplate(
dut=dut,
signal_prefix="wr_", # Finds: wr_valid, wr_ready, wr_data
data_width=32,
preset="comprehensive" # handshake, back2back, stall, idle
)
# Start capturing
await gaxi_wave.start_sampling()
# Run your test
dut.wr_valid.value = 1
dut.wr_data.value = 0xDEAD
await RisingEdge(dut.axi_aclk)
dut.wr_valid.value = 0
await RisingEdge(dut.axi_aclk)
# Stop and generate waveforms
results = await gaxi_wave.stop_sampling()
gaxi_wave.get_status()
Output: WaveJSON files in sim_build/ directory
APB Protocol¶
# Import from the RTLDesignSherpa main repo (tbclasses/wavedrom_user/apb.py)
from CocoTBFramework.tbclasses.wavedrom_user.apb import APBWaveDromTemplate
@cocotb.test()
async def apb_test(dut):
# Clock and reset...
apb_wave = APBWaveDromTemplate(
dut=dut,
signal_prefix="apb_", # Finds: apb_psel, apb_penable, etc.
data_width=32,
addr_width=32,
preset="comprehensive" # write, read, phases, errors
)
await apb_wave.start_sampling()
# Run APB transactions...
results = await apb_wave.stop_sampling()
Method 2: Manual Setup (More Control)¶
Step 1: Create Field Config¶
# Import from the RTLDesignSherpa main repo (tbclasses/wavedrom_user/gaxi.py)
from CocoTBFramework.tbclasses.wavedrom_user.gaxi import get_gaxi_field_config
# Define data fields
field_config = get_gaxi_field_config(
data_width=32,
addr_width=16, # Optional
ctrl_width=4 # Optional
)
Step 2: Create WaveJSON Generator¶
# Import from the RTLDesignSherpa main repo (tbclasses/wavedrom_user/gaxi.py)
from CocoTBFramework.tbclasses.wavedrom_user.gaxi import create_gaxi_wavejson_generator
wave_generator = create_gaxi_wavejson_generator(
field_config=field_config,
signal_prefix="cmd_",
group_name="Command Interface"
)
Step 3: Create Constraint Solver¶
from CocoTBFramework.components.wavedrom.constraint_solver import TemporalConstraintSolver
wave_solver = TemporalConstraintSolver(
dut=dut,
log=dut._log,
wavejson_generator=wave_generator,
default_field_config=field_config
)
# Add clock
wave_solver.add_clock_group('default', dut.axi_aclk)
Step 4: Auto-Bind Signals¶
# Automatic signal discovery
wave_solver.auto_bind_signals(
protocol_type='gaxi',
signal_prefix='cmd_',
field_config=field_config
)
Step 5: Setup Constraints¶
# Import from the RTLDesignSherpa main repo (tbclasses/wavedrom_user/gaxi.py)
from CocoTBFramework.tbclasses.wavedrom_user.gaxi import setup_gaxi_constraints_with_boundaries
setup_gaxi_constraints_with_boundaries(
wave_solver=wave_solver,
preset_name="comprehensive",
signal_prefix="cmd_",
field_config=field_config
)
Step 6: Capture and Generate¶
await wave_solver.start_sampling()
# Run test...
await wave_solver.stop_sampling()
wave_solver.debug_status()
Generate PNG/SVG from WaveJSON¶
Script Method (Batch Processing)¶
Create wd_cmd.sh:
#!/bin/bash
rm -rf ./PNG ./SVG
mkdir -p ./PNG ./SVG
find ./ -name "*.json" | while read file; do
test_name=$(echo "$file" | sed 's|^\./local_sim_build/\([^/]*\)/.*|\1|')
base_name=$(basename "${file%.json}")
wavedrom-cli -i "$file" \\
-s "./SVG/${test_name}_${base_name}.svg" \\
-p "./PNG/${test_name}_${base_name}.png"
done
Run:
Manual Method (Single File)¶
Segmented Capture Pattern¶
For clean, isolated scenario waveforms:
# Scenario 1
await wave_solver.start_sampling()
# ... run scenario 1 ...
await wave_solver.stop_sampling()
await wave_solver.solve_and_generate()
wave_solver.clear_windows()
# Scenario 2
await wave_solver.start_sampling()
# ... run scenario 2 ...
await wave_solver.stop_sampling()
await wave_solver.solve_and_generate()
wave_solver.clear_windows()
Benefits: - No spurious matches across scenarios - Cleaner, more deterministic waveforms - Faster CP-SAT solving (smaller windows)
Common Presets¶
GAXI Presets¶
| Preset | Constraints | Use Case |
|---|---|---|
basic_handshake |
handshake | Verify valid/ready works |
comprehensive |
handshake, back2back, stall, idle | Full behavior analysis |
performance |
handshake, back2back, stall (extended) | Throughput optimization |
debug |
All with extended windows | Debugging stuck interfaces |
APB Presets¶
| Preset | Constraints | Use Case |
|---|---|---|
basic_rw |
write, read | Basic functionality |
comprehensive |
write, read, phases, completion, errors | Full protocol analysis |
debug |
Activity detection on all signals | Troubleshooting |
timing |
Complete transactions with wait states | Timing analysis |
error |
Error responses and edge cases | Error handling verification |
Troubleshooting¶
No waveforms generated?¶
-
Check constraint solver status:
-
Verify signals were bound:
-
Check if patterns were detected:
Signals not found?¶
Use manual signal map:
gaxi_wave = GAXIWaveDromTemplate(
dut=dut,
signal_prefix="",
signal_map={
'valid': 'my_custom_valid',
'ready': 'weird_ready_signal',
'data': 'pkt_data'
}
)
Wrong data captured?¶
Adjust window sizes:
setup_gaxi_constraints_with_boundaries(
wave_solver=wave_solver,
max_cycles=50, # Increase if pattern is longer
context_cycles_before=10, # More setup cycles
context_cycles_after=10 # More teardown cycles
)
Next Steps¶
- Full Tutorial: Wavedrom GAXI Example (see TestTutorial)
- Protocol Presets: All Supported Protocols
- Auto-Binding Details: Auto-Binding Guide
- Advanced Techniques: Segmented Capture