Part 6 · Agents & Protocol IP · Intermediate
Sequencer Debug Patterns: Deadlocks, Starvation, and Missing Responses
Concrete debug patterns for common sequencer failures with deterministic triage and instrumentation.
Symptom map for sequencer failures
Most sequencer issues show up as timeouts, stuck sequences, or unfair grants. Start with symptom classification before changing policy code.
[SEQ] failure symptom matrix
symptom likely root zone
----------------------------------------------------------------
sequence stuck at start_item no grants / arbitration lockout
driver idle, sequences pending connect mismatch or grant deadlock
one sequence never progresses starvation by policy/priority
responses missing in sequence routing/ID mismatch
random non-reproducible stalls hidden locks/grabs or startup contention[SEQ][UVM] first-pass checks
1) drv.seq_item_port connected to sqr.seq_item_export?
2) any sequence holding grab/lock unexpectedly?
3) grant counters changing over time?
4) response counters balanced with requests?
5) default sequence causing hidden contention?Map symptoms to boundaries to reduce exploratory debug noise.
Check connectivity and lock/grab state before policy rewrites.
Track request/grant/response balance continuously in regressions.
Instrumentation patterns for deterministic debug
Sequencer instrumentation should expose queue depth, grants, wait latencies, active lock owners, and response routing health. Keep counters lightweight and always-on at low verbosity.
class dbg_sequencer extends my_sequencer;
`uvm_component_utils(dbg_sequencer)
int unsigned req_count;
int unsigned grant_count;
int unsigned rsp_count;
int unsigned lock_wait_count;
function void report_phase(uvm_phase phase);
`uvm_info("SQR_SUMMARY",
$sformatf("req=%0d grant=%0d rsp=%0d lock_wait=%0d",
req_count, grant_count, rsp_count, lock_wait_count),
UVM_LOW)
endfunction
endclasstask check_progress_timeout(int unsigned cycles);
int unsigned g0 = sqr.grant_count;
repeat (cycles) @(posedge vif.clk);
if (sqr.pending_req_count > 0 && sqr.grant_count == g0)
`uvm_error("SQR_STALL", "pending requests but no grant progress")
endtask[SEQ] useful counters
pending_req_count
current_lock_owner
grant_count_by_sequence
max_wait_cycles_by_sequence
rsp_unmatched_count
startup_seq_list
these convert "stuck" into actionable boundary diagnosisAlways collect progression metrics before reproducing rare deadlocks.
Use watchdogs to detect pending-without-grant states early.
Attribute grants/waits by sequence name for starvation diagnostics.
Deadlock and starvation runbook
For stubborn stalls, use a deterministic runbook: freeze seed, reduce traffic to minimal competing sequences, inspect lock ownership timeline, then reintroduce complexity gradually.
[SEQ][UVM][AGT] deadlock runbook
phase A: deterministic reproduce
fixed seed, minimal two-sequence contention
phase B: lock/grab audit
who owns lock? when released?
phase C: arbitration progress audit
pending > 0 while grants frozen?
phase D: response path audit
req/rsp balance by sequence
phase E: restore full scenario once minimal case is stabletask assert_no_starvation(seq_stat_t st[$], int unsigned max_wait);
foreach (st[i]) begin
if (st[i].max_wait_cycles > max_wait)
`uvm_warning("STARVE",
$sformatf("%s wait=%0d > %0d",
st[i].name, st[i].max_wait_cycles, max_wait));
end
endtask[SEQ][MON] sequencing vs protocol separation
if sequencer shows healthy grants but monitor shows no DUT activity:
likely driver/protocol path issue
if monitor shows activity but sequences wait for responses:
likely response routing issue
use both telemetry streams to isolate root cause quicklyKey takeaways
Sequencer debug is fastest when symptom categories map to clear boundaries.
Counters for grants, waits, locks, and responses make stalls diagnosable.
Deterministic minimal repro is essential before broad scenario debugging.
Combine sequencer and monitor telemetry to distinguish policy vs protocol failures.
Common pitfalls
Changing arbitration policy before checking lock/connectivity basics.
Debugging deadlocks under full random traffic without minimal repro.
Ignoring response-balance metrics in concurrent sequence environments.
Treating all timeouts as driver bugs without sequencer progress evidence.