Part 7 · Environment & Tests · Intermediate
Virtual Sequencer Debug: Symptom-First Triage and Recovery Runbook
Diagnose null handles, deadlocks, bad ordering, and premature completion with deterministic instrumentation and staged recovery.
Symptom Matrix
Classify failure symptoms before changing code. Each symptom maps to a specific boundary and reduces random debugging.
[TEST][UVM] symptom matrix
symptom likely boundary
----------------------------------------------------------------
null handle fatal env connect/mode mapping
vseq started, no child traffic wrong handle target or blocked child sqr
intermittent order mismatch missing/weak barrier synchronization
hang after partial progress unbounded wait or undropped objection
time-0 pass objection not raised / vseq not started[TEST][UVM] triage order
1) verify startup profile and mode config
2) verify mapped handle snapshot
3) verify vseq checkpoint timeline
4) verify event trigger/wait pairs
5) verify objection lifecycle and closure gatesKey takeaways
Symptom-first debugging narrows search scope immediately.
Fixed triage order prevents noisy, non-repeatable investigation.
Boundary-focused logs outperform ad hoc waveform hunting.
Common pitfalls
Patching code before proving handle map correctness.
Investigating full-stress profile before minimal reproducer.
Relying on one-time debug prints not present in CI runs.
Instrumentation Baseline
class soc_virtual_sequencer extends uvm_sequencer #(uvm_sequence_item);
int unsigned start_cnt;
int unsigned wait_cnt;
int unsigned timeout_cnt;
string checkpoint_q[$];
function void mark(string cp);
checkpoint_q.push_back(cp);
`uvm_info("VSQR_CP", cp, UVM_MEDIUM)
endfunction
endclasstask wait_event_or_fatal(uvm_event ev, time tmo, string name);
p_sequencer.wait_cnt++;
p_sequencer.mark($sformatf("WAIT_%s_BEGIN", name));
if (!ev.try_wait_trigger(tmo)) begin
p_sequencer.timeout_cnt++;
`uvm_fatal("VSQR_WAIT", $sformatf("timeout waiting %s", name))
end
p_sequencer.mark($sformatf("WAIT_%s_DONE", name));
endtask[TEST][UVM][ENV] mandatory debug payload
seed, test, profile
required handles
mapped handles
checkpoint timeline
wait/timeout counters
objection raise/drop times
scenario closure metricsKeep debug payload low overhead and always-on.
Capture checkpoints around every wait and branch start.
Print a compact final summary for quick triage in CI logs.
Applied Patterns
[TEST][UVM][VSEQ] recovery runbook
step 1:
freeze seed and exact command line
step 2:
run minimal profile that still reproduces
step 3:
disable optional interfaces and re-enable one by one
step 4:
compare checkpoint timelines between pass and fail
step 5:
convert discovered assumption into permanent guardrailfunction void final_phase(uvm_phase phase);
`uvm_info("VSQR_FINAL",
$sformatf("start=%0d waits=%0d timeouts=%0d cps=%0d",
env.v_sqr.start_cnt,
env.v_sqr.wait_cnt,
env.v_sqr.timeout_cnt,
env.v_sqr.checkpoint_q.size()),
UVM_LOW)
endfunctionUse reduction-and-rebuild to isolate orchestration bugs quickly.
Promote every fixed bug into a guardrail or assertion.
Prefer deterministic checks over manual log inspection.