Part 11 · Senior Prep · Intermediate

Analysis Port & Subscriber Interview Q&A

Model answers on uvm_analysis_port broadcast, uvm_subscriber, fan-out patterns, and zero-subscriber behavior.

Analysis port broadcast semantics

Analysis port is the workhorse of UVM checking — senior answers must cover fan-out, type parameterization, and silent drop behavior.

Q: How does analysis_port write() work with multiple subscribers?

diagram
[INT][SENIOR][UVM] MODEL ANSWER

Q: analysis_port multiple subscribers?

A:
  MECHANISM:  write(t) broadcasts to all connected imps — each subscriber write()
              called in connection order; initiator does not wait for completion.
  MOTIVATION:  Monitor observes once; scoreboard, coverage, predictor consume same txn
              without monitor knowing how many consumers exist.
  WHEN:       Standard monitor.ap fan-out in env.connect_phase — 2 to N subscribers.
  PITFALL:    Subscriber write() with heavy compute blocks other subscribers in same
              simulation time slot — one slow subscriber delays all (cooperative SV).
  EXAMPLE:    mon.ap  scb.imp + cov_sub.imp + predictor.imp — one write(), three
              parallel consumers, monitor unaware of fan-out count.

Q: What happens with zero subscribers on analysis_port?

diagram
[INT][SENIOR][UVM] MODEL ANSWER

Q: Zero subscribers on analysis_port?

A:
  MECHANISM:  write() with no connected imp is silent no-op — no error, no warning
              by default. Transaction disappears.
  MOTIVATION:  Allows optional subscribers — passive monitor works with or without
              scoreboard connected (bring-up mode).
  WHEN:       end_of_elaboration ap.size() check to catch accidental no-connect.
              UVM_HIGH display for first write() diagnostic in debug builds.
  PITFALL:    Forgetting connect in generate loop for agt[3] — 3 of 4 agents wired,
              one agent's txns silently dropped, scoreboard partial compare passes wrongly.
  EXAMPLE:    Forgot scb connect on agt_rx only — TX scoreboard works, RX empty,
              bug hidden until specific seed hits RX-only failure mode.

Q: uvm_subscriber vs custom analysis imp?

diagram
[INT][SENIOR][UVM] MODEL ANSWER

Q: uvm_subscriber vs custom imp?

A:
  MECHANISM:  uvm_subscriber#(T) extends uvm_component with built-in analysis_export
              and write(T t) virtual method — standard coverage subscriber base.
  MOTIVATION:  Eliminates boilerplate imp declaration — override write() for sampling.
  WHEN:       Coverage subscribers, simple logging taps, protocol checkers consuming
              one stream. Custom imp_decl for multi-stream scoreboard write_tx/write_rx.
  PITFALL:    Extending uvm_subscriber when component needs multiple analysis exports —
              one subscriber one stream; use separate subscribers or imp_decl.
  EXAMPLE:    axi_cov_sub extends uvm_subscriber#(axi_item) — write() samples
              covergroup; connect mon.ap to cov_sub.analysis_export.

Q: Must analysis port type parameter match exactly?

diagram
[INT][SENIOR][UVM] MODEL ANSWER

Q: analysis_port type parameter match?

A:
  MECHANISM:  uvm_analysis_port#(T) must connect to imp #(T) with identical T — base/derived
              covariance follows SV assignment rules for write argument.
  MOTIVATION:  Type safety prevents connecting AXI monitor to APB scoreboard silently —
              compile-time catch on type mismatch.
  WHEN:       Use common base txn class if multiple protocol variants share subscriber.
              Derived txn connects to base imp if write accepts base type.
  PITFALL:    Parameter typo uvm_analysis_port#(axi_item) vs imp#(axi_trans) — compile
              error (good) or wrong typedef alias mismatch across packages.
  EXAMPLE:    mon ap#(eth_frame) to scb imp#(eth_frame) — exact match. Generic subscriber
              imp#(uvm_sequence_item) accepts derived if write casts safely.

Key takeaways

  • analysis write broadcasts to all imps — non-blocking for initiator.

  • Zero subscribers = silent drop — check ap.size() in end_of_elaboration.

  • uvm_subscriber#(T) is standard single-stream coverage pattern.

Common pitfalls

  • Heavy compute in subscriber write() blocking sibling subscribers.

  • Partial connect in generate loop — some agents silently unwired.


