Part 4 · TLM & Analysis · Intermediate

Unconnected Port Detection: UVM_WARNING Patterns and print_connections()

How to detect and diagnose missing TLM links with UVM warnings, topology printouts, and endpoint-local assertions.

What unconnected means in practice

A TLM connection is valid only when producer and consumer endpoints are connected through matching port/export/imp topology before run-time traffic starts.

When this is broken, UVM may emit a UVM_WARNING for some endpoint classes, but not all cases are fatal. The safest approach is to enforce explicit connection checks.

diagram
[UVM][TLM] canonical point-to-point chain

producer.put_port  -->  parent.put_export  -->  consumer.put_imp
      [TLM] initiator          [TLM] bridge          [TLM] target

if any arrow is missing:
  - calls may block forever (blocking put/get)
  - item may never reach sink
  - warnings may be non-fatal
diagram
[MON][TLM][SB] analysis broadcast chain

monitor.ap.write(txn)
       │
       ├─> scoreboard.analysis_export
       └─> coverage.analysis_export

if no subscribers:
  write(txn) returns immediately, data is dropped silently
  • Unconnected blocking ports can hang threads; unconnected analysis ports can silently drop data.

  • Connection bugs are best found in connect_phase, not after random stimulus.

  • Detect absence of links explicitly with endpoint checks and audit logs.


Using print_connections() effectively

Most TLM endpoint classes provide diagnostics that summarize current fanout/fanin. Use these right after connect_phase to confirm expected topology.

systemverilog
class my_env extends uvm_env;
  `uvm_component_utils(my_env)

  my_monitor    mon;
  my_scoreboard sb;
  my_cov        cov;

  function void connect_phase(uvm_phase phase);
    super.connect_phase(phase);
    mon.ap.connect(sb.analysis_export);
    mon.ap.connect(cov.analysis_export);
  endfunction

  function void end_of_elaboration_phase(uvm_phase phase);
    super.end_of_elaboration_phase(phase);
    mon.ap.print_connections();
  endfunction
endclass
diagram
[UVM] expected connection audit (conceptual)

mon.ap:
  fanout = 2
    -> sb.analysis_export
    -> cov.analysis_export

unexpected examples:
  fanout = 0     // silent analysis drop risk
  fanout = 1     // one consumer missing
  wrong endpoint // connected to unintended component
systemverilog
function void verify_analysis_wiring();
  int n = mon.ap.size(); // typical analysis_port fanout query
  if (n == 0) begin
    `uvm_fatal("TLM_CONN", "monitor.ap has zero subscribers")
  end
  `uvm_info("TLM_CONN", $sformatf("monitor.ap subscribers=%0d", n), UVM_LOW)
endfunction
  • Run connection dumps at end_of_elaboration for stable hierarchy names.

  • Use fail-fast checks for must-have links such as monitor->scoreboard.

  • Keep expected fanout counts documented and asserted.


Detecting direction and hierarchy mistakes

Another common failure is connecting incompatible endpoint roles (port-to-port, imp-to-imp) or skipping hierarchy pass-through exports.

diagram
[TLM] role compatibility quick guide

legal:
  port   -> export
  export -> export
  export -> imp
  port   -> imp   (in some direct forms)

illegal / suspicious:
  port -> port
  imp  -> imp
  write() endpoint used for put/get path
systemverilog
// BAD: forgot intermediate export hookup
function void connect_phase(uvm_phase phase);
  super.connect_phase(phase);
  // child_mon.ap should connect to parent export first.
  // child_mon.ap.connect(parent_ap_export);  // missing
  parent_ap_export.connect(sb.analysis_export);
endfunction
systemverilog
// GOOD: full chain is explicit and auditable
function void connect_phase(uvm_phase phase);
  super.connect_phase(phase);
  child_mon.ap.connect(parent_ap_export);
  parent_ap_export.connect(sb.analysis_export);
endfunction
  • Validate full source-to-sink chain, including parent exports.

  • Check endpoint role compatibility when refactoring hierarchy.

  • Avoid hidden connect logic in utility methods without logging.


Pre-run connection gate

Treat connectivity as a regression gate: if required links are absent, fail before run_phase. This avoids wasting simulation on invalid topology.

systemverilog
function void start_of_simulation_phase(uvm_phase phase);
  super.start_of_simulation_phase(phase);
  audit_tlm_links();
endfunction

function void audit_tlm_links();
  if (drv.seq_item_port.size() == 0)
    `uvm_fatal("TLM_AUDIT", "driver.seq_item_port is unconnected")

  if (mon.ap.size() == 0)
    `uvm_fatal("TLM_AUDIT", "monitor.ap has no subscribers")

  mon.ap.print_connections();
endfunction
diagram
[UVM][TLM] gate checklist

required checks before run:
  - sequencer <-> driver seq_item path connected
  - monitor analysis fanout >= 1
  - expected analysis sinks present by name
  - no known warning IDs suppressed for connection errors

Key takeaways

  • Use print_connections and explicit fanout checks together.

  • Fail early for mandatory links; do not rely on warnings alone.

  • Direction/hierarchy mistakes are easier to catch with role-based audits.

  • Connection gating at start_of_simulation saves debug time.

Common pitfalls

  • Assuming connect_phase code is correct without post-connect verification.

  • Treating fanout > 0 as sufficient when specific sinks are required.

  • Suppressing connection warning IDs globally in regressions.

  • Allowing testbench to continue after known unconnected critical links.