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

AboutRoadmapCareersInternshipsFAQContactPrivacyTerms
Skip to lesson

Course contents

  • How to Use This Puzzle Bank
  • SystemVerilog Language Puzzles25
  • Difficulty Guide
  • Full Topic Map
  • Interview-Day Tips
  • Study Route: One Week Before the Interview
  • Study Route: Two Weeks
  • Study Route: Four Weeks (Full Course)4
  • OOP & Testbench Puzzles25
  • Concurrency & Timing Puzzles25
  • Randomization & Constraint Puzzles25
  • SVA Assertion Puzzles25
  • Functional Coverage Puzzles25
  • Logic & Aptitude Puzzles25
  • Scenario & Debug Puzzles25
    • Testbench Debug Puzzles: Why Did the Test Hang?
      • Handshake Hang: Missing item_done on One Branch
      • Missing run_phase Objection in Test
      • Wrong Phase: Starting Traffic in shutdown_phase
      • Handshake Violation: item_done Called Twice
      • Sequence get_response Stall
      • Virtual Sequence Waits on an Event That Already Fired
    • Deadlock Scenario Puzzles: Objection and Phase Stalls
    • Scoreboard Puzzles: Mismatch or Ordering Bug?
    • Real Interview Rounds: End-to-End Debug Walkthrough
    • Scenario & Debug Puzzles: Tricky Q&A
  • UVM Testbench Puzzles25
  • Clock, Reset & CDC Puzzles25
  • Bus and Interface Protocol Puzzles25
  • Interview Prep: Puzzle Rounds7
  • DV Puzzle Cheatsheet
Loading lesson

←Testbench Debug Puzzles: Why Did the Test Hang?
  1. Topics
  2. DV Interview Puzzles
  3. Scenario & Debug Puzzles
  4. Testbench Debug Puzzles: Why Did the Test Hang?
  5. Handshake Hang: Missing item_done on One Branch
On this page

    VLSI DV Interview PuzzlesAll levels

    Handshake Hang: Missing item_done on One Branch

    Regression hangs in about 20 of 200 seeds (roughly 1 in 10). Last log says the sequence is blocked in finish_item(). The item class constrains kind with dist { NORMAL := 999, SKIP_ME := 1 }, so a 100-item sequence contains a SKIP_ME item in about 1 seed in 10. Find the exact liveness bug and fix it without changing stimulus intent.

    Puzzle

    Difficulty: Medium · Puzzle 1 of 6 · Topic: Testbench Debug Puzzles: Why Did the Test Hang?

    Regression hangs in about 20 of 200 seeds (roughly 1 in 10). Last log says the sequence is blocked in finish_item(). The item class constrains kind with dist { NORMAL := 999, SKIP_ME := 1 }, so a 100-item sequence contains a SKIP_ME item in about 1 seed in 10. Find the exact liveness bug and fix it without changing stimulus intent.

    Code

    design.sv
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    class my_item extends uvm_sequence_item;
      rand bit [31:0] addr;
      rand kind_e     kind; // NORMAL or SKIP_ME
      constraint c_kind { kind dist { NORMAL := 999, SKIP_ME := 1 }; }
      // ...
    endclass
    
    class req_seq extends uvm_sequence #(my_item);
      \`uvm_object_utils(req_seq)
      virtual task body();
        my_item req;
        repeat (100) begin
          req = my_item::type_id::create("req");
          start_item(req);
          assert(req.randomize());
          finish_item(req);
        end
      endtask
    endclass
    
    class my_driver extends uvm_driver #(my_item);
      \`uvm_component_utils(my_driver)
      virtual task run_phase(uvm_phase phase);
        my_item req;
        forever begin
          seq_item_port.get_next_item(req);
          if (req.kind == SKIP_ME) begin
            continue; // bug
          end
          drive_req(req);
          seq_item_port.item_done();
        end
      endtask
    endclass

    Hint

    Audit get_next_item/item_done pairing on every control-flow path, not just the common path.

    Step-by-step solution

    Diagram
    1) Reproduce one failing seed and add driver logs around get_next_item/item_done with the item id. The hang rate (about 1 seed in 10) matches the rare SKIP_ME item, not a common path.
    2) The last driver log is "got item N (SKIP_ME)" with no matching "done N"; the sequence log shows finish_item(N) never returned.
    3) The continue jumps back to get_next_item without item_done. The sequence stays blocked in finish_item for the old item, and the new get_next_item finds nothing to grant (in UVM 1.2 calling get_next_item twice without item_done is a UVM_ERROR, after which the call blocks; older versions may behave differently).
    4) Refactor so item_done is called exactly once per get_next_item on every path: if (req.kind != SKIP_ME) drive_req(req); seq_item_port.item_done();
    5) Add a counter check: outstanding get_next_item minus item_done equals zero at end of test, and a directed test that forces SKIP_ME on item 1.

    Answer

    Answer: Bug: the early continue on SKIP_ME skips item_done, so finish_item never returns and the driver then calls get_next_item on a handshake that is still open. Fix: call item_done exactly once per get_next_item on every path (if (kind != SKIP_ME) drive_req(req); item_done();).

    How this was checked

    Checked by running the code in Verilator 5; the printed output supports the answer above. Plain-SV model of the driver handshake (mailbox + done counter), not the UVM library: the skipped item leaves finish_item stuck, the fixed driver completes all five.

    Why candidates get it wrong

    Raising the global timeout or rerunning the failing seed with more time does nothing: the handshake is open forever. The tell is the low hang rate matching a rare item kind, which points at a rarely-taken driver branch.

    Interviewer follow-up

    How would you instrument sequencer-driver latency so this class of bug is caught within 100 cycles? Model answer: Wrap the pull side: timestamp every get_next_item and assert (or count in a watchdog thread) that item_done follows within N cycles, e.g. a driver-side counter of open handshakes with an error if it stays at 1 for more than 100 clocks; the same check on the sequence side bounds finish_item latency. The check fires at the first stuck item instead of at the global timeout.

    Say it out loud

    The hang rate of one seed in ten matches the rare SKIP_ME item, so I look at the driver branch that item takes. The log shows the driver got that item and never printed done, so the sequence is still blocked in finish_item. The root cause is the continue, which skips item_done and leaves the handshake open. I confirm it with a directed test that forces SKIP_ME on item one, and the fix is to call item_done exactly once per get_next_item on every path.

    Related topics

    • The Driver Handshake: start_item, finish_item, get_next_item, item_done

    • Stalled Sequences: Hang Triage

    • Back to Testbench Debug Puzzles: Why Did the Test Hang?

    • Scenario & Debug Puzzles section

    Previous

    186 / 293

    Next: Missing run_phase Objection in Test

    Up next

    Up nextMissing run_phase Objection in Test

    Sign in to save progress

    Practice this lessonPrevious lessonReport an error

    See also

    • Wrong Phase: Starting Traffic in shutdown_phase
    • Handshake Violation: item_done Called Twice
    • Sequence get_response Stall