Part 2 · Phases & Lifecycle · Intermediate

Debug Checklist Playbook: Step-by-Step Phase Triage

A repeatable playbook for any phase-related failure — from first symptom to confirmed fix.

Universal triage playbook

diagram
[PHASE][UVM] universal phase debug playbook

STEP 1 — Reproduce with traces
  simv +UVM_PHASE_TRACE +UVM_OBJECTION_TRACE +UVM_VERBOSITY=UVM_MEDIUM

STEP 2 — Classify symptom
  A) hang          B) instant pass       C) null/error in connect
  D) no override   E) wrong phase order  F) post-jump corruption

STEP 3 — Apply symptom-specific path (below)

STEP 4 — Confirm fix
  rerun traces: clean objection count, expected phase order

STEP 5 — Add regression guard
  check_phase invariant or phase-entry log

Symptom-specific paths

A) Hang

  1. OBJECTION_TRACE → last unmatched RAISE.

  2. Inspect error/timeout branches in that component.

  3. Check fork/join for stranded child objections.

  4. Verify drain_time setting if hang is after count hits zero.

B) Instant pass

  1. PHASE_TRACE → run_phase END at time 0.

  2. Find missing raise_objection.

  3. Add check_phase zero-transaction guard.

C) Null connect

  1. print_topology — component exists?

  2. Review active/passive create branch.

  3. Guard connect or fix create condition.

D) Override not working

  1. Add phase-entry uvm_info — did it print?

  2. Compare method signature to uvm_component base.

  3. Move factory override before create.

systemverilog
class robust_comp extends uvm_component;
  `uvm_component_utils(robust_comp)
  function new(string name, uvm_component parent); super.new(name, parent); endfunction

  function void build_phase(uvm_phase phase);
    super.build_phase(phase);
  endfunction

  function void end_of_elaboration_phase(uvm_phase phase);
    super.end_of_elaboration_phase(phase);
    uvm_top.print_topology();
  endfunction

  task run_phase(uvm_phase phase);
    super.run_phase(phase);
    phase.raise_objection(this, "work");
    fork : work
      do_work();
    join
    phase.drop_objection(this, "work done");
  endtask
endclass

Key takeaways

  • Follow the playbook in order — traces before waveforms.

  • Classify symptom first; do not skip to random fixes.

  • Add regression guard after every phase bug fix.

Common pitfalls

  • Skipping step 1 because 'it worked before'.

  • Fixing symptom without guard — bug returns next sprint.


Defensive template adoption

Adopt the robust_comp template as a project base class. It encodes super calls, topology print, and balanced objections — preventing the majority of phase bugs by construction.