AMBA AXI · Module 16
AXI Assertions (SVA)
Write the core AXI protocol assertions in SystemVerilog Assertions — the handshake rules (VALID stable until READY, VALID not waiting on READY), payload stability ($stable while VALID held), and structural/encoding checks — with the concurrent-assertion idioms, disable-on-reset, and binding pattern that make them reusable across any AXI interface.
The protocol-checker mindset (16.1) produced a categorised rule catalog; this chapter turns the per-cycle rules into executable SystemVerilog Assertions (SVA). We'll write the core checks for the two categories that are naturally cycle-by-cycle — handshake and payload stability — plus the structural/encoding checks, using the concurrent-assertion idioms (property, |->, $stable, $rose, disable iff) that every AXI assertion set relies on. (The ordering/transaction rules that span beats are better handled by monitors and scoreboards in 16.3–16.4.) The goal is a set of assertions you can bind onto any AXI interface and trust — the executable form of the rule catalog, and the engine inside every protocol VIP.
1. The Anatomy of an AXI Assertion
A concurrent SVA assertion has a fixed shape: a clocking event, a disable condition (almost always reset), an antecedent (the trigger), and a consequent (what must then hold). Nearly every AXI rule fits the pattern "when this is observed, that must be true on the relevant cycles."
// Template: every AXI assertion shares this skeleton
property p_example;
@(posedge aclk) disable iff (!aresetn)
antecedent |-> consequent; // |-> same cycle, |=> next cycle
endproperty
a_example: assert property (p_example)
else $error("AXI violation: <rule> at %0t", $time);The disable iff (!aresetn) is essential: during reset the bus is not expected to be compliant, so every AXI assertion is disabled while reset is asserted. The |-> (overlapping) and |=> (non-overlapping) implication operators express "in the same cycle" vs. "starting next cycle" — the choice matters for getting the timing of a rule exactly right.
2. Handshake Assertions
The handshake category produces three canonical checks per channel. Shown for the write-address (AW) channel; the same three apply to W, B, AR, R by signal substitution.
// (H1) VALID must remain asserted, with no change, until READY accepts it.
property p_awvalid_stable;
@(posedge aclk) disable iff (!aresetn)
(awvalid && !awready) |=> awvalid;
endproperty
a_awvalid_stable: assert property (p_awvalid_stable)
else $error("AWVALID deasserted before AWREADY");
// (H2) Once asserted, VALID is held — equivalently it may only fall the cycle
// after a completed handshake (this is the dual of H1).
// (H3) VALID must not depend combinationally on READY (no deadlock).
// Checked structurally / formally: prove awvalid has no comb. path from
// awready. In simulation, a liveness check guards against the hang:
property p_aw_progress; // an asserted request is eventually accepted
@(posedge aclk) disable iff (!aresetn)
awvalid |-> s_eventually awready;
endproperty
a_aw_progress: assert property (p_aw_progress)
else $error("AWVALID never accepted — possible deadlock");H1 (stability of VALID) is the everyday workhorse; the liveness check (H3) guards the deadlock rule that 16.1 flagged as fatal. Note H3's combinational-independence is ideally proven structurally/formally (no logic path awready → awvalid), with the liveness assertion as the simulation backstop.
3. Payload-Stability Assertions
The stability category checks that every payload field stays constant while its VALID is held and not yet accepted — the $stable built-in is exactly the tool. One assertion per payload field per channel (often grouped):
// (S1) All AW payload fields stable while AWVALID held and not yet accepted.
property p_aw_payload_stable;
@(posedge aclk) disable iff (!aresetn)
(awvalid && !awready) |=>
$stable(awaddr) && $stable(awlen) && $stable(awsize) &&
$stable(awburst)&& $stable(awid) && $stable(awprot) &&
$stable(awcache)&& $stable(awlock);
endproperty
a_aw_payload_stable: assert property (p_aw_payload_stable)
else $error("AW payload changed while AWVALID held");
// (S2) W payload stable while WVALID held.
property p_w_payload_stable;
@(posedge aclk) disable iff (!aresetn)
(wvalid && !wready) |=> $stable(wdata) && $stable(wstrb) && $stable(wlast);
endproperty
a_w_payload_stable: assert property (p_w_payload_stable)
else $error("W payload changed while WVALID held");
// (S3) Read-data payload stable while RVALID held.
property p_r_payload_stable;
@(posedge aclk) disable iff (!aresetn)
(rvalid && !rready) |=> $stable(rdata) && $stable(rresp) &&
$stable(rlast) && $stable(rid);
endproperty
a_r_payload_stable: assert property (p_r_payload_stable)
else $error("R payload changed while RVALID held");$stable(x) is true when x has the same value as the previous clock — so "VALID held last cycle ⇒ payload unchanged this cycle" exactly encodes the stability rule. The |=> (next-cycle) form is correct here because $stable compares against the prior sample.
4. Structural Assertions and Reset Behavior
The structural/encoding category checks legal field values and combinations — immediate, single-cycle conditions on the payload (only meaningful when VALID). Plus a few reset-behavior checks that do apply during/after reset:
// (E1) Burst type is never the reserved encoding (2'b11).
property p_awburst_legal;
@(posedge aclk) disable iff (!aresetn)
awvalid |-> (awburst != 2'b11);
endproperty
a_awburst_legal: assert property (p_awburst_legal)
else $error("Reserved AWBURST encoding");
// (E2) Transfer size never exceeds the data bus width.
property p_awsize_legal;
@(posedge aclk) disable iff (!aresetn)
awvalid |-> ((1 << awsize) <= (DATA_W/8));
endproperty
a_awsize_legal: assert property (p_awsize_legal)
else $error("AWSIZE exceeds bus width");
// (E3) WRAP bursts have a legal length (2, 4, 8, or 16 beats).
property p_wrap_len_legal;
@(posedge aclk) disable iff (!aresetn)
(awvalid && awburst == 2'b10) |-> (awlen inside {1, 3, 7, 15});
endproperty
a_wrap_len_legal: assert property (p_wrap_len_legal)
else $error("Illegal WRAP burst length");
// (R1) RESET behavior: all VALIDs must be low during reset.
property p_reset_valids_low;
@(posedge aclk) (!aresetn) |-> (!awvalid && !wvalid && !arvalid
&& !bvalid && !rvalid);
endproperty
a_reset_valids_low: assert property (p_reset_valids_low)
else $error("A VALID was high during reset");Note R1 is not disabled on reset — it specifically checks the reset behavior (all VALIDs low), so it must be active exactly when reset is asserted.
When a structural or handshake assertion fires, the failure is pinned to a cycle and a signal, as the waveform shows:
Payload-stability assertion firing
7 cyclesThe whole set is deployed and trusted via one pattern: write the assertions once in a checker module, bind it to every AXI interface, then prove the set is sound (inject violations → each fires) and non-vacuous (antecedent coverage):
5. Common Misconceptions
6. Debugging Insight
7. Verification Insight
8. Interview Questions
9. Summary
AXI assertions encode the per-cycle rules of the catalog as SystemVerilog Assertions. Every concurrent assertion shares one skeleton — @(posedge aclk) disable iff (!aresetn) antecedent |-> / |=> consequent — where disable iff (!aresetn) suppresses checks during reset and the implication operator selects same-cycle (|->) vs. next-cycle (|=>) timing. The handshake category yields, per channel, the VALID-held-until-READY stability check (the workhorse), its deassert-timing dual, and a liveness backstop for the deadlock rule (with combinational independence proven formally). The payload-stability category uses (valid && !ready) |=> $stable(field) for every payload field — $stable comparing to the prior sample is the exact tool. The structural/encoding category uses same-cycle |-> checks gated on VALID for legal BURST/SIZE/WRAP-length and reserved encodings, plus a reset-behavior check (all VALIDs low) that deliberately stays active during reset.
The cross-beat ordering/transaction rules are not forced into per-cycle SVA — they're delegated to monitors and scoreboards (16.3–16.4) that hold transaction state. Assertions are deployed as a bound checker module (bind) so they attach to any interface without editing RTL and are reusable as VIP. Crucially, the assertion set must itself be verified — injected violations confirm each fires (soundness), antecedent coverage confirms each is exercised (non-vacuity), the catalog mapping confirms completeness, and formal proves the structural/liveness subset. Next, we build the passive monitor that reconstructs transactions so the stateful ordering rules can be checked.
10. What Comes Next
You can now check the signal-local rules; next we reconstruct transactions to check the stateful ones:
- 16.3 — AXI Monitors (coming next) — a passive monitor that observes the bus and reconstructs complete transactions, the bridge from per-cycle assertions to transaction-level checking.
Previous: 16.1 — The Protocol-Checker Mindset. Related: 3.5 — Handshake Dependency & Deadlock Rules for the handshake rules these assertions encode, 7.4 — WRAP Bursts for the legal WRAP lengths, and 6.8 — RRESP, BRESP & RLAST for the response/last rules.
Continue learning
Related tutorials
- Related topic
AMBA — AHB · APB · AXI
ARM's AMBA family — channels, handshakes, ordering rules, and verification strategy.
- Related topic
AXI4 Write Channel — AW, W & B Handshake
The AMBA 5 AXI4 write path — AW/W/B channels, the VALID/READY handshake, channel-dependency rules, and BRESP write-response semantics.
- Related topic
The AMBA Family Overview
Where APB sits among the AMBA generations (APB, AHB, AXI, ACE, CHI), and how a modern SoC layers them by traffic class.
- Related topic
APB vs AHB vs AXI
How handshake, pipelining, and bandwidth differ across the three classic AMBA buses, and the tradeoffs that decide which one a block deserves.
Standards & specifications
- Governing standard
- Arm AMBA AXI Protocol Specification (IHI 0022)(opens Arm in a new tab)
Defines the AXI channels, handshake and ordering rules. RTL structure, interconnect topology and verification strategy are design choices this specification does not mandate.
This page also covers RTL structure, verification approach and debugging technique. Those are engineering practice built on the standard, not requirements the standard itself imposes.
Where this fits
Part of the AMBA AXI curriculum.
