Skip to content

AMBA AXI · Module 3

Backpressure & Stalls

How a destination de-asserting READY stalls an AXI channel, inserts bubbles, and propagates upstream through a pipeline — and how buffering absorbs it.

READY isn't just "I'm ready" — its absence is a control signal in its own right. When a destination drops READY, it is applying backpressure: telling the source "hold — I can't take a beat this cycle." This is the universal flow-control mechanism of AXI: every channel can be throttled the same way, and in a chain of stages a single slow consumer can ripple a stall all the way back to the producer. This chapter shows backpressure on a waveform, explains the bubbles it inserts, traces how it propagates upstream, and shows how buffering absorbs it. It builds directly on the handshake (3.1) and the transfer event (3.2); throughput math is the next chapter.

1. Backpressure Is READY Saying "Not Yet"

From the handshake contract, a beat transfers only when VALID && READY at a clock edge. The destination therefore has a lever: by holding READY low, it prevents the transfer even though the source is offering. That deliberate withholding is backpressure — the receiver throttling the sender.

The source's obligation during backpressure is exactly the stability rule (3.1): hold VALID high and keep the payload stable until READY finally rises and the beat transfers. So backpressure is a clean, lossless stall — nothing is dropped; the beat simply waits. Because every AXI channel uses the same handshake, every channel supports backpressure identically: a subordinate can backpressure write data (WREADY low), a manager can backpressure read data (RREADY low), and so on. One mechanism, everywhere.

READY backpressure — the destination stalls the source

8 cycles
D0 transfers at cycle 1; the source then holds VALID and D1 while READY is low for cycles 2 to 4; D1 transfers at cycle 5 when READY rises again.stall — destination not READYD0 transfersD0 transfersREADY low → backpressure (D1 held)READY low → backpressu…READY high → D1 transfersREADY high → D1 transf…aclkvalidreadydataXD0D1D1D1D1D2Xt0t1t2t3t4t5t6t7
Figure 1 — backpressure on a channel. The source offers D0 at cycle 1 and it transfers. It then offers D1, but the destination drops READY for cycles 2–4 (backpressure); the source holds VALID and D1 stable through the stall, and D1 transfers only at cycle 5 when READY rises. No data is lost — the beat waits.

2. Bubbles — The Cost of a Stall

Every cycle the handshake doesn't complete is a bubble: the clock ticks, but no beat moves (no transfer event, from 3.2). Backpressure inserts bubbles deliberately — they're the price of matching a fast source to a slower destination. In Figure 1, cycles 2–4 are three bubbles: D1 sat waiting, moving no data, while the clock advanced.

Bubbles are not a bug — they're how flow control works — but they are exactly the lost throughput from Chapter 1.6: beats-per-cycle drops below one whenever a bubble appears. A channel running at full bandwidth has zero bubbles (a beat every edge); a backpressured channel trades bandwidth for the ability to not overrun a slow receiver. The whole point of buffering (below) and of throughput tuning (next chapter) is to minimize avoidable bubbles while keeping the lossless stall when a bubble is genuinely necessary.

3. Backpressure Propagates Upstream

Here's the behaviour that makes backpressure a system property, not a local one. Real datapaths are chains of stages, each connected to the next by a VALID/READY handshake. When the final consumer backpressures, the stall doesn't stay local — it ripples upstream:

  1. The consumer drops its READY, so the last stage can't hand off its beat.
  2. That stage, now holding a beat it can't drain, fills up — so it drops its input READY.
  3. The stage before it can't hand off either, fills, and drops its READY — and so on, back toward the producer.

So a single slow consumer can, stage by stage, stall the entire pipeline back to the source. This is head-of-line blocking in its simplest form: the slowest point throttles everyone upstream of it.

A pipeline of producer, stage 1, stage 2, and consumer. Data flows left to right; when the consumer stalls, backpressure (READY low) propagates right to left through the stages back to the producer.datadatadataREADY lowREADY lowREADY lowProducerstalls lastStage 1fills, then stallsStage 2fills firstConsumerdrops READYBackpressure ripples upstreamREADY low propagates right → left12
Figure 2 — backpressure propagating upstream. The consumer stalls (drops READY); the last stage fills and drops its own input READY; the stall ripples back through each stage to the producer. Data flows downstream (left to right); backpressure flows upstream (right to left). One slow consumer can throttle the whole chain.

4. Buffering Absorbs Transient Backpressure

