Part 2 · Phases & Lifecycle · Intermediate

connect_phase Walkthrough: Env Wiring Timeline

Step-by-step connect_phase execution from leaf driver to env fanout — with logging hooks and phase-trace interpretation.

Full connect timeline

After build completes, connect walks the same tree in reverse order — deepest children first.

diagram
[PHASE][UVM] annotated connect timeline

T0        drv.connect_phase (leaf)
T1        mon.connect_phase (leaf)
T2        sqr.connect_phase (leaf)
T3      agt_tx.connect_phase
            drv.seq_item_port  sqr.seq_item_export
T4        sb.connect_phase (leaf imp ready)
T5        cov.connect_phase
T6      agt_rx.connect_phase
T7    env.connect_phase
          agt_tx.mon.ap  sb.tx_imp
          agt_tx.mon.ap  cov.tx_export
          agt_rx.mon.ap  sb.rx_imp
          v_sqr.tx_sqr = agt_tx.sqr
          v_sqr.rx_sqr = agt_rx.sqr
T8  test.connect_phase (optional)
T9  connect complete  end_of_elaboration_phase
systemverilog
function void connect_phase(uvm_phase phase);
  super.connect_phase(phase);
  `uvm_info("PHASE_CONNECT",
    $sformatf("enter %s", get_full_name()), UVM_MEDIUM)
  // ... wiring ...
  `uvm_info("PHASE_CONNECT",
    $sformatf("exit  %s", get_full_name()), UVM_MEDIUM)
endfunction

Key takeaways

  • Connect logging pairs with build logging for full elaboration transcript.

  • Env connect is the integration layer — agent connect is intra-agent.

  • Phase trace shows bottom-up order as reverse of build trace.

Common pitfalls

  • Env connect before agent internal drv-sqr link — ordering violation if forced manually.

  • Assuming connect order matches build order — it is reversed, not identical.

  • Missing connect log on env — hardest layer to debug without it.


Reference env connect implementation

Complete env connect_phase showing analysis fanout, virtual sequencer map, and null guards.

Env connect scaffold

systemverilog
class chip_env extends uvm_env;
  tx_agent      agt_tx;
  rx_agent      agt_rx;
  chip_scoreboard sb;
  chip_coverage   cov;
  chip_virtual_sqr v_sqr;

  function void connect_phase(uvm_phase phase);
    super.connect_phase(phase);

    // intra-agent links already done in agent.connect_phase

    // analysis fanout
    agt_tx.mon.ap.connect(sb.tx_act_imp);
    agt_rx.mon.ap.connect(sb.rx_act_imp);
    if (cfg.enable_coverage) begin
      agt_tx.mon.ap.connect(cov.tx_export);
      agt_rx.mon.ap.connect(cov.rx_export);
    end

    // virtual sequencer map
    if (agt_tx.cfg.is_active == UVM_ACTIVE)
      v_sqr.tx_sqr = agt_tx.sqr;
    if (agt_rx.cfg.is_active == UVM_ACTIVE)
      v_sqr.rx_sqr = agt_rx.sqr;
  endfunction
endclass

Trace interpretation

diagram
[PHASE] +UVM_PHASE_TRACE connect debug

grep CONNECT logs + PHASE_TRACE EXIT connect_phase

Expected: leaf components EXIT before parents ENTER
Anomaly:  env ENTER before agt_tx EXIT  investigate forced phase jump

Pair with print_topology after connect to verify graph
  • Run smoke test with PHASE_TRACE after build debug passes.

  • Verify fanout count matches number of ap.connect calls.

  • Confirm v_sqr handles non-null for every active agent.

Common pitfalls

  • Debugging connect without confirming build topology first.

  • Comparing traces across tests with different passive/active cfg.

  • Ignoring super.connect_phase in trace — missing base wiring.