Skip to content
DenseChip
Learn
PracticeCode labInterview

DenseChip

Navigate

Menu

LearnPracticeCode labInterview

Tools

All toolsSV editorCode repoResume
DenseChip

Practice, courses, and chip-design tools in one focused workspace.

LearnPracticeCode labInterviewToolsLearning paths

© 2026 DenseChip

AboutContactPrivacyTerms
Skip to lesson

Course contents

  • Part 0 · What Debugging Is6
  • Part 1 · Reproduce8
  • Part 2 · Observe9
  • Part 3 · Localise10
  • Part 4 · Hypothesise and Test6
  • Part 5 · Bug Classes16
  • Part 6 · Debug by Stage9
  • Part 7 · Hangs and Deadlocks7
  • Part 8 · Intermittent Failures7
  • Part 9 · Fix, Prove, Prevent7
  • Part 10 · Case Studies12
  • Part 11 · Debug as a Team5
  • Part 12 · Interview Prep5
    • Find the Bug in This Waveform
    • The Chip Hangs: What Do You Do?
    • A Test Fails Once in 500 Runs
    • How Do You Know Your Fix Works?
    • Mock Debug Interview
Loading lesson

‹Part 12 · Interview Prep
  1. Topics
  2. The Art of Hardware Debug
  3. Part 12 · Interview Prep
  4. The Chip Hangs: What Do You Do?

Part 12 · Interview Prep · Senior (S)

The Chip Hangs: What Do You Do?

The hang interview question rehearsed: keep the evidence, classify the hang, ask who is waiting for whom, find the cycle, move it to simulation, break the cycle and leave a detector. A weak and a strong answer, follow-ups, and the strong answer shown on a real dbglab hang.

