AMBA AXI · Module 16
AXI Functional Coverage
Define functional coverage for AXI — coverpoints for burst type/length/size, IDs, response codes, WSTRB patterns, and handshake/backpressure timing, with cross coverage for the combinations that matter (burst × size, ID × response) — turning a clean assertion/scoreboard run into evidence that the scenarios worth checking were actually exercised.
A clean assertion and scoreboard run only proves the design behaved correctly on the traffic it saw — it says nothing about traffic it never saw. Functional coverage closes that gap: it measures which scenarios were actually exercised, turning "no check fired" into "the interesting cases occurred and were checked." Without it, a passing testbench can hide enormous holes — a slave that's never received a WRAP burst, never seen back-to-back transactions, never returned a SLVERR — and every one of those is an unverified region. This chapter defines AXI functional coverage: the coverpoints for the protocol's variables (burst type/length/size, IDs, responses, WSTRB, timing), the cross coverage for the combinations that matter, and the discipline of reading coverage as the completeness half of verification, paired with the checks from 16.2–16.4.
1. Coverage Is the Completeness Half
Verification has two halves: checking (assertions, scoreboard) confirms correctness when a scenario occurs; coverage confirms the scenario occurred at all. They're independent — a perfect check never triggered by the right stimulus protects nothing, and lots of stimulus with no checks proves nothing. Coverage answers "what did we actually exercise?" and drives stimulus until the answer is "everything that matters."
2. The Core Coverpoints
A covergroup samples the transaction (from the monitor) and bins each protocol variable. The core AXI coverpoints, with bins chosen to separate the values that exercise different behavior:
covergroup axi_cg with function sample(axi_txn t);
// Burst type: the three legal encodings
cp_burst: coverpoint t.burst { bins fixed = {0}; bins incr = {1}; bins wrap = {2}; }
// Burst length: boundaries that matter, not all 256 values
cp_len: coverpoint t.len {
bins single = {0}; // 1-beat
bins small = {[1:3]};
bins mid = {[4:63]};
bins large = {[64:254]};
bins max = {255}; // 256-beat (AWLEN=255)
}
// Transfer size up to bus width
cp_size: coverpoint t.size { bins sizes[] = {[0:$clog2(BYTES)]}; }
// ID space (sample the range, not every value)
cp_id: coverpoint t.id { bins ids[] = {[0:(1<<ID_W)-1]}; }
// Response codes — error responses are high-value
cp_resp: coverpoint t.resp {
bins okay = {0}; bins exokay = {1}; bins slverr = {2}; bins decerr = {3};
}
// WSTRB patterns (write): all-set, sparse, single-byte
cp_strb: coverpoint t.strb_class {
bins full = {FULL}; bins partial = {PARTIAL}; bins single = {SINGLE};
}
endgroupThe art is in the bins: you don't cover all 256 lengths, you cover the classes that exercise distinct logic (1-beat, small, mid, large, the 256-beat max). Error responses (SLVERR/DECERR) get their own bins because they're easy to never hit and high-value to confirm.
3. Cross Coverage: The Combinations That Matter
Individual coverpoints aren't enough — many bugs live in combinations. Cross coverage records which pairs (or tuples) of values co-occurred: burst type × size, length × size (does a max-length narrow transfer happen?), ID × response (does every ID ever see an error?), burst × WSTRB. The skill is crossing the combinations that exercise distinct logic and excluding illegal or uninteresting ones so the cross doesn't explode.
// Cross: every burst type at every size (e.g. WRAP at the narrow sizes)
x_burst_size: cross cp_burst, cp_size;
// Cross: does each ID ever receive an error response?
x_id_resp: cross cp_id, cp_resp;
// Cross: burst type with length class (max-length WRAP is illegal — exclude)
x_burst_len: cross cp_burst, cp_len {
ignore_bins wrap_too_long = binsof(cp_burst.wrap) &&
binsof(cp_len) intersect {[16:255]};
}Excluding the illegal combinations (ignore_bins) is as important as including the legal ones: a WRAP burst can only be 2/4/8/16 beats, so crossing WRAP with the large/max length bins would create coverage goals that can never be hit, permanently blocking closure.
4. Timing/Corner Coverage and the Closure Loop
Beyond payload values, timing and corner scenarios need coverage too — back-to-back transactions, mid-burst stalls (WVALID/RREADY low), maximum outstanding depth, 4 KB-boundary-adjacent bursts, simultaneous read/write. These are sampled from observed timing, not transaction fields. Coverage then drives a closure loop: run, measure coverage, find holes, refine constraints (16.6) to hit them, repeat until the meaningful bins are covered.
5. Common Misconceptions
6. Debugging Insight
7. Verification Insight
8. Interview Questions
9. Summary
Functional coverage is the completeness half of verification: checking (assertions, scoreboard) decides correctness when a scenario occurs, while coverage measures whether each scenario occurred — and both are required, since a perfect check never triggered protects nothing. The core coverpoints bin AXI's variables by distinct behavior — burst type (FIXED/INCR/WRAP), length classes (single/small/mid/large/max, not all 256 values), size, ID range, response codes (with error responses as explicit, high-value bins), and WSTRB pattern classes. Cross coverage records the combinations where bugs hide — burst × size, ID × response, burst × length — and rigorously excludes illegal/unreachable combinations with ignore_bins (so goals stay closable) and illegal_bins (which double as protocol checks). Timing/corner coverpoints sample back-to-back transactions, stalls, outstanding depth, and boundary-adjacent bursts.
Coverage drives a closure loop — run, measure, find holes, refine constraints (16.6) or add directed tests or justify exclusions, repeat — until every meaningful bin is hit and every unhit bin is justified (illegal/excluded or a documented design fact). Read holes as a work list and unreachable bins as design facts. The disciplines: bin by behavior, cross deliberately and exclude rigorously, and read coverage as evidence paired with live checks (a covered bin means exercised and checked). 100% coverage is not bug-free — it measures exercise, the checks decide correctness, and the model only measures what it defines. Coverage closure plus a clean check run is the evidence-based completeness the mindset demanded. Next, we generate the constrained-random traffic that drives coverage toward closure.
10. What Comes Next
You can now measure completeness; next we generate the stimulus that drives it:
- 16.6 — Constrained-Random AXI Traffic (coming next) — generating legal, stressful random AXI stimulus with constraints, the engine that drives coverage toward closure while staying protocol-legal.
Previous: 16.4 — AXI Scoreboards. Related: 7.1 — Burst Fundamentals and 7.4 — WRAP Bursts for the burst variables to cover, and 8.2 — Transaction IDs for the ID space.