If every consumer stall instantly froze the producer, throughput would be hostage to the slowest momentary hiccup. The fix is buffering: place a FIFO (or a skid buffer) between producer and consumer. The buffer absorbs transient backpressure — while the consumer is briefly not ready, beats pile into the buffer and the producer keeps running. Only if the buffer fills completely does backpressure finally reach the producer.

A producer feeds a FIFO buffer that feeds a consumer; the buffer absorbs transient backpressure from the consumer so the producer keeps running until the buffer is full.filldrain when READYProducerkeeps flowingFIFO / skid bufferabsorbs transient stallsConsumerstalls briefly12
Figure 3 — buffering decouples producer from consumer stalls. A FIFO between them soaks up beats during a brief consumer stall, so the producer keeps flowing; backpressure only reaches the producer if the buffer fills entirely. Sizing the buffer to the expected stall length is how designs hide transient backpressure.

A pipeline stage's accept/offer logic captures the propagation precisely — it accepts input only when it can drain or has room, which is exactly how a stall ripples back:

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
// Conceptual — one buffered stage. Downstream backpressure (out_ready low)
// propagates to in_ready once the stage can't drain and has no room.
assign out_valid = occupied;                 // I offer a beat when I hold one
assign in_ready  = !occupied || out_ready;   // accept if empty, or I can drain now
// STALL case: occupied && !out_ready  →  in_ready = 0  → upstream is backpressured

Buffering doesn't make backpressure disappear — a sustained slow consumer will still eventually stall the producer once buffers fill. It hides transient stalls. (The skid buffer and FIFO designs that do this without losing throughput are Module 15.)

5. Reactive vs Speculative READY

A subtlety worth knowing: a destination can drive READY two ways. Reactive READY waits to see VALID before asserting — simple, but it costs a cycle of latency on each transfer because the destination only commits to accept after observing an offer. Speculative (or always-ready) READY is asserted ahead of VALID — the destination declares "I can take a beat whenever one arrives," so a transfer happens the instant VALID rises, with no acceptance latency.

Both are legal (recall 3.1: READY may depend on VALID, but need not). The trade-off is latency vs simplicity/area: always-ready gives the best latency and throughput but requires the destination to genuinely always have room (often backed by a buffer); reactive READY is simpler but inserts bubbles. This is a knob designers turn when tuning a path — and a thing to recognize on a waveform when reasoning about why a transfer took an extra cycle.

Speculative READY is asserted before VALID for lowest latency but needs guaranteed room; reactive READY waits for VALID, which is simpler but adds a cycle of latency.Speculative READYasserted before VALIDLowest latencytransfers as soon as VALID rises— needs guaranteed roomReactive READYwaits to see VALIDSimpler, +1 cycleacceptance latency → a bubble12
Figure 4 — two ways to drive READY. Speculative (always-ready) READY is high before VALID, so a beat transfers the moment VALID rises — lowest latency, but needs guaranteed room. Reactive READY waits to see VALID before asserting — simpler, but adds a cycle of acceptance latency (a bubble). Both are legal; it's a latency-versus-simplicity choice.

6. Common Misconceptions

7. Debugging Insight

8. Verification Insight

9. Interview Questions

10. Summary

Backpressure is a destination withholding READY to stall a source — AXI's universal, lossless flow control. The source obeys the stability rule (hold VALID and payload steady), so no beat is lost; the stall simply inserts bubbles (cycles with no transfer event), trading bandwidth for rate-matching. Crucially, backpressure is a system property: in a chain of VALID/READY stages it propagates upstream — a stalled consumer fills the last stage, which backpressures the previous one, rippling all the way to the producer (head-of-line blocking). Buffering (FIFOs, skid buffers) absorbs transient backpressure so the producer keeps running until a buffer fills — it hides hiccups, not a sustained rate mismatch. And a destination can drive READY reactively (simpler, +1 cycle latency) or speculatively/always-ready (lowest latency, needs guaranteed room).

For debugging, follow the backpressure downstream to its origin — the stalled producer is a symptom; the true bottleneck is the stage whose READY is low while its own downstream is ready. For verification, inject random per-channel backpressure and pair it with stability and liveness checks, since always-ready testing is a false pass. With the stall mechanism understood, the next chapter turns it into numbers: how back-to-back transfers and bubbles set sustained throughput.

11. What Comes Next

You understand the stall; now quantify it:

Previous: 3.2 — The Transfer Event. For the broader protocol catalog, see the AMBA family overview doc.