Reading Waveforms
The evidence is all there, every signal at every instant. The skill is knowing what to look for, and most of it is pattern recognition: a few kinds of bug make shapes that, once seen, you spot at once. This article is that catalogue, after the method that makes it useful.
Backwards from the output
Waveform debugging without a method is staring at traces hoping to notice something. The method is to start at the output the testbench said was wrong, at the time it said, and confirm that it is wrong. If it looks right, suspect the testbench; that happens more than you would think. Then add the signals that feed that output and ask which of them carries the wrong value, and follow that one back, until you reach the first signal that differs from what it should be. The bug is in the logic that makes that signal. Everything downstream is only carrying the mistake, and fixing the last symptom you see is how you spend a day patching the wrong place.
x propagation
A single bit at x draws at mid-level, neither high nor low, often in red; a bus at x is a red bar. An x on an output was not made there; it was carried there. An x into an AND gate comes out unless the other input is 0, and an x on a D input is registered at the next edge (Figure 1).
Scroll left until you find the signal that was x first. That is the register that was never reset, the memory read before it was written, the case with no default, or the port left unconnected. In silicon that signal would be 0 or 1 at random, working on most chips and failing on some, and the simulation’s x is that latent randomness made visible. Treat every x on an output as an arrow.
Glitches
A glitch is a narrow pulse: a sliver of high in a low signal, or a bus that shows an intermediate value for a couple of nanoseconds on its way between two correct ones (Figure 2). At a coarse zoom it is a discoloration; zoom into the transition to see it. Section 2.4 explained where they come from.
A glitch that settles before the next edge is harmless to a registered output, and the flip-flop captures the settled value. It is a real bug if it drives something asynchronous, a latch enable or a reset, or if it is wide enough to reach the edge. Measure it with the cursors and decide which.
Timing signatures
RTL simulation has no gate delays, so real setup and hold violations show only in gate-level simulation with annotated timing. Their shapes are worth knowing for when you get there. A setup violation looks like an input still changing just before the sampling edge, and an output that changes in the same cycle as the input when it should have taken one (Figure 3). A hold violation is an input that changes just after the edge and an output that moved suspiciously early (Figure 4).
Before chasing logic, look at when the output changed relative to the edge. The right time and the wrong value is a logic bug. The wrong time is a timing bug, and the fixes are entirely different.
State names
A state register shows as 0x0, 0x1, 0x3, and you decode it in your head. GTKWave takes a translate file, one mapping per line:
0 IDLE
1 FETCH
2 DECODE
3 EXECUTE
4 WRITEBACK
Right-click the signal, Data Format, Translate Filter File, and the canvas shows the names. Teams generate the file from the localparam definitions with a short script and commit it beside the save file.
Pipeline latency
Put a distinctive value, 0xFF among zeros, on the input, and find where it appears on the output. One cursor on the edge where it goes in, the other on the edge where it comes out, and the difference divided by the period is the pipeline depth (Figure 5). If it is not the depth the RTL intends, a stage is miscounted.
The sequence
- Fit the run.
- Find the output. Is it wrong? If not, check the checker.
- Look for x. Any x on an output has a source upstream; find it.
- Look for narrow pulses at transitions, and measure whether they reach an edge.
- Look at when outputs change relative to the clock.
- Add the signals feeding the wrong output, one level at a time.
- Measure your hypothesis with the cursors before acting on it.
The waveform gives evidence, not answers. The last article takes one bug the whole way, from a failing test to a confirmed fix.