AMBA AXI · Module 16
AXI Monitors
Build a passive AXI monitor that observes the five channels and reconstructs complete transactions from beats — sampling handshakes, matching write data to addresses and responses by ID, assembling read bursts to RLAST, and broadcasting transaction objects through an analysis port to scoreboards and coverage.
Assertions (16.2) check signal-local rules cycle by cycle, but the stateful rules — beat counts, per-ID ordering, data integrity — live at the transaction level, and to check them you first need to reconstruct transactions from the raw beats on the bus. That's the monitor's job. An AXI monitor is passive: it never drives the bus, only observes it, sampling the five channels' handshakes and assembling the scattered beats of each burst into a complete transaction object, which it then broadcasts to scoreboards and coverage collectors. This chapter builds the monitor — what it samples, how it matches write data to addresses and responses by ID, how it assembles read bursts, and how it publishes transactions through an analysis port — making it the bridge from the per-cycle world of assertions to the transaction-level world of scoreboards (16.4) and coverage (16.5).
1. The Monitor's Place and Passivity
A monitor sits at an AXI interface and only observes — it taps the signals, never asserts VALID/READY or drives any line. It reconstructs transactions and sends them out an analysis port to any number of subscribers (scoreboard, coverage, protocol log). Because it's passive, the same monitor works whether the interface is driven by a testbench agent or by real RTL, and multiple monitors can watch different points (manager side, subordinate side, interconnect ports) of the same path.
2. Sampling Beats on the Handshake
The monitor's atomic action is sampling a beat exactly when it transfers — on every cycle where VALID && READY is high for a channel. It captures the payload at that instant into a per-channel record. Nothing is sampled on stalled cycles, so the monitor sees exactly the beats that actually moved.
// Passive sampling: capture each channel's beat on its completed handshake
task automatic monitor_run();
forever begin
@(posedge vif.aclk);
if (!vif.aresetn) continue;
// Write address beat
if (vif.awvalid && vif.awready)
capture_aw('{id:vif.awid, addr:vif.awaddr, len:vif.awlen,
size:vif.awsize, burst:vif.awburst});
// Write data beat
if (vif.wvalid && vif.wready)
capture_w('{data:vif.wdata, strb:vif.wstrb, last:vif.wlast});
// Write response beat
if (vif.bvalid && vif.bready)
capture_b('{id:vif.bid, resp:vif.bresp});
// Read address beat
if (vif.arvalid && vif.arready)
capture_ar('{id:vif.arid, addr:vif.araddr, len:vif.arlen,
size:vif.arsize, burst:vif.arburst});
// Read data beat
if (vif.rvalid && vif.rready)
capture_r('{id:vif.rid, data:vif.rdata, resp:vif.rresp, last:vif.rlast});
end
endtaskThis is the same VALID && READY transfer condition the assertions use — the monitor and the assertions agree on exactly when a beat exists.
3. Reconstructing a Transaction
Captured beats are scattered across channels and cycles; the monitor assembles them into a transaction. For a write: collect the AW (address/params), accumulate W beats until WLAST, then match the B response — tied together by AWID/BID. For a read: collect the AR, then accumulate R beats (each with its own RRESP) until RLAST, tied by ARID/RID. Outstanding transactions are tracked in per-ID structures so concurrent, interleaved bursts are reassembled correctly.
The reconstruction logic, sketched for the write side:
// Per-ID outstanding write context, keyed by AWID
typedef struct { axi_addr_t addr; int len; data_t data[$]; bit have_aw; } wctx_t;
wctx_t wctx [int]; // associative array, key = id
function void on_aw(aw_beat b); wctx[b.id].addr = b.addr;
wctx[b.id].len = b.len;
wctx[b.id].have_aw = 1; endfunction
function void on_w(w_beat b, int id); // id from matching the open burst
wctx[id].data.push_back(b.data);
if (b.last) begin /* data phase complete; await B */ end
endfunction
function void on_b(b_beat b); // B closes the transaction
axi_txn t = build_write_txn(wctx[b.id], b.resp);
ap.write(t); // broadcast completed transaction
wctx.delete(b.id);
endfunction(Matching W beats to the right open burst is the subtle part: AXI write data is in order per the address stream, so the monitor associates the in-progress W stream with the outstanding write — implementations track the current write burst and its ID accordingly.)
Each transaction therefore moves through a small lifecycle in the per-ID context, and tracking it per ID is what untangles concurrent, interleaved bursts:
4. Broadcasting Through the Analysis Port
Once a transaction is complete, the monitor publishes it on its analysis port (uvm_analysis_port), which broadcasts to every subscribed component without the monitor knowing or caring who listens. This decoupling is what lets one monitor feed a scoreboard, a coverage collector, and a logger simultaneously, and lets you add subscribers without touching the monitor.
5. Common Misconceptions
6. Debugging Insight
7. Verification Insight
8. Interview Questions
9. Summary
An AXI monitor is the passive component that turns raw bus activity into transaction-level information. It taps the interface without driving it, samples each channel's beat exactly on its completed handshake (VALID && READY — the same condition the assertions use), and reconstructs transactions by gathering beats across channels and cycles: for a write, the AW opens a context, W beats accumulate to WLAST, and the B (matched by ID) closes it; for a read, the AR opens it and R beats (each with its own RRESP) accumulate to RLAST. Per-ID context structures — ideally per-ID queues — let it correctly reassemble multiple outstanding, interleaved, and out-of-order transactions, mirroring AXI's ordering model. Completed transactions are broadcast through an analysis port, which decouples the monitor from its subscribers so one monitor feeds a scoreboard, coverage collector, and logger at once.
The monitor's discipline is to reconstruct independently (from observed traffic, never DUT internals), stay passive and check-free (reconstruction here, checking in the scoreboard, measuring in coverage), and be verified itself against scripted known traffic — especially interleaved multi-ID bursts and out-of-order completion, where reconstruction bugs hide and masquerade as scoreboard failures. As the source of truth for transaction-level verification, the monitor is the bridge from per-cycle assertions to the scoreboard and coverage built next. Next, we feed its transaction stream into a scoreboard that checks data integrity and ordering against a reference.
10. What Comes Next
You can now reconstruct transactions; next we check them for correctness:
- 16.4 — AXI Scoreboards (coming next) — a scoreboard that checks data integrity and ordering by comparing the monitor's reconstructed transactions against a reference model.
Previous: 16.2 — AXI Assertions (SVA). Related: 8.3 — Same-ID Ordering and 8.4 — Different-ID Ordering for the ordering model the monitor must mirror, and 16.1 — The Protocol-Checker Mindset for where the monitor fits in the verification stack.