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.
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[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
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[PHASE] conditional analysis wiring
build: if (enable_cov) create cov
connect: if (enable_cov) ap.connect(cov)
run: monitor always writes; disabled subscribers simply absentFIFO and secondary monitor taps
// 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.
[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.