Skip to main content

Module analysis

Module analysis 

Source
Expand description

Analysis: one write, every subscriber hears it (D86–D88; pyuvm uvm_analysis_port, uvm_subscriber, uvm_tlm_analysis_fifo).

§Analysis is not a queue

AnalysisBus and TlmFifo share three letters and nothing else. A TlmFifo is a queue: one consumer takes each item, the producer blocks when it is full, and the item is gone once taken. An AnalysisBus is a broadcast, and it has no queue at all: write calls every subscriber and returns. Nothing is stored, so a write with no subscribers is not buffered for later — it is simply gone, which is legal and is what a monitor nobody listens to should cost. Do not reach for one expecting the other.

To keep the traffic, subscribe and keep it: a subscriber’s write puts the item wherever that component wants it — a Vec, an unbounded TlmFifo, a comparison against a prediction. The hub is not the memory; the subscriber is.

§Why delivery is synchronous

A monitor writes a transaction and moves on within the same simulation instant — the time wheel must not turn because a scoreboard was listening. So write is not async: the publisher’s call runs every subscriber’s handler and returns.

That is only possible because a subscriber shares its state rather than itself. A handler needs &mut its data, and no component can hand out &mut self to a sibling — so the data lives in a RustdvShared, the component keeps one handle, and the port gets another. An earlier design queued items and delivered them later; “later” is exactly what analysis must not do.

§One connection idiom (Ray, 2026-07-24)

The UVM broadcasts straight from a source’s analysis port to subscribers. rustdv’s components are erased, so neither side can reach the other, and analysis gets a hub for the same reason put/get has a FIFO: a concrete #[component] child that the parent owns and can wire.

self.bus.pub_export().connect(&self.mon, Monitor::AP);
self.bus.sub_export().connect(&self.sb, Scoreboard::INPUT);
self.bus.sub_export().connect(&self.cov, Coverage::INPUT);

Several subscribers on one sub_export() is what makes it a broadcast. This is a deliberate divergence from IEEE 1800.2 — which we are not implementing — and one idiom to learn beats two.

Structs§

AnalysisBus
A broadcast hub: one publisher in, every subscriber out.
PublishExport
The publish side of a hub: connect it to a source’s PublishPort.
SubscribeExport
The subscribe side of a hub. Connect as many subscribers to it as you like — that is what makes the write a broadcast.