Skip to content

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.

Driver drives the AXI interface; monitor passively taps it and reconstructs transactions; analysis port broadcasts to scoreboard and coverage.Driver/sequencerdrives busAXI interface5 channelsMonitor (passive)taps, reconstructsAnalysis portbroadcast txnScoreboardcorrectness/orderCoveragescenario tracking12
Figure 1 — the monitor's place in a UVM-style environment. The monitor passively taps the AXI interface (no driving), reconstructs transactions, and broadcasts them through an analysis port to subscribers — a scoreboard (correctness/ordering) and a coverage collector. The driver/sequencer drive the bus separately; the monitor observes the result. Passivity means it works identically on a testbench-driven or RTL-driven interface.

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.

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
// 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
endtask

This 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.

Monitor observes AW beat, W data beats to WLAST, and matching B response, assembling them into one write transaction object.AXI busMonitorAnalysis portAW: id=3, addr,len=3W beat 0W beat 1W beat 2W beat 3 (WLAST)B: id=3, OKAYwrite txn {id=3, data[4], OKAY}write txn{id=3, data[4]…
Figure 2 — reconstructing a write transaction from scattered beats. The monitor observes the AW beat (address, ID), then the stream of W data beats up to WLAST, then the matching B response (same ID). It assembles these into one transaction object — address, data array, response — and broadcasts it. Read transactions are assembled symmetrically from AR plus R beats to RLAST, matched by ID.

The reconstruction logic, sketched for the write side:

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
// 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:

Per-ID lifecycle: address opens context, data beats accumulate to last, response closes and broadcasts, context freed.noyesAW/AR → OPENcontext (by ID)W/R beats →ACCUMULATEWLAST/RLAST?B / final R → CLOSE+ broadcastfree context
Figure 4 — the per-ID transaction lifecycle in the monitor. An address beat OPENS a context (keyed by ID); data beats ACCUMULATE into it until the last beat (WLAST/RLAST); the response (matched by ID) CLOSES it, the assembled transaction is broadcast, and the context is freed. Because each ID has its own context (ideally a queue), interleaved and out-of-order bursts are reassembled correctly — same-ID in order, different-ID independent.

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.

Monitor analysis port broadcasts one transaction to scoreboard, coverage, and logger subscribers simultaneously; monitor decoupled from subscribers.Monitorap.write(txn)Analysis port1 → manyScoreboardsubscriberCoveragesubscriberLoggersubscriberDecoupledadd subs freely12
Figure 3 — the analysis-port broadcast. The monitor's analysis port (write()) publishes each completed transaction to all subscribers at once — scoreboard, coverage collector, protocol logger — via their analysis exports. The monitor is decoupled from the subscribers: it doesn't know who listens, so subscribers can be added or removed without changing the monitor. One observation, many consumers.

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.