Fan-out architecture patterns

Q: Draw and explain monitor → scoreboard + coverage fan-out

diagram
[INT][SENIOR][UVM] MODEL ANSWER

Q: Monitor fan-out architecture?

A:
  MECHANISM:  Single monitor.ap connects to multiple imps in env.connect — each subscriber
              write() invoked per transaction broadcast.
  MOTIVATION:  Separation of concerns — monitor captures once; checking (scb) and
              metrics (cov) are independent consumers that can be enabled/disabled.
  WHEN:       env.connect_phase: ap.connect(scb.imp); ap.connect(cov.analysis_export);
              optional ap.connect(predictor.imp).
  PITFALL:    Separate monitors for scb and cov — duplicate sampling, divergence if
              one monitor has filter bug.
  EXAMPLE:    One axi_monitor per interface; fan-out to axi_scb + axi_cov + ref_model;
              disable cov via config without touching monitor or scb code.

Q: How do you disable coverage without disconnecting TLM?

diagram
[INT][SENIOR][UVM] MODEL ANSWER

Q: Disable coverage without disconnect?

A:
  MECHANISM:  coverage subscriber write() checks cfg.enable_coverage flag — early return
              without sampling. Connection remains; overhead is one if-check per txn.
  MOTIVATION:  Disconnect/reconnect at runtime is fragile — config knob in write() is
              standard pattern for optional subscribers.
  WHEN:       Nightly fast mode: +ENABLE_COV=0 sets cfg; cov write() returns immediately.
  PITFALL:    Not connecting cov at all in fast mode — connect_phase ifdef changes
              topology between regressions, hides connect bugs.
  EXAMPLE:    cov_sub.write(): if (!cfg.enable_coverage) return; cg.sample(txn); —
              same topology all regressions, coverage optional via cfg.
diagram
[INT][SENIOR][UVM] fan-out with optional subscriber

  mon.ap ──► scb.imp          (always connected)
         ──► cov_sub.imp       (connected, gated by cfg.enable_coverage)
         ──► predictor.imp     (connected if ref model enabled)

  prefer cfg gate over dynamic connect/disconnect

Q: Analysis port across hierarchy levels — env vs agent connect?

diagram
[INT][SENIOR][UVM] MODEL ANSWER

Q: Connect at env or agent level?

A:
  MECHANISM:  Agent internal connect (drv↔sqr) in agent.connect. Cross-component
              connect (monscb) in env.connect — parent has handles to all agents and scb.
  MOTIVATION:  Agent reusable without scoreboard reference — env owns integration wiring.
              VIP policy: agent exposes analysis_export, env connects subscriber.
  WHEN:       Internal agent TLM in agent.connect. External fan-out in env.connect.
  PITFALL:    Scoreboard connect inside agent — agent now depends on scb type, not
              reusable VIP.
  EXAMPLE:    Reusable axi_agent: mon.apanalysis_export in agent. Chip env connects
              agt[i].analysis_export to chip_scb[i].imp — block agent unchanged.

Q: Predictor + scoreboard both subscribe — ordering concern?

diagram
[INT][SENIOR][UVM] MODEL ANSWER

Q: Predictor and scoreboard ordering?

A:
  MECHANISM:  analysis_port calls subscribers in connect order — no guaranteed scb before
              predictor unless connect order enforced.
  MOTIVATION:  If scb needs predicted result before actual compare, predictor must run
              first — or scb queues actual until predict arrives (preferred decoupling).
  WHEN:       Connect predictor before scb if scb write uses predicted queue synchronously.
              Better: scb async compare with timeout — ordering-independent.
  PITFALL:    Assuming UVM guarantees subscriber execution order across simulators —
              connect order may vary; design for ordering independence.
  EXAMPLE:    scb write_actual queues txn; write_predict fills exp queue; compare
              when both queues have matching id — order of subscriber calls irrelevant.

Key takeaways

  • One monitor, fan-out to scb/cov/predictor — never duplicate monitors.

  • Cfg-gate optional subscribers instead of dynamic connect/disconnect.

  • Cross-component connect belongs in env.connect, not inside agent.

Common pitfalls

  • Agent depends on scoreboard type — breaks VIP reuse.

  • Relying on subscriber call order instead of async compare queues.