Part 2 · Phases & Lifecycle · Intermediate
connect_phase Debug: Null Handles and Binding Failures
Deterministic triage for connect-time null derefs, double-bind errors, type mismatches, and passive/active wiring bugs.
Symptom matrix
Connect failures are almost always traceable to build-phase decisions or wrong TLM pairing.
[PHASE][UVM] connect-phase triage matrix
SYMPTOM LIKELY CAUSE
─────────────────────────────────────────────────────────
null pointer in connect build did not create component
UVM_FATAL CONNECT drv/sqr active/passive branch mismatch
port already connected double connect in build+connect
type mismatch at connect wrong #(T) on port vs export
analysis write goes nowhere ap.connect never called
v_sqr handle null at seq.start connect map missing or passive agentfunction void connect_phase(uvm_phase phase);
super.connect_phase(phase);
if (cfg.is_active == UVM_ACTIVE) begin
if (drv == null || sqr == null)
`uvm_fatal("CONNECT",
$sformatf("%s: active but drv=%p sqr=%p", get_full_name(), drv, sqr))
drv.seq_item_port.connect(sqr.seq_item_export);
end
endfunctionKey takeaways
Null at connect → go back to build_phase conditional branches.
Defensive fatals with get_full_name() save hours of gdb-style debug.
print_topology after connect confirms what was actually wired.
Common pitfalls
Patching null checks without fixing build branching.
Connecting passive agent driver 'just in case'.
Ignoring UVM warning about already-connected port.
Deterministic debug toolkit
Use this ordered checklist before diving into monitor or sequence internals.
Debug commands
[PHASE] connect debug recipe
simv +UVM_TESTNAME=smoke_test \
+UVM_PHASE_TRACE \
+UVM_VERBOSITY=UVM_MEDIUM
Steps:
1) confirm build_phase log shows component created
2) grep CONNECT fatal / null
3) uvm_top.print_topology()
4) compare cfg.is_active vs components in tree
5) trace ap.connect call sites vs imp existencefunction void end_of_elaboration_phase(uvm_phase phase);
super.end_of_elaboration_phase(phase);
uvm_top.print_topology();
if (v_sqr.tx_sqr == null && agt_tx.cfg.is_active == UVM_ACTIVE)
`uvm_error("CONNECT_DBG", "active tx agent but v_sqr.tx_sqr null")
endfunctionReproduction checklist
Reproduce with smoke_test and passive/active cfg documented.
Capture build log — verify gated components not created.
Capture connect log — identify first failing connect call.
Print topology — confirm imp components present.
Verify port type parameters match across connect pair.
Fix build/connect guard parity, rerun exact failing cfg.
Keep a passive-only smoke variant to test monitor-only paths.
Diff topology between active and passive cfg runs.
Log every ap.connect with subscriber full name at UVM_HIGH.
Key takeaways
Connect debug is build debug in disguise — check construction first.
end_of_elaboration topology print is the connect audit checkpoint.
Guard parity between build and connect prevents most null failures.
Common pitfalls
Adding connect in run_phase as workaround — breaks methodology.
Disabling scoreboard instead of fixing missing imp.
Skipping rerun with exact plusarg that exposed passive/active mismatch.