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.
[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[UVM] misleading signal pattern
PASS indicators:
+ sequence completed
+ no fatal in run_phase
hidden failure:
- checker never evaluated transaction streamAnalysis 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.
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
endclassfunction 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[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-zeroGuard 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.
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[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 intactfunction void write(txn_item t);
counters.sb_received++;
// ... scoreboard model/update/check
counters.sb_checked++;
endfunctionCounter 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.
[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 countersfunction 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")
endfunctionKey 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.