Debugging

Reporting the bug

The short form that decides how well a debug run goes, field by field.

Debug mode opens with a short form rather than an empty box. That is deliberate: the single strongest predictor of whether a debug run lands is whether it was told what should have happened and what happened instead. An open prompt reliably produces "it doesn't work", which is the one description nobody can act on.

The form, field by field

FieldWhat to put in it
Where it failsIn simulation, or in synthesis. This picks the whole investigation path, so it is the one field worth being careful about.
What you expectedThe behaviour you were entitled to see. Concrete beats general: “the counter wraps to 0 after 15”.
What happened insteadWhat it actually did. “It sticks at 15 and never wraps”.
How to reproduceThe command or the testbench that shows it. If there is no testbench yet, say so; that is useful information, not a gap to hide.
EvidencePaste the simulator log, the synthesis warning, or the error text. Long logs are fine.
WaveformOptional. Attach a VCD or a capture from your board; see Waveforms and evidence.

Simulation or synthesis

These are genuinely different investigations, and picking the wrong one produces a confident, wrong answer. A simulation bug is chased with waveforms and a re-run. A synthesis bug is chased through the synthesis log, the static checks and the places where simulation and hardware are known to disagree.

Pick thisWhen
In simulationThe testbench fails, hangs, or prints values you did not expect. Also the right choice when the design works in simulation and you want to know whether it will keep working.
In synthesisThe tool errors, infers a latch, warns about widths or undriven nets, or produces something structurally different from what you wrote.

Note

There is no separate hardware option, and that is on purpose. Settling a board failure needs timing analysis we cannot run, so a hardware track could only ever restate static heuristics as though they were an answer. Describe the board symptom in the expected and actual fields and pick the domain the evidence you have came from.

What a good report looks like

Enough for a run to start reproducing immediately
Where:     In simulation
Expected:  On a write when full is high, the FIFO must ignore the write
           and keep its contents.
Actual:    The write goes through and overwrites the oldest entry.
Repro:     iverilog -g2012 -o sim rtl/*.v tb/tb_fifo.v && vvp sim
           Test 7 ("write while full") fails.
Evidence:  # Test 7: write while full                       FAIL
           #   at 2410 ns: expected data_out=0x41, got 0x7A
  • Name the signal if you know it. Even a suspicion narrows the search enormously, and a suspicion that turns out to be wrong gets recorded as ruled out.
  • Give the failing time if you have it. The run still hunts for the first divergence, but it now knows where to start looking backwards from.
  • Say what you have already tried. It stops the run from spending your budget re-walking a path you have already closed off.
  • Do not pre-diagnose. Say what you observed. Telling the run what is wrong when you are not sure biases the whole investigation towards your theory.

Follow-up turns

The form is for the first turn. After that you can simply reply in the composer, and the workspace stays where it was: the instrumentation, the captured waveforms and the hypotheses already eliminated all carry forward. That is why a second turn on the same bug is usually much cheaper than the first.

Tip

If the answer comes back as Needs more from you, the summary says exactly what is missing. Answering that in the composer is the fastest route to a result; starting a fresh chat throws away everything the first turn learned.