Part 6 · Agents & Protocol IP · Intermediate

connect_phase Wiring: Structural Links and Invariant Enforcement

Wire agent internals in connect_phase with explicit guards, mode-aware checks, and wrapper-level analysis export patterns.

Connect responsibilities

connect_phase is where agent topology becomes operational. It must connect both active pull path and passive analysis path with mode-aware guards.

diagram
[UVM][AGT] connect map

always:
  mon.ap.connect(agt.ap)

if active:
  drv.seq_item_port.connect(sqr.seq_item_export)

if passive:
  assert drv/sqr absent
diagram
[AGT] connection intent

sequence traffic:
  sequence -> sequencer -> driver

observation traffic:
  monitor -> agent.ap -> subscribers
  • Centralize all component links in connect_phase.

  • Ensure analysis path is connected in every mode.

  • Guard active-only links with explicit checks.


Reference connect_phase code

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

  if (mon == null || ap == null)
    `uvm_fatal("AGT_CONN", "monitor/ap missing")
  mon.ap.connect(ap);

  if (is_active == UVM_ACTIVE) begin
    if (drv == null || sqr == null)
      `uvm_fatal("AGT_CONN", "active mode missing drv/sqr")
    drv.seq_item_port.connect(sqr.seq_item_export);
  end
  else begin
    if (drv != null || sqr != null)
      `uvm_error("AGT_CONN", "passive mode should not keep drv/sqr")
  end
endfunction
diagram
[UVM] post-connect checks

end_of_elaboration:
  print topology
start_of_simulation:
  run one-item smoke if active
run_phase:
  monitor counter increments regardless of mode
  • Use fatal for broken required links and shape mismatches.

  • Keep passive-path checks strict to prevent hidden active behavior.

  • Pair connection checks with tiny smoke probes.


Wrapper re-export pattern for multiple streams

Monitors may publish multiple streams (transactions, beats, errors). Re-export all required streams from wrapper instead of exposing monitor internals.

systemverilog
class stream_agent extends uvm_agent;
  `uvm_component_utils(stream_agent)
  stream_monitor mon;
  uvm_analysis_port #(stream_item) tr_ap;
  uvm_analysis_port #(stream_beat) beat_ap;

  function void build_phase(uvm_phase phase);
    super.build_phase(phase);
    mon = stream_monitor::type_id::create("mon", this);
    tr_ap = new("tr_ap", this);
    beat_ap = new("beat_ap", this);
  endfunction

  function void connect_phase(uvm_phase phase);
    super.connect_phase(phase);
    mon.tr_ap.connect(tr_ap);
    mon.beat_ap.connect(beat_ap);
  endfunction
endclass
diagram
[AGT] re-export benefits

env wiring remains wrapper-centric
monitor internals stay private
stream expansion does not break existing consumers

Key takeaways

  • connect_phase should be the single source of agent link truth.

  • Analysis path must remain available in both active and passive modes.

  • Mode-aware assertions prevent silent topology corruption.

  • Wrapper-level re-exports preserve encapsulation as stream count grows.

Common pitfalls

  • Scattering connections across phases and helper threads unpredictably.

  • Forgetting to connect monitor stream to wrapper analysis port.

  • Allowing passive agents to retain active handshake links.

  • Exposing monitor internal ports directly to environment wiring.