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.

diagram
[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 agent
systemverilog
function 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
endfunction

Key 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

diagram
[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 existence
systemverilog
function 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")
endfunction

Reproduction checklist

  1. Reproduce with smoke_test and passive/active cfg documented.

  2. Capture build log — verify gated components not created.

  3. Capture connect log — identify first failing connect call.

  4. Print topology — confirm imp components present.

  5. Verify port type parameters match across connect pair.

  6. 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.