Debugging

Waveforms and evidence

Attach a capture, or let the run record its own, and see what the agent read from it.

A waveform is the difference between reasoning about what a signal probably did and reading what it actually did. Debug runs capture one automatically, and you can attach one of your own when you already know where the trouble is.

Capture happens on its own

When a debug run simulates your design, it records a waveform, and it does so without touching your testbench. That matters for a practical reason: an edit to your testbench would turn up in the diff as a change you never asked for, and you would have to review it.

The captured file is attached to the turn and can be downloaded, so you can open the same waveform in your own viewer and check the run's reasoning against it.

Attaching your own

The intake form takes a VCD. Two cases where attaching one is much better than letting the run capture its own:

  • The failure is hard to reproduce. If you have already caught it once, your capture is the reproduction; the run inspects it before trying to recreate the conditions itself.
  • The failure was on hardware. An ILA or SignalTap export is a waveform like any other. Every query below works on it unchanged, which is the one part of a board investigation that carries over cleanly.

Note

Very large captures are truncated rather than rejected, and the turn tells you when that happened along with the time range that was kept. If you can, export a window around the failure instead of the whole run.

What the run does with it

The waveform is read, not dumped. A debug run asks it specific questions: what a set of signals did over a window, when a signal first changed, when a particular combination first became true, and where anything is undefined. The answers become the evidence you see on the diagnosis, each with the time it was taken.

You get the capture itself as well, so you can open the same waveform in your own viewer and check any claim in the answer against it.

Undefined is not zero

An undefined bit is reported as undefined, never quietly rounded down to zero. This sounds like a detail and it is not: treating X as 0 turns "this register was never initialised" into "this register held a small number", which is exactly the bug the run exists to find.

Reading a window
t = 300 ns   clk=1  rst_n=1  wr_ptr=0111  full=0  push=1
t = 310 ns   clk=0  rst_n=1  wr_ptr=1000  full=0  push=1
t = 320 ns   clk=1  rst_n=1  wr_ptr=1000  full=1  push=0
                                          ^ full asserts a cycle late

Values are shown in the width the signal actually has, so a partly-undefined vector reads as partly undefined rather than as a number that happens to look plausible.

Where it shows up in the answer

Waveform readings appear in the evidence list on the diagnosis, each with the time it was taken and the signal values at that time. If a claim about behaviour has no time attached to it, treat it as reasoning rather than as an observation; see Reading a diagnosis.

Tip

Captured waveforms are kept inside the workspace and are excluded from the file tree, the download zip and the change report, so they never turn up in your project as files somebody added.