Every protocol must decide what happens when the receiver is not ready. Read across for one protocol; read down to see how widely the answers differ.
Protocol | How the receiver pushes back | Granularity | Transfers in flight |
|---|---|---|---|
UART (basic) | It cannot: the receiver must take every character | None | One character at a time on the line |
SPI | It cannot: the master drives the clock and decides when every bit moves | None | One transfer |
I2C | Clock stretching (a slave holds SCL low); a receiver may also not acknowledge a byte | Per bit (stretching), per byte (acknowledge) | One transfer |
APB | Wait states: the access phase lasts until PREADY is high | Per transfer | One |
AXI | VALID/READY on each of its channels | Per transfer on each channel | Many (Part 6) |
AXI-Stream | TVALID/TREADY | Per transfer | A stream |
CDC handshakes | Request/acknowledge: the sender waits for ack | Per word | One word |
PCI Express | Credits: the sender may only send what the receiver advertised (Part 4) | Per packet, per credit type | Many |
Ethernet | Lossy by default: frames may be dropped; PAUSE and priority flow control can stop a sender | Per link or per priority | Many |
Simple buses push back on one transfer at a time (wait states, stretching): easy, but the initiator is blocked.
On-chip streams use valid/ready: per-cycle agreement, any number of transfers in sequence, latency-insensitive.
Long links use credits, because a per-cycle ready would arrive many cycles late: the skid-buffer rule (spare buffering = how late the stop arrives) scaled up to a whole round trip.
Some protocols have no back-pressure at all and push the problem to buffering or to the application (UART, SPI, lossy Ethernet).