Part 2 · Phases & Lifecycle · Intermediate

Analysis Connect Patterns: Broadcast, Fanout, and FIFOs

Monitor analysis_port wiring to scoreboards, coverage, and FIFOs — one-to-many broadcast and subscriber discipline.

Analysis broadcast model

A monitor's uvm_analysis_port broadcasts observed transactions to every connected imp. One write() call delivers a copy to scoreboard, coverage, and any other subscriber.

systemverilog
class my_monitor extends uvm_monitor;
  uvm_analysis_port #(my_txn) ap;
  function new(string name, uvm_component parent);
    super.new(name, parent);
    ap = new("ap", this);
  endfunction
  // in run_phase: ap.write(observed_txn);
endclass

class my_env extends uvm_env;
  function void connect_phase(uvm_phase phase);
    super.connect_phase(phase);
    agt.mon.ap.connect(sb.act_imp);
    agt.mon.ap.connect(cov.analysis_export);
  endfunction
endclass
diagram
[PHASE][UVM] analysis fanout diagram

        ┌─────────┐
        │ monitor │
        │   ap    │
        └────┬────┘
             │ write(txn)
     ┌───────┼───────┐
     ▼       ▼       ▼
   ┌───┐   ┌───┐   ┌──────┐
   │sb │   │cov│   │fifo  │
   │imp│   │imp│   │export│
   └───┘   └───┘   └──────┘

Key takeaways

  • analysis_port is broadcast — one monitor feeds many checkers.

  • Each subscriber implements write() via uvm_analysis_imp.

  • Connect every subscriber imp in connect_phase before run_phase.

Common pitfalls

  • Subscriber imp not created — connect to null.

  • Writing from monitor before connect_phase completes.

  • Expecting analysis delivery order across subscribers — not guaranteed.


Advanced fanout patterns

Production envs combine scoreboard checking, functional coverage, protocol checkers, and FIFO taps on the same analysis stream.

Conditional subscriber wiring

systemverilog
function void connect_phase(uvm_phase phase);
  super.connect_phase(phase);
  agt.mon.ap.connect(sb.act_imp);
  if (cfg.enable_coverage)
    agt.mon.ap.connect(cov.analysis_export);
  if (cfg.enable_protocol_checker)
    agt.mon.ap.connect(proto_chk.analysis_export);
endfunction
diagram
[PHASE] conditional analysis wiring

build:   if (enable_cov) create cov
connect: if (enable_cov) ap.connect(cov)
run:     monitor always writes; disabled subscribers simply absent

FIFO and secondary monitor taps

systemverilog
// tap for passive checker or reference model input
agt.mon.ap.connect(ref_model.fifo.analysis_export);

// second monitor on different interface
agt_rx.mon.ap.connect(sb.rx_imp);
  • Name imps distinctly: act_imp, exp_imp, rx_imp — aids debug.

  • Scoreboard often has two imps: actual and expected streams.

  • Avoid circular analysis paths — write should not loop back.

diagram
[PHASE][UVM] scoreboard dual-imp pattern

monitor_actual.ap   sb.act_imp   (write  compare queue)
monitor_expect.ap   sb.exp_imp   (write  compare queue)
ref_model.ap        sb.exp_imp   (alternative expected path)

Common pitfalls

  • Connecting same imp twice — analysis connect error.

  • Coverage imp type mismatch with port parameter.

  • Heavy write() work in imp blocking monitor throughput.