Part 2 · Phases & Lifecycle · Intermediate
Phase Overview Debug: Trace, Logs, and Traversal Verification
Practical debug workflow for phase ordering confusion — trace switches, diagnostic prints, topology checks, and symptom-to-cause mapping.
First switches to throw
Before waveform debug, enable phase and objection tracing plus a structural print at end_of_elaboration.
[UVM][PHASE] debug boot
sim plusargs:
+UVM_PHASE_TRACE
+UVM_OBJECTION_TRACE
+UVM_CONFIG_DB_TRACE (if cfg suspect)
code:
end_of_elaboration -> print_topology on env
verbosity:
UVM_LOW on PHASE tag in build/connectfunction void build_phase(uvm_phase phase);
super.build_phase(phase);
`uvm_info("PHASE", $sformatf("BUILD %s", get_full_name()), UVM_LOW)
endfunction
function void connect_phase(uvm_phase phase);
super.connect_phase(phase);
`uvm_info("PHASE", $sformatf("CONNECT %s", get_full_name()), UVM_LOW)
endfunction
function void end_of_elaboration_phase(uvm_phase phase);
super.end_of_elaboration_phase(phase);
if (get_type_name() == "my_env")
uvm_top.print_topology();
endfunctionKey takeaways
Phase trace turns ordering arguments into log evidence.
Topology print is the fastest structural sanity check.
PHASE-tagged build/connect logs teach traversal direction viscerally.
Common pitfalls
Jumping to waves before confirming build/connect completed.
Printing only one component — need env + leaf for direction proof.
Leaving +UVM_CONFIG_DB_TRACE on in production regressions — too noisy.
Symptom → cause matrix
Structural symptoms
[PHASE] triage matrix
null handle in connect:
cause: not created in build, or gated create branch wrong
fix: build_phase create + config gating review
override ignored:
cause: override after create, or used new()
fix: override before super.build, use type_id::create
component missing in topology:
cause: lazy create in run_phase
fix: move create to build_phaseRun-time symptoms
[PHASE][RUN] triage matrix
test ends at 0ns:
cause: no objection raised
fix: raise before stimulus, verify drop on all paths
hang forever:
cause: objection leak or unkillable fork
fix: +UVM_OBJECTION_TRACE, audit raise/drop pairs
activity before reset:
cause: stimulus in wrong sub-phase / no reset wait
fix: move to main or post_reset, add explicit waitDeterministic reproduction
Fix seed and run with PHASE trace only (low verbosity).
Capture build/connect order for env and one agent.
Confirm topology before run_phase begins.
If run symptom, capture objection trace through hang or early end.
Only then inspect sequences or RTL waves.
function void report_phase(uvm_phase phase);
super.report_phase(phase);
`uvm_info("PHASE_DBG", $sformatf("seed=%0d phase_trace=on",
$get_initial_random_seed()), UVM_NONE)
endfunctionKey takeaways
Most overview bugs map to five patterns: null connect, override miss, missing topology, objection leak, no objection.
Ordered triage saves hours of wave debug.
Seed plus trace logs are reproducible artifacts for bug reports.
Common pitfalls
Adding random delays to 'fix' ordering seen in trace.
Disabling phase trace too early because log is long — filter with tags.
Fixing report formatting while connect still crashes.