AMBA AXI · Module 3
Handshake Throughput
Turn AXI handshakes into numbers — back-to-back transfers, bubbles, utilization (beats per cycle), and the bytes-per-second bandwidth they produce.
So far the handshake has been about whether a beat moves. This chapter is about how fast. The peak any AXI channel can do is one beat per cycle — a transfer event on every rising edge — and everything else is measured against that ceiling. A bubble (a cycle with no transfer) drops you below it, so sustained throughput is just beats ÷ cycles, and real bandwidth is that utilization times the beat width times the clock. We'll watch full back-to-back transfer, watch bubbles cut it in half, turn beats-per-cycle into bytes-per-second, and see the classic registered-handshake trap that silently halves throughput. This builds on the transfer event (3.2) and backpressure (3.3); the deadlock rules are next.
1. The Ceiling — One Beat Per Cycle
A single AXI channel transfers at most one beat per clock cycle — because a beat needs one transfer event (VALID && READY at an edge), and there's one edge per cycle. That's the ceiling. "Full throughput," "100% utilization," "line rate" on a channel all mean the same thing: a beat every cycle, no gaps.
To actually hit it, both sides must cooperate every cycle: the source keeps VALID high with a fresh beat each cycle, and the destination keeps READY high to take one each cycle. Miss either, even for one cycle, and that cycle is a bubble.
Back-to-back transfer — 100% utilization
8 cycles2. Utilization — Beats Per Cycle
Throughput on a channel is one ratio:
Utilization = beats transferred ÷ cycles elapsed.
A utilization of 1.0 is the ceiling (a beat every cycle); 0.5 means half the cycles were bubbles; 0.0 is a stalled channel. This is precisely the beat-vs-cycle distinction from Chapter 1.6, now used as a measurement: count transfer events (beats), divide by clock cycles, and you have utilization over that window. Everything that throttles a channel — backpressure, a slow source, latency overhead — shows up as utilization below 1.0, and the gap from 1.0 is your wasted bandwidth.
3. Bubbles Cut Throughput
Any cycle without a transfer event is a bubble, and each one drops utilization. The most common pattern is a source (or destination) that can only act every other cycle — instantly halving throughput.
Bubble insertion — 50% utilization
8 cyclesA bubble can come from either side: the source can't produce a beat every cycle (a slow producer, or one that needs a recovery cycle), or the destination backpressures (READY low, Chapter 3.3). On a waveform they look the same — a cycle where the transfer condition is false — but the cause (and fix) differs by which signal is low.
4. From Beats Per Cycle to Bytes Per Second
Utilization is dimensionless; bandwidth is the number people actually quote. Convert with the beat width and the clock:
Bandwidth = utilization × (data-bus bytes per beat) × clock frequency.
So a 128-bit (16-byte) channel at 1 GHz running at full utilization moves 16 bytes × 1.0 × 1 GHz = 16 GB/s; at 50% utilization, 8 GB/s. This is why two things dominate AXI bandwidth tuning: bus width (bytes per beat) and utilization (keeping beats-per-cycle near 1.0). Clock frequency is usually fixed by the design, so the levers an architect actually pulls are wider beats and fewer bubbles.
A monitor measures exactly this — count beats on transfer events, count cycles, divide:
// Conceptual — sustained throughput over a window.
if (valid && ready) beats++; // a transfer event (one beat)
cycles++; // every clock
// utilization = beats / cycles // 1.0 = a beat every cycle
// bandwidth = utilization * DATA_BYTES * F_CLK // bytes/sec5. Sustaining Full Throughput
Hitting 1.0 utilization is a cooperation requirement on both ends, every cycle:
- The source must have the next beat ready and
VALIDhigh continuously — no recovery cycles, no waiting to compute the next payload. - The destination must keep
READYhigh continuously — enough buffering/drain capacity to never need to stall.
Bursts help on the source side (one address, then a beat every cycle of data), and buffering helps on the destination side (absorb transient stalls, Chapter 3.3). But the bar is strict: a single bubble per N beats caps utilization at N/(N+1). For back-to-back streaming, you need zero avoidable bubbles — which is exactly what makes the next pitfall so important.
6. The Registered-Handshake Trap
A subtle, extremely common bug: naively registering a VALID/READY interface to fix timing inserts a bubble on every transfer, halving throughput to 50%. The mechanism: if a stage registers its output and can only hold one beat, it must de-assert its input READY for a cycle after each transfer to drain — so it accepts a beat, stalls a cycle, accepts the next, stalls again. One beat every two cycles.
The fix is the skid buffer (sometimes "register slice"): a 2-deep design that registers the interface for timing and sustains one beat per cycle, by having a spare slot to "skid" into so it never has to drop READY. It's the canonical way to break a long VALID/READY timing path without paying throughput.
This is one of the most-asked AXI interview topics and a real bring-up bug — a path that "works" but mysteriously runs at half bandwidth. The full skid-buffer RTL is Module 15; here, recognize the symptom (50%) and the cause (a single-register handshake that can't hold while draining).
7. Peak vs Sustained
Two numbers people conflate. Peak throughput is the ceiling — one beat per cycle, the best the channel can ever do. Sustained throughput is what you actually measure over a real window, after bubbles from backpressure, source gaps, burst boundaries, and latency. Sustained is always ≤ peak, and the ratio is utilization.
Datasheets quote peak (width × frequency); engineers live in sustained. The gap between them is the sum of every bubble cause in the system — which is why "what's your achieved utilization?" is a sharper question than "what's the peak bandwidth?" The performance modules (13) are largely about closing that gap.
8. Common Misconceptions
9. Debugging Insight
10. Verification Insight
11. Interview Questions
12. Summary
A single AXI channel tops out at one beat per cycle — a transfer event every edge — and utilization = beats ÷ cycles measures how close you get. Every bubble (a cycle with no transfer, from a stalled destination or a source that can't offer) drops utilization below 1.0, and the gap is wasted bandwidth. Turn it into the number people quote with bandwidth = utilization × beat-bytes × frequency: width and utilization are the tunable levers, since frequency is usually fixed. Sustaining 1.0 demands both sides cooperate every cycle (continuous VALID, continuous READY), aided by bursts and buffering.
The classic trap is the naive registered handshake, which halves throughput by dropping READY to drain each beat — fixed by a skid buffer that registers for timing without bubbles. Debug throughput by measuring utilization and attributing bubbles to the low signal (source vs destination), watching for the 50% registered-handshake signature. Verify it explicitly — a correct-but-slow bug is invisible to data checkers — with a performance monitor and coverage of both back-to-back and bubbly rates. With throughput quantified, the last handshake topic is the rule set that keeps decoupled, backpressured channels from deadlocking.
13. What Comes Next
You can now measure and reason about channel throughput. Module 3 closes with the safety rules underneath all this concurrency:
- 3.5 — Handshake Dependency & Deadlock Rules (coming next) — the cross-channel dependency graph (which VALID/READY may wait for which) that prevents deadlock across decoupled, backpressured channels.
- 3.6 — Common Handshake Bugs (coming soon) — the recurring handshake mistakes and how to spot them.
Previous: 3.3 — Backpressure & Stalls. For the broader protocol catalog, see the AMBA family overview doc.