On this page

    Why this matters

    "The chip hangs, what do you do?" separates candidates who have stood next to a stuck board from those who have not. A guessed answer (reset it, add a timeout, look at the waveform) loses the evidence and fixes nothing.

    After this lesson you can: answer the hang question as a method: preserve state, classify the hang, build the wait-for table, find the cycle, move it to the cheapest stage, break the cycle and add a detector, with a real hang as the example.

    Note

    Level: Senior (S) · Debug-loop step: Observe, Localise

    Before this: Who Is Waiting for Whom, Hang, Livelock or Starvation

    The question, as it is asked

    "You get a call from the lab. The new chip boots, runs traffic for a few minutes and then stops responding. Nothing on the console. What do you do?"

    The interviewer has left out almost everything on purpose: how often, which traffic, whether the clocks still run. Part of the test is whether you notice. Where do you begin?

    What the interviewer is listening for

    1. Keep the evidence. Do not reset or power-cycle until the state has been read: status registers, error logs, counters, a scan dump if the lab can take one. The first failing test on silicon lesson covers the order.

    2. Questions about the report. Is the whole chip dead or one function? Do clocks toggle? Does the debug port answer? How often, and what was running?

    3. A classification. Deadlock, livelock or starvation, from evidence, as in hang, livelock or starvation.

    4. Who is waiting for whom. Every agent waits for something; write it down and look for a cycle (who is waiting for whom, finding the cycle).

    5. Move it somewhere cheaper. Reproduce the conditions in simulation or on an FPGA, where every signal is visible (moving the failure to the cheapest stage).

    6. A fix that breaks the cycle, and a detector. Not a longer timeout.

    A weak answer, and why it fails

    Interview

    Weak: "I would reset the chip and try to reproduce it, then look at the waveform around where it hangs to find the stuck signal. If it is a handshake that never completes I would add a timeout so the block recovers."

    Three problems. The reset throws away the only snapshot of the bug, and a hang that takes minutes may take days to come back. "The waveform around where it hangs" does not exist on silicon, and in simulation it shows flat lines: a hang has no first wrong value to walk back from. And a timeout that "recovers" turns a deadlock into dropped data and hides the cause, as the watchdog lesson shows. The interviewer hears a candidate who would make the bug harder to find.

    A strong answer, out loud

    For a hang, the weight is at Report (what exactly stopped), Observe (the snapshot and the wait-for table) and Localise (the cycle).

    Say it as steps, and name each step. This is the shape of a two-minute answer:

    1. Report. "Before anyone resets it: is the whole chip stuck or one interface? Are the clocks running and does the debug port answer? How long after boot, and with what traffic? Has it happened before?"

    2. Observe without disturbing. "Through the debug port I read every status and error register, the interrupt state, any progress counters and hang detectors, and each bus master's outstanding requests. If the lab can scan-dump the stopped chip, I take one."

    3. Classify. "I read the counters twice, a second apart. If nothing changed anywhere it is a deadlock. If attempts grow but nothing completes it is a livelock. If one agent waits while others progress it is starvation."

    4. Localise with a wait-for table. "For each agent: what is it waiting for, and what is the evidence? If following the waits comes back to the start, there is the cycle. I look for the one arrow that is a design choice rather than a protocol rule, usually something holding a shared resource while it waits."

    5. Reproduce cheaply. "I rebuild those conditions in simulation, starting from the scan dump or from the traffic and configuration, so the cycle forms where I can see every signal. If it used to work, I bisect the history."

    6. Fix, prove, prevent. "The fix removes an arrow from the cycle. I predict what it changes, prove it on the repro and a sweep, and leave an assertion on the broken rule so the next one fires in tens of cycles, not when a watchdog gives up."

    Do it: the strong answer on a real hang

    Steps 3 to 5 are easiest to show where everything is visible. dbglab's dma_burst_backpressure test hangs at HEAD; the case study hunts it in full. Here is how much of the answer each command gives you, in the order you would say it.

    Report: how often, and does it depend on anything

    Terminal
    $ tb/run.sh dma_burst_backpressure 1
    dbglab: test=dma_burst_backpressure seed=1
    FAIL test=dma_burst_backpressure seed=1 cycle=2165: WATCHDOG: no bus or stream progress for 2000 cycles; cpu_valid=1 cpu_ready=0 cpu_addr=00003008
    $ tb/run.sh dma_burst_backpressure 1 verilator
    dbglab: test=dma_burst_backpressure seed=1
    FAIL test=dma_burst_backpressure seed=1 cycle=2165: WATCHDOG: no bus or stream progress for 2000 cycles; cpu_valid=1 cpu_ready=0 cpu_addr=00003008
    $ for s in $(seq 1 20); do tb/run.sh dma_burst_backpressure $s | tail -1; done | sed -E 's/seed=[0-9]+ //' | sort | uniq -c
      20 FAIL test=dma_burst_backpressure cycle=2165: WATCHDOG: no bus or stream progress for 2000 cycles; cpu_valid=1 cpu_ready=0 cpu_addr=00003008

    Twenty seeds, one line, one cycle: the seed does not matter, and two simulators agree. That rules out a race and a rare ordering before any waveform is opened. The watchdog line already names one waiting agent: the CPU, on a write to 0x3008 that never gets ready.

    Classify: is anything still trying?

    Terminal
    $ probes/run-probe.sh dbglab probes/hang_probe.sv dma_burst_backpressure 1 +FROM=2160 +TO=2164
    dbglab: test=dma_burst_backpressure seed=1
    cycle  cpu v r addr     grant lock  dma     dreq full sink_en
     2160      1 0 00003008  10    10    WAIT    0    1    0
     2161      1 0 00003008  10    10    WAIT    0    1    0
     2162      1 0 00003008  10    10    WAIT    0    1    0
     2163      1 0 00003008  10    10    WAIT    0    1    0
     2164      1 0 00003008  10    10    WAIT    0    1    0
    FAIL test=dma_burst_backpressure seed=1 cycle=2165: WATCHDOG: no bus or stream progress for 2000 cycles; cpu_valid=1 cpu_ready=0 cpu_addr=00003008

    Nothing changes from cycle to cycle: no retries, no state moving. That is a deadlock, not a livelock. On silicon you would get the same answer by reading the progress counters twice.

    Observe: the snapshot, as a wait-for table

    The snapshot at cycle 2165 gives one row per agent: the CPU waits for the bus (valid=1 ready=0 on the write that turns the sink on), the fabric for its locked owner, the DMA (grant=10 lock=10), the DMA for FIFO space (state=WAIT dreq=0), and the FIFO and sink for the CPU's write (full=1 sink_en=0). The case study builds that wait-for table line by line. Read down the waits and you are back at the CPU: a cycle. Three arrows are protocol (a paced DMA waits for space, a stopped sink does not drain, a CPU waits for the bus). One is a choice: the fabric keeps the grant for an owner that is not using it. That is the sentence the interviewer wants.

    Localise in time: when did the cycle close, and which change made it

    Terminal
    $ probes/run-probe.sh dbglab probes/hang_probe.sv dma_burst_backpressure 1 +FROM=164 +TO=168
    dbglab: test=dma_burst_backpressure seed=1
    cycle  cpu v r addr     grant lock  dma     dreq full sink_en
      164      1 0 00003008  10    10    RD_RSP  0    1    0
      165      1 0 00003008  10    10    POP     0    1    0
      166      1 0 00003008  10    10    LOAD    0    1    0
      167      1 0 00003008  10    10    WAIT    0    1    0
      168      1 0 00003008  10    10    WAIT    0    1    0
    ...
    $ git bisect start HEAD v0.1 && git bisect run tb/run.sh dma_burst_backpressure 1
    ...
    c4a71b585e287d527b9c2a827a3969bca0334445 is the first bad commit
    ...
    bisect found first bad commit
    $ git log -1 --oneline c4a71b5
    c4a71b5 dma: keep the bus for a whole chunk

    The DMA enters WAIT at cycle 167 still holding lock and the grant; every line after is the same. Four bisect runs name a performance change that taught the fabric to keep the grant while the owner holds lock. The case study shows why the obvious fix (drop lock in WAIT) still hangs, and the fix that works (re-arbitrate after every response).

    What the evidence says

    Each command answered one part of the spoken answer: deterministic or not, deadlock or livelock, which agents and which arrow, when, and which commit. None of it needed a waveform viewer, and none of it needed a guess. On silicon the commands change (register reads through the debug port, a scan dump, a lab repro) but the questions are the same, which is why the interviewer cares about the questions.

    Follow-up questions

    • "It never hangs in simulation." List what the failure needs (clock ratio, traffic mix, configuration, power state, temperature) and which stage has each ingredient. Rebuild the missing one in simulation, or start simulation from a scan dump of the stuck chip. See silicon vs simulation correlation.

    • "How do you tell a deadlock from a livelock without a waveform?" Two reads of the counters, some time apart: attempts and completions per agent. No change anywhere is a deadlock; attempts rising with no completions is a livelock.

    • "Why not just add a timeout?" A timeout ends the wait without removing the cause: a DMA that gives up drops a word, a bus that times out returns an error software did not expect. A timeout is a detector to report the hang, not a fix.

    • "The hang goes away when you connect the debugger." The probe changed the timing. Use passive observation (counters, a trace buffer frozen by the hang) and see heisenbugs.

    • "What would you want in the next chip?" Per-port progress timers, a sticky record of the first hang with a snapshot of who waits for what, readable without a reset (watchdogs and hang detectors).

    Traps

    Common pitfall

    Answering only for simulation. If the question says chip, start in the lab: keep the state, read it, then move to simulation. Jumping straight to "I would open the waveform" tells the interviewer you have not debugged silicon. The bring-up course's failure triage covers the lab side.

    Common pitfall

    Fixing the most suspicious arrow without a prediction. In dbglab the obvious fix, dropping lock while the DMA waits, still hangs at the same cycle. Say what a fix changes in the cycle before you claim it works.

    Why this matters

    Principal lens. A hang on silicon is debugged with whatever was built in before tape-out. The principal answer adds the design review: every shared resource (grant, credit, buffer, lock) should be able to say who holds it and what that holder waits for, through a register readable with the chip stuck. That costs a few hundred flops (illustrative) and can save weeks. The observability by design lesson lists them; Part 11 covers running a hang hunt across the RTL, verification and lab teams.

    Interview

    Asked: "The FPGA prototype hangs about once a week under a customer workload. You cannot attach a waveform. How do you approach it?"

    Weak answer: I would try to reproduce it in simulation with random tests until it hangs, and add some debug signals to the FPGA build.

    Strong answer: First I make the weekly event leave evidence: a progress timer per port that freezes a small trace buffer and a snapshot of every agent's wait state when it fires, readable over the debug link without a reset. While that runs I classify from counters: no progress anywhere or attempts without completions. When it fires I build the wait-for table from the snapshot, find the cycle, and look for the arrow that holds a shared resource while waiting. Then I recreate those conditions in simulation, often by biasing traffic towards the state the snapshot showed, prove a fix there, and run the prototype for several times the old mean time to hang with the detector still armed.

    Follow-ups: (1) How long must the prototype run clean before you believe the fix? (2) What if adding the trace buffer makes the hang stop?

    Check yourself A candidate's answer begins "First I would power-cycle the board to see if it happens again." What did they lose, and what should come first?

    They lost the only snapshot of the bug: the state of every agent at the hang, which a reset clears. If the hang takes days to recur, they also lost days. First come the questions (whole chip or one function, clocks, debug port) and the reads: status and error registers, counters twice, outstanding requests, a scan dump if possible. Only then reset and try to reproduce.

    Check yourself In the dbglab hang, the progress counters would show the CPU retrying its write every cycle. Would that make it a livelock?

    No. Holding valid high while waiting for ready is one attempt that never completes, not a repeated attempt. A livelock needs agents that act and undo, such as retries that are each refused. The probe lines are identical from cycle 167 on, so nothing acts: a deadlock. Count attempts as distinct tries, not cycles spent waiting.

    Remember

    • The first move is not to reset. A hung chip is a snapshot of the bug; read every status, counter and debug register before anyone power-cycles it.

    • Classify before you chase: no attempts anywhere is a deadlock, attempts without progress a livelock, one agent waiting while others work is starvation.

    • A fix must remove an arrow from the wait-for cycle. A longer timeout or a retry only changes how the test ends.

    Rule of thumb: capture the state of a hang before you change anything, and do not call it fixed until the wait-for cycle cannot form.

    How this was checked

    dbglab at HEAD 49c5f04 (build-history.sh), 2026-10-18. tb/run.sh dma_burst_backpressure 1 (Icarus Verilog 13.0) and the same with verilator (5.048) print the same WATCHDOG line at cycle 2165; seeds 1 to 20 all fail with that line at that cycle.

    hang_probe.sv (the case study's probe, compiled next to dbglab by probes/run-probe.sh: iverilog -g2012 -Wno-timescale -I tb ... hang_probe.sv, then vvp -n build/probe.vvp +TEST=dma_burst_backpressure +SEED=1) with +AT=2165, +FROM=164 +TO=168 and +FROM=2160 +TO=2164. Bisect in a scratch copy: git bisect start HEAD v0.1, git bisect run tb/run.sh dma_burst_backpressure 1 (git 2.54.0), four test runs, first bad commit c4a71b5.

    Limits: a simulated hang in one small design; no silicon, FPGA or lab instrument was used, so the lab steps of the answer are described, not run. The interview wording and the weak answer are illustrative.

    Keep going

    • Practice: FSM deadlock and livelock debugging

    • Practice: Deadlock and livelock: detection, debug and SVA

    • Practice: Interface-embedded assertions for deadlock detection

    • Practice: Timeout-safe concurrency with watchdogs

    • Code lab: Watchdog FSM

    • Code lab: Testbench timeout

    • Code lab: Timeout watchdog

    • Interview: run a mock interview on this topic

    Related topics

    • Part 12 · Interview Prep

    • Part 7: hangs and deadlocks

    • Case study: the deadlock under back-pressure

    • A full hang on dbglab

    • Bring-up: failure triage

    • Bring-up: debug interfaces

    Previous

    104 / 107

    Next: A Test Fails Once in 500 Runs

    Up next

    Up nextA Test Fails Once in 500 Runs

    Sign in to save progress

    Practice this lessonReport an error

    See also

    • How Do You Know Your Fix Works?
    • Mock Debug Interview