Part 4 · TLM & Analysis · Intermediate

Silent Drop Scenarios: Writes to Unconnected Analysis Paths

How analysis transactions can be dropped without immediate errors, and how to instrument and enforce subscriber presence.

Why analysis drops are dangerous

An analysis_port.write(txn) call usually returns immediately even with zero subscribers. Simulation continues, but checkers/coverage may never see traffic.

This creates false confidence: stimulus appears to run, DUT toggles, but scoreboard remains empty because the observation path is disconnected.

diagram
[MON][TLM][SB] silent-drop anatomy

monitor captures bus item
   │
   ├─ builds txn object
   │
   └─ ap.write(txn)  ---------------------> (no subscribers)
                                            dropped silently

symptom:
  - monitor logs increment
  - scoreboard seen count stays zero
  - no immediate fatal unless instrumented
diagram
[UVM] misleading signal pattern

PASS indicators:
  + sequence completed
  + no fatal in run_phase

hidden failure:
  - checker never evaluated transaction stream
  • Analysis write is broadcast-style and non-blocking by design.

  • Zero-subscriber paths require explicit guardrails.

  • Silent drops can invalidate functional checking with no hard failure.


Subscriber presence guards

Add lightweight guards at publication points so empty fanout is detected immediately during bring-up and optionally enforced in regressions.

systemverilog
class my_monitor extends uvm_component;
  `uvm_component_utils(my_monitor)
  uvm_analysis_port #(txn_item) ap;
  bit require_subscriber = 1;

  function void publish(txn_item t);
    int n = ap.size();
    if (n == 0) begin
      if (require_subscriber)
        `uvm_fatal("TLM_DROP", "analysis_port has zero subscribers")
      else
        `uvm_warning("TLM_DROP", "analysis_port drop: zero subscribers")
    end
    ap.write(t);
  endfunction
endclass
systemverilog
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 start_of_simulation_phase(uvm_phase phase);
  super.start_of_simulation_phase(phase);
  if (mon.ap.size() < 1)
    `uvm_fatal("TLM_AUDIT", "monitor must have >=1 analysis subscriber")
endfunction
diagram
[UVM][TLM] policy by simulation stage

bring-up:
  allow warning + detailed trace

pre-commit regression:
  enforce fatal on zero subscribers for critical monitors

nightly:
  aggregate drop counters and fail on non-zero
  • Guard at source monitor for fastest fault localization.

  • Use policy toggles to balance bring-up flexibility vs regression strictness.

  • Audit both critical and optional subscribers separately.


End-to-end observability counters

Maintain stage counters (published, received, checked) to expose where loss occurs. Counter deltas are often more informative than raw logs.

systemverilog
class tlm_obs_counters extends uvm_component;
  `uvm_component_utils(tlm_obs_counters)
  int mon_published;
  int sb_received;
  int sb_checked;

  function void report_phase(uvm_phase phase);
    `uvm_info("TLM_COUNT",
      $sformatf("published=%0d received=%0d checked=%0d",
        mon_published, sb_received, sb_checked),
      UVM_LOW)

    if (mon_published != sb_received)
      `uvm_error("TLM_DROP",
        "publish/receive mismatch indicates analysis-path loss")
  endfunction
endclass
diagram
[UVM][TLM] counter interpretation

published == 100, received == 0
  -> likely disconnected analysis path

published == 100, received == 100, checked == 0
  -> sink receives but checker logic bypasses

published == received == checked
  -> observation pipeline intact
systemverilog
function void write(txn_item t);
  counters.sb_received++;
  // ... scoreboard model/update/check
  counters.sb_checked++;
endfunction
  • Counter mismatches pinpoint loss boundary quickly.

  • Report counters in all tests, not only debug tests.

  • Keep publish/receive/check counter names consistent project-wide.


Hardening against silent analysis failures

Move from ad-hoc debug to institutional safeguards: connection audits, source guards, and CI checks that fail on drop signatures.

diagram
[UVM] hardening checklist

source side:
  - assert subscriber count for critical monitor ports
  - emit connection map at start_of_simulation

sink side:
  - count receives and checks
  - fail if expected stream absent

regression:
  - parse logs for TLM_DROP / TLM_AUDIT IDs
  - fail build on non-zero drop counters
systemverilog
function void final_phase(uvm_phase phase);
  super.final_phase(phase);
  if (counters.mon_published > 0 && counters.sb_received == 0)
    `uvm_fatal("TLM_SILENT_DROP",
      "Published traffic never reached scoreboard")
endfunction

Key takeaways

  • Analysis writes can silently drop when fanout is zero.

  • Guard subscriber presence at source monitor publication points.

  • Use publish/receive/check counters to localize loss stages.

  • Enforce drop-free behavior with regression-level gates.

Common pitfalls

  • Assuming no UVM error means analysis path is healthy.

  • Only checking connection counts once and never re-auditing after refactors.

  • Logging drops as warnings forever without promotion to test failures.

  • Not tracking end-to-end counters, forcing manual log archaeology.