A network interface receives packets from a link and must get them into memory. One design has the interface push each packet into memory as it arrives. Another has a DMA engine pull packets out of the interface's buffer when it has room. Both move the same bytes. One needs a large buffer in the interface; the other needs almost none, but makes the link wait.
Does it matter which side starts a transfer, and how do you choose?
It is tempting to treat "who starts" as a detail, since the data ends up in the same place either way. But the side that starts a transfer is the side that decides when data moves, and the other side must be ready to deal with it at that moment. That decides where data waits when the two sides run at different speeds, and so where the buffers must be and how big.
Push | Pull | |
|---|---|---|
Who starts | The producer, when it has data | The consumer, when it wants data |
Where data waits if the other side is slow | At the consumer (or the producer is stalled) | At the producer, until it is asked for |
Back-pressure | The consumer must say "wait" (ready, credits) | Built in: the consumer only asks for what it can take |
Latency | Data moves as soon as it exists | Data waits for a request: a round trip before it moves |
Valid/ready sits between the two: the producer pushes (raises valid), but a consumer that holds ready low until it wants data is effectively pulling. Credits (Part 4) are pull in disguise: the consumer grants permission in advance, one slot at a time, so the producer pushes only what has been asked for.
With illustrative numbers: packets arrive from a link at 10 Gb/s in bursts of up to 64 KB, and memory is sometimes busy for up to 20 µs.
Push into memory: while memory is busy, arriving data must wait somewhere. 20 µs at 10 Gb/s is 200,000 bits, about 25 KB, so the interface needs at least that much buffering, or it must push back on the link.
Pull by DMA: the DMA asks for data when memory is free. Data waits in the interface's receive buffer, which must still absorb the link's bursts, because the link cannot be paused instantly: the buffering moved, it did not vanish.
The lesson is general: with a producer that cannot be paused (a link, a sensor), someone must buffer the difference in rates. Push or pull only decides who holds that buffer and who controls when it drains.
Choose | When | Watch out for |
|---|---|---|
Push | The producer cannot wait (a link, a sensor) or latency matters most | The consumer needs buffering or back-pressure |
Pull | The consumer has the limited resource (memory bandwidth, buffer space) and should control it | The round-trip latency of every request |
Push with credits | Long paths where the consumer's buffer must never overflow and latency matters | Credit sizing (lesson 4.5) |
Protocol | Push or pull |
|---|---|
SPI | The master pulls and pushes at once: it drives the clock, so every bit moves when the master decides, in both directions. A slave cannot start anything or slow the master down. |
AXI read channel | The master pulls: it asks for data with a read request and the slave pushes the data back on the read data channel, where the master may still push back with RREADY. |
PCI Express | Writes are pushed (posted) by the requester; reads are pulled with a request and answered by completions. Credits keep pushes from overflowing the receiver. |
A design uses a pull interface across a long path (illustrative): the consumer requests one word, waits for it to arrive, then requests the next. The round trip is 20 cycles, so it moves one word every 20 cycles and runs at 5% of the link's rate, even though both sides are idle most of the time. Pull needs several requests in flight to cover the round trip, exactly the outstanding-transaction idea of Part 6, or it turns latency into lost throughput.
No. The difference in rates must be buffered somewhere; pull only moves the buffer to the producer side and lets the consumer decide when it drains.
The consumer grants each credit when it has a free slot, so the producer only sends what the consumer has, in effect, asked for.
One word per 10 cycles, 10% of one word per cycle, unless it keeps several requests in flight.
Push: the producer starts and the consumer must cope; pull: the consumer starts and never gets more than it asked for.
The choice decides where data waits and who controls when buffers drain; it does not remove the need to buffer rate differences.
Credits are pull in disguise; pull and credits both need enough requests in flight to cover the round trip.