Part 5 · Sequences · Intermediate

Symptom & Hang Overview: Silence Failures

Classify sequence failure modes, the diagnosis table, and where threads block in the handshake stack.

The silence problem

Most UVM bugs scream — UVM_ERROR, assertion failures, X-propagation. Sequence bugs whisper. The simulation appears healthy: time advances, components report phase transitions, sometimes objections drop and the test passes with zero bus transactions. Understanding which kind of silence you have determines the first debug step.

diagram
[SEQ] three silence failure modes

  TYPE A — HANG (sim never ends)
    thread blocked at start_item, finish_item, or get_next_item
    objection still raised OR no timeout configured
    fix: find blocked handshake (driver/arbiter)

  TYPE B — QUIET PASS (sim ends, no bus activity)
    seq.start() never called, or called after objection dropped
    driver in passive agent — get_next_item never services
    fix: test flow / agent is_active

  TYPE C — NULL / FATAL (sim stops with message)
    p_sequencer wrong type, null sequencer handle
    fix: declare macro and start() target

Where threads block

The sequencer–driver handshake is a pair of blocking calls. The sequence blocks at start_item until the driver calls get_next_item. It blocks at finish_item until the driver calls item_done(). The driver blocks at get_next_item until a sequence calls start_item. A stall anywhere in this cycle freezes the whole agent.

diagram
Legend: [SEQ] [DRV] [UVM]

  SEQUENCE                    SEQUENCER                 DRIVER
  [SEQ]                       [UVM]                     [DRV]

  start_item(req) ──────────► pending FIFO ──────────► get_next_item(req)
       │ BLOCKS here                                      │ BLOCKS here
       │ until driver pulls                               │ until seq pushes
       │                                                  │
       │◄───────────────────────────────────────────────┘
       │
  randomize(req)
       │
  finish_item(req) ─────────► wait for done ───────────► drive(req)
       │ BLOCKS here                                      │ then item_done()
       │ until item_done                                    │
       │◄──────────────────────────────────────────────────┘
       ▼
  next beat

Full diagnosis table

Use this table to map observable symptoms to likely root cause. Confirm with targeted uvm_info before deep diving — the sub-lessons expand each row.

diagram
SYMPTOM                          LIKELY CAUSE                    FIRST CHECK
──────────────────────────────────────────────────────────────────────────────────
Hang at finish_item                missing item_done()             driver drive() path
Hang at start_item                 lock/grab held by other seq     search lock() calls
Hang at start_item                 sequencer arbitration starvation  bg seq never finishes
Hang at get_next_item              no sequence started             test run_phase flow
Hang at get_next_item              no run_phase objection          phase.raise_objection
Null ptr p_sequencer.apb_sqr       wrong `uvm_declare_p_sequencer  macro vs start target
Null ptr p_sequencer               seq.start(null)                 null check before start
No bus activity, sim ends          objection dropped early         seq.start before drop?
No bus activity, sim ends          UVM_PASSIVE agent               is_active == UVM_ACTIVE?
Randomize assert / uvm_fatal       constraint conflict             req.print(), UVM_FULL
Driver log never prints            passive agent or no driver      agent build, is_active
Bus activity then stops            item_done skipped on error path every get needs done
Wave shows pins, no seq log        seq on wrong sequencer          full_name() on sqr

Walkthrough — classifying a real stall

Scenario: test starts, sim runs 10 ms, zero AXI transactions, test passes. Classification:

diagram
[STIM] triage walkthrough — quiet pass

  OBSERVATION: sim ends, UVM_INFO "TEST PASSED", zero wdata on waves
  CLASSIFICATION: TYPE B — quiet pass (not a hang)

  STEP 1: grep log for "run_phase started" on driver
     MISSING: driver never entered run_phase
  STEP 2: check agent is_active
     UVM_PASSIVE: no driver built, sequencer has no executor
  STEP 3: check seq.start timing vs objection
     seq.start after drop_objection — seq never ran during run_phase

  ROOT CAUSE: passive agent + seq.start after objection dropped
  FIX: is_active = UVM_ACTIVE; move seq.start before drop_objection
  • Quiet pass is worse than hang — regression green with zero checking.

  • Always grep for driver run_phase and seq start messages before waveform debug.

  • Classification (hang vs quiet pass vs null) picks the right sub-lesson.

Key takeaways

  • Silence = blocked thread, missing start, or wrong sequencer — classify first.

  • finish_item hang → item_done; start_item hang → lock or arbitration.

  • Diagnosis table maps symptom to cause — work top to bottom.

Common pitfalls

  • Assuming sim hang when test already ended — check objection timeline first.

  • Debugging waves before reading log — driver/seq uvm_info is faster.

  • Ignoring quiet pass — zero transactions should fail review even if UVM says PASS.