AMBA APB · Module 14
Why APB Is Not Pipelined
The architectural reason APB cannot overlap transfers — each transfer's SETUP and ACCESS belong to one transfer and the next cannot begin until the current completes. Pipelining would require the buffering and address/data decoupling that contradict APB's whole purpose as a dead-simple, low-power control bus.
You have used one fact in every cost argument of this module — APB transfers don't overlap, so each pays its full 2 + N with no burst bonus. Chapters 14.1 and 14.2 consumed that fact to derive latency and throughput. This chapter asks the deeper question: why? Why can a bus like AHB overlap one transfer's address phase with the previous transfer's data phase, while APB structurally cannot? The single idea to carry: APB is unpipelined by design, not by accident — overlapping transfers would require the buffering, address/data-phase decoupling, and per-slave handshake complexity that contradict APB's entire reason for existing (a dead-simple, low-power, low-gate control bus). The lack of a pipeline is a feature you bought in exchange for trivial slaves and tiny logic — accepted deliberately, not a flaw to be fixed.
1. Problem statement
The problem is explaining the architectural cause of APB's serial behaviour — not merely restating that transfers don't overlap, but showing why the protocol structurally forbids overlap, so an engineer can defend the design choice rather than treat it as a missing feature.
Performance chapters lean on "APB can't pipeline" as a given. But "can't" has a precise structural meaning that you must be able to articulate:
- Each transfer owns the bus for both its phases. An APB transfer is two-phase: SETUP (
PSELhigh,PENABLElow) then ACCESS (PENABLEhigh untilPREADY). The manager drives one address/control set, and the selected slave is committed for the whole two-phase transfer. There is no second address/control set in flight, so there is nothing for a "next" transfer's SETUP to occupy while the current ACCESS runs. - The next SETUP cannot begin until the current ACCESS completes. The manager's state machine moves IDLE → SETUP → ACCESS → (back to SETUP or IDLE). It only re-enters SETUP after ACCESS finishes. That serial state progression is the protocol — there is no path in which SETUP of transfer N+1 coexists with ACCESS of transfer N.
- Pipelining would require machinery APB deliberately omits. Overlapping address and data phases (as AHB does) needs an address-to-data pipeline register, decoupled address/data handshakes, and a slave that can accept a new address while still returning old data. APB has none of these — and adding them would make it not-APB.
So the job is to explain why the structure serialises transfers, why that structure was chosen, and why "no pipeline" is the right answer for a control bus — the architectural reason behind the cost facts the rest of the module uses.
2. Why previous knowledge is insufficient
You already used the no-pipeline fact. In 14.1, latency anatomy you learned a transfer costs exactly 2 + N with "no overlap term"; in 14.2, throughput you learned back-to-back transfers don't amortise SETUP because APB can't pipeline. What you have not done is explain the cause:
- You learned the consequence, not the mechanism. 14.1 stated "there is no overlap term" and 14.2 stated "no burst bonus" — both asserted the serialisation to do the math. This chapter supplies the why: the manager drives one address/control set at a time and the slave is held for the whole two-phase transfer, so there is structurally nothing to overlap. The cost facts become consequences of a design choice you can now justify.
- You have seen a pipeline elsewhere but not contrasted it. AHB's pipelined operation overlaps phases by design; AHB's two-phase pipeline decouples address and data with a pipeline register. Knowing AHB does overlap is not the same as understanding why APB cannot — the contrast is the lesson, and it reveals exactly which machinery APB omits to stay simple.
- You know APB exists to be simple, but not what simplicity costs structurally. Why APB exists and the APB2 baseline frame APB as the low-power, low-gate control bus. This chapter shows that the no-pipeline property is a direct, deliberate consequence of that goal: pipelining is precisely the complexity APB was built to avoid.
So the model to add is causal: serialisation is not a limitation bolted on after the fact — it falls directly out of the one-transfer-at-a-time structure APB chose so its slaves could be trivial.
3. Mental model
The model: an APB bus is a single-lane checkout with one cashier and one customer at a time. A customer (transfer) steps up (SETUP), is served (ACCESS), and only when they finish and leave does the next customer step up. There is no conveyor belt staging the next customer's items while the current one pays — one lane, one customer, start-to-finish. AHB, by contrast, is a checkout with a conveyor: the next customer's items are already being scanned (address phase) while the current customer pays (data phase). The conveyor is the pipeline register; APB simply doesn't have one.
Three refinements make it precise:
- One address/control set, held for the whole transfer. The manager drives
PADDR,PWRITE,PWDATA,PSELfor this transfer, and holds them stable through SETUP and ACCESS untilPREADY. There is no second set of address/control wires staged behind it — so there is no "next transfer's address" that could be presented during the current ACCESS. - The slave is selected for the entire two-phase transfer.
PSELto the addressed slave stays high across SETUP and ACCESS. A pipeline would need the slave to accept a new address while still completing the old data — APB's singlePSEL/single-address model gives it no way to be doing two things at once. - The state machine progresses serially, by definition. SETUP → ACCESS → (SETUP again only after ACCESS). There is no protocol state where SETUP(N+1) and ACCESS(N) coexist. The serialisation is the protocol, not a property layered on top — which is exactly why the cost is a clean
2 + Nper transfer with nothing to amortise.
4. Real SoC implementation
In real RTL, the serialisation is not enforced by extra logic — it falls out of the manager's two-phase state machine. The FSM simply has no transition that starts a new SETUP while an ACCESS is unfinished. The block below shows the structural cause, with comments contrasting what a pipeline would demand.
// APB manager FSM: structurally one transfer at a time.
// Note what is ABSENT — there is no address/data buffer and no path
// that starts SETUP(N+1) while ACCESS(N) is still in flight.
typedef enum logic [1:0] { IDLE, SETUP, ACCESS } apb_state_t;
apb_state_t state, next;
always_comb begin
next = state;
unique case (state)
IDLE: if (req) next = SETUP; // a new transfer may start
SETUP: next = ACCESS; // SETUP is always exactly one cycle
ACCESS: if (pready) begin
// completion. ONLY here can the next transfer begin its SETUP.
next = req ? SETUP : IDLE; // back-to-back => SETUP again, NOT overlap
end
// if !pready: stay in ACCESS (wait state). The next transfer
// still cannot start — the bus is owned until PREADY.
endcase
end
always_ff @(posedge pclk or negedge presetn) begin
if (!presetn) state <= IDLE;
else state <= next;
end
// One address/control set, held stable for the WHOLE transfer:
assign psel = (state == SETUP) || (state == ACCESS);
assign penable = (state == ACCESS);
// paddr/pwrite/pwdata are loaded at SETUP and held until PREADY — there is
// no second (staged) address register behind them.
// ---------------------------------------------------------------------------
// What PIPELINING would have required (and why it would no longer be APB):
// - an address-to-data PIPELINE REGISTER, so the manager could present
// transfer N+1's address while transfer N's data is still returning;
// - DECOUPLED address-phase and data-phase handshakes (separate "address
// accepted" vs "data ready"), instead of one PREADY for the whole transfer;
// - a SLAVE able to latch a new address while still completing the old read,
// i.e. per-slave buffering and outstanding-transfer tracking.
// All of that is exactly the gate count, power, and slave complexity APB
// was created to avoid. Omitting it IS the design — see /protocols/ahb/two-phase-pipeline.
// ---------------------------------------------------------------------------Two facts make this the right way to see the cause. First, the serialisation is structural, not policed — there is no "wait for previous transfer" guard anywhere; the FSM simply re-enters SETUP only out of a completed ACCESS, so overlap is unrepresentable, not merely disallowed. Second, the absent machinery is the whole point: a pipeline would need the address/data register, decoupled handshakes, and a smarter slave listed in the comment — the very complexity that would inflate gate count and power and make slaves hard to write, which is precisely what APB exists to avoid (see why APB exists). The implementation doesn't prevent pipelining; it simply never built the mechanism that would enable it.
5. Engineering tradeoffs
Pipelining is a genuine trade, not a free win. AHB buys overlap-driven throughput by paying for buffering, decoupled handshakes, and slave complexity; APB declines the purchase to keep slaves trivial and logic tiny.
| Dimension | Pipelined (AHB) | Unpipelined (APB) |
|---|---|---|
| Address/data overlap | Yes — address phase of T(N+1) overlaps data phase of T(N) | None — SETUP(N+1) only after ACCESS(N) completes |
| Buffering required | Address-to-data pipeline register; outstanding-transfer state | None — one address/control set, held for the whole transfer |
| Slave complexity | Higher — must accept a new address while completing old data | Trivial — select, respond, drive PREADY; one thing at a time |
| Handshake | Decoupled address-accept vs data-ready | Single PREADY for the whole two-phase transfer |
| Gate cost / power | Higher — buffers, decode, control for overlap | Minimal — the explicit goal of APB |
| Throughput | Up to ~1 transfer/cycle in a burst (overlap amortises) | 1 / (2 + N) per cycle, no burst bonus |
| Right for | High-bandwidth memory/DMA traffic | Low-bandwidth control/configuration registers |
The throughline: pipelining and simplicity are the two ends of one trade. AHB spends gates, power, and slave complexity to win overlap; APB spends throughput to win a dead-simple slave and a tiny footprint. For a control bus — sparse register writes, not bandwidth-bound streaming — the APB end of the trade is the correct engineering choice. "No pipeline" is not a weakness here; it is the deliberately chosen side of a deliberate trade.
6. Common RTL mistakes
7. Debugging scenario
The signature "bug" here is not a logic error — it is an architectural costing mistake: an engineer who assumed APB would pipeline like AHB, budgeted a peripheral region for pipelined throughput, and then found real traffic running at half the assumed rate because APB serialises.
- Observed symptom: a peripheral-configuration region was budgeted at ~5 cycles for a burst of four back-to-back register writes (assuming ~1 transfer/cycle), but the subsystem measures ~8 cycles for the same burst — roughly double — and a boot-time configuration sequence misses its timing budget. Every transfer is functionally correct; the aggregate rate is wrong.
- Waveform clue: decomposing the trace shows no overlap between consecutive transfers — each transfer shows a full SETUP cycle (
PSELhigh,PENABLElow) followed by an ACCESS cycle (PENABLEhigh,PREADYhigh), and the next transfer's SETUP begins only on the cycle after the previousPREADY. There is never a cycle where one transfer'sPENABLE-high ACCESS coincides with another transfer'sPENABLE-low SETUP. The expected pipelined overlap simply isn't there. - Root cause: the architect's throughput model assumed an AHB-style pipeline (address of T(N+1) overlapping data of T(N)). APB has no such pipeline — the manager drives one address/control set at a time and the slave is held for the whole two-phase transfer, so each transfer costs its full
2 + Nand the burst rate is1 / (2 + N)with no overlap. The budget used the wrong structural model, not the wrong RTL. - Correct RTL: there is nothing to fix in the RTL — the serial behaviour is correct APB. The fix is in the model and the placement: re-cost the region with the serial
2 + N-per-transfer math (the burst is4 × 2 = 8cycles for zero-wait, not 5), and if the region genuinely needs higher throughput, relocate the bursty traffic onto a pipelined bus (AHB/AXI) rather than expecting APB to overlap. Where it stays on APB, accept the serial rate as the design point. - Verification assertion: assert that no overlap is even possible — the next SETUP never asserts while the previous ACCESS is incomplete:
assert property (@(posedge pclk) disable iff(!presetn) (psel && penable && !pready) |-> ##1 (penable || !psel));— i.e. while in an unfinished ACCESS (PENABLEhigh,PREADYlow), the very next cycle is still that same ACCESS (stillPENABLEhigh) or the transfer ends (PSELdeasserted), never a freshPSEL-high/PENABLE-low SETUP of a new transfer overlapping it. Pair it with a performance coverpoint that the back-to-back burst rate matches1 / (2 + N). - Debug habit: when an APB region "runs slower than budgeted" with every transfer correct, don't hunt for a logic bug — check the throughput model. APB never pipelines, so any budget that assumed overlap is wrong by construction. Confirm the absence of overlap on the waveform, re-cost with serial
2 + N, and decide between accepting the serial rate or moving the traffic to a pipelined bus.
8. Verification perspective
Because the no-pipeline property is structural, verification's job is to prove the serialisation holds — that no two transfers ever overlap, that each SETUP follows the previous transfer's completion, and that the serial rate is what the system budgeted against.
- Assert no transfer overlap, ever. The core property is that a new transfer's SETUP (
PSELhigh,PENABLElow for a fresh address) never coexists with another transfer's in-flight ACCESS. Equivalently, whilePENABLEis high andPREADYlow (unfinished ACCESS), the next cycle is still that ACCESS or the transfer ends — never a new transfer's first cycle. This proves the bus carries exactly one transfer at a time, which is the whole no-pipeline claim. - Assert SETUP follows the previous completion. Check that every entry into SETUP for a back-to-back transfer is preceded by a completed ACCESS (
PENABLE && PREADY) of the prior transfer — i.e. the FSM only re-enters SETUP out of completion. This catches any (illegal) attempt to start a transfer early and confirms the serial state progression directly. - Cover that serialisation holds under back-to-back traffic. Functional coverage must include a stream of back-to-back transfers (with and without wait states) and confirm the measured burst rate equals
1 / (2 + N)— no cycle is ever saved by overlap. A suite that only exercises isolated transfers proves nothing about serialisation; the burst case is where a mistaken pipeline assumption would show up, so it must be covered explicitly.
The point: verify that APB carries one transfer at a time (no overlap), that SETUP only follows the prior completion, and that back-to-back streams run at the serial 1 / (2 + N) rate — so the no-pipeline guarantee the whole performance model depends on is proven, not assumed.
9. Interview discussion
"Why isn't APB pipelined?" is a favourite because the weak answer is a tautology — "because it doesn't overlap transfers" — and the strong answer explains the structural cause and the design intent behind it.
State the cause first: APB drives one address/control set at a time and selects the slave for the whole two-phase transfer, so the manager's state machine can only re-enter SETUP after the current ACCESS completes — there is structurally no second transfer in flight to overlap. Then deliver the intent: pipelining (as in AHB) requires an address-to-data pipeline register, decoupled address/data handshakes, and a slave that can accept a new address while completing the old one — exactly the buffering, decoupling, and per-slave complexity APB was built to avoid. So APB is unpipelined by design: it trades overlap for a trivial slave, tiny gate count, and low power, which is the right trade for a control bus that handles sparse register accesses, not bandwidth-bound streaming. The senior flourish ties it to cost: "because there's no overlap, each transfer is a clean 2 + N and the back-to-back rate is just its reciprocal with no burst bonus — so if a region needs real throughput you put it on AHB or AXI, not APB." Framing it as a deliberate, defensible trade — not a limitation — is what signals you understand why the bus exists, not just what it does.
10. Practice
- Explain the cause. In two or three sentences, state the structural reason APB cannot overlap transfers — without using the word "pipeline" as the explanation itself.
- Name the missing machinery. List the three things a bus needs to pipeline transfers that APB deliberately omits, and say what each would cost.
- Contrast with AHB. Describe exactly what AHB overlaps that APB does not, and which AHB structure (named in prose) makes that overlap possible.
- Cost a burst. For four back-to-back zero-wait transfers, give the APB cycle count and the (wrongly) assumed pipelined count, and state the ratio.
- Write the assertion. From memory, sketch the SystemVerilog assertion that proves no new transfer's SETUP ever overlaps an in-flight ACCESS.
11. Q&A
12. Key takeaways
- APB transfers serialise by structure: the manager drives one address/control set at a time and holds the slave for the whole two-phase transfer, so the next SETUP can only begin after the current ACCESS completes. There is structurally nothing to overlap.
- The serialisation is unrepresentable, not policed. The manager's FSM re-enters SETUP only out of a completed ACCESS — there is no state where SETUP(N+1) and ACCESS(N) coexist, so the cost is a clean
2 + Nper transfer with no overlap term. - Pipelining would require machinery APB deliberately omits: an address-to-data pipeline register, decoupled address/data handshakes, and a slave that latches a new address while completing the old one — exactly the buffering, decoupling, and complexity APB exists to avoid.
- No pipeline is a feature, not a flaw. APB trades overlap-driven throughput for a trivial slave, minimal gates, and low power — the correct trade for a control bus, and the deliberate other end of the same trade AHB makes for bandwidth.
- The contrast is AHB: AHB's two-phase pipeline decouples address and data so the next transfer's address overlaps the current data; APB has no such register, so it can't — and "add a pipeline to APB" just means "use AHB."
- Verify the serialisation holds: assert no transfer ever overlaps an in-flight ACCESS, that SETUP only follows the prior completion, and cover that back-to-back streams run at the serial
1 / (2 + N)rate the whole performance model assumes.