A waveform shows what happened at each clock
A waveform is a record of how the signals of a circuit change over time. A simulator writes it to a VCD file, short for value change dump.
When a design misbehaves you cannot see the wires. The waveform is how you find the moment a signal went wrong, and which clock edge caused it.
By the end of this lesson
Note
I can read a waveform file and say what happened at each clock.
Key words
| Word | What it means | Example |
|---|---|---|
| Signal | a wire or register whose value is recorded | |
| Waveform | how signals change as time passes | |
| VCD file | a text file of every value change | |
| Timestamp | a line that says when the changes below happened | #15 |
| Unknown | a value no one has set yet, written x | |
| Column | one slice of time in the text picture |
The cells students fill in are left blank in this preview.
A testbench can record every signal
The lab's counter_tb.v calls $dumpfile and $dumpvars. Together they tell the simulator to write every signal to out/counter.vcd.
The three Runs move into your lab folder, compile the counter with its testbench, and run it. The simulator prints its own notice that it opened the dump file.
Go into the lab folder
cd ~/hdlShown here, not run. Create a free account to press Run and type it into your own lab’s terminal.
Compile the counter
iverilog -o /tmp/counter counter.v counter_tb.vShown here, not run. Create a free account to press Run and type it into your own lab’s terminal.
Run it and write the dump
vvp /tmp/counterShown here, not run. Create a free account to press Run and type it into your own lab’s terminal.
A VCD header names the signals
A VCD file is plain text. First comes a header. Each $var line declares one signal: its kind, its width in bits, a one-character code and its name.
In this file, the code ! is the 4-bit signal q, " is clk and # is rst. The lines are indented by scope: the testbench is the outer one and the counter, dut, the inner. The next Run prints those lines.
Print the signal declarations
sed -n '10,20p' out/counter.vcdShown here, not run. Create a free account to press Run and type it into your own lab’s terminal.
A line starting with # is a time
After the header, each line that starts with # is a timestamp. The lines under it are the changes at that time.
1" sets the one-bit signal " to 1. b1 ! sets the bus ! to binary 1. Only changes are written, so a signal that holds its value costs nothing.
Worked example: the first edges of the dump
| Time | Lines in the file | What happened |
|---|---|---|
| 5 | 1" and b0 ! | clk rises, and q takes 0 because rst is 1 |
| 10 | 0" | clk falls, nothing else changes |
| 12 | 0# | rst is released, in the middle of a clock cycle |
| 15 | 1" and b1 ! | clk rises, and q counts up to 1 |
The cells students fill in are left blank in this preview.
Print the first changes
sed -n '31,44p' out/counter.vcdShown here, not run. Create a free account to press Run and type it into your own lab’s terminal.
vcd2txt draws the dump as text
The lab has a tool, vcd2txt FILE STEP. It prints one row for each signal and one column for each STEP time units.
A one-bit signal shows _ for 0 and # for 1. A bus shows its number, and x means unknown. The first Run uses a step of 10 and the second a step of 5.
Read it at 10 time units a column
vcd2txt out/counter.vcd 10Shown here, not run. Create a free account to press Run and type it into your own lab’s terminal.
Read it at 5 time units a column
vcd2txt out/counter.vcd 5Shown here, not run. Create a free account to press Run and type it into your own lab’s terminal.
A common mistake
Warning
Many people think a wider step gives a clearer picture. At 10 units a column the clock looks flat, because each column lands on a falling edge. A step that skips edges hides them. Pick a step no bigger than half a clock cycle.