AMBA APB · Module 4
Anatomy of a Read Transfer
A full APB read walked from IDLE to IDLE — setup, access, the completion cycle where PRDATA is valid and sampled, and the return to IDLE, shown in timing.
You have met the read direction one signal at a time — the access phase, PRDATA, the PREADY handshake. This chapter assembles them into the thing you actually trace on a waveform: one complete read transfer, walked cycle by cycle from IDLE back to IDLE. A read is IDLE → SETUP → ACCESS → COMPLETE → IDLE, with PWRITE low selecting the read direction and the subordinate — not the manager — driving the returned data. The single idea to carry: a read has exactly one cycle that matters for data — the completion cycle, where PSEL, PENABLE, and PREADY are all high — and the manager samples PRDATA on that edge and nowhere else, whether or not the subordinate inserted a wait.
1. What problem is being solved?
The problem is reading a register out of an addressed subordinate and getting its value back to the manager, with one unambiguous cycle on which that value is real.
A read is not a single event; it is a short choreography. The manager must announce where it is reading and that it is a read, give the subordinate a cycle to decode and look up the value, and then agree on the exact cycle the value is valid to capture. APB lays this out as a fixed sequence:
IDLE— nothing selected;PSELlow; the bus is quiet.SETUP—PSELrises,PADDRholds the read address,PWRITEis low (read),PENABLEstays low. One cycle for the subordinate to decode.ACCESS—PENABLErises; the subordinate drivesPRDATAand assertsPREADYwhen its value is ready.COMPLETE— the access cycle wherePREADYis high: the read finishes and the manager samplesPRDATA.- back to
IDLE(or straight to the nextSETUP).
The whole point of the sequence is that one cycle — completion — is where the data is real. Everything before it is announce-and-wait; the value only counts on the edge where PSEL, PENABLE, and PREADY are all high.
2. Why the previous model is not enough
You have correct pieces: the access phase mechanics, the PRDATA contract, and the PREADY handshake. Each is right in isolation, but a per-signal view does not show you how a read reads on a waveform — the cycle-by-cycle motion from quiet bus to captured data and back.
Three things only become clear when you trace the whole transfer:
- The direction bit is set up front and held.
PWRITElow is what makes this a read, and it is presented in SETUP alongside the address — not negotiated later. For a readPWDATAis unused; the data flows the other way, subordinate to manager, onPRDATA. - The valid cycle is the same cycle no matter the latency. A clean read and a one-wait read differ only in how long ACCESS lasts. The cycle the manager samples
PRDATAis the completion cycle in both — a wait state stretches the access, it does not move the sample point or restart SETUP. - The transfer has a clean end. After completion the bus returns to IDLE (or flows to the next SETUP). Knowing where the transfer ends is as important as knowing where data is valid — it is what lets you tell one transfer from the next on a busy bus.
So the model to add is not another signal; it is the whole motion — IDLE to IDLE — with the completion cycle as the one fixed landmark inside it.
3. Mental model
The model: a read is asking a librarian for a book — you fill out the slip (SETUP), they fetch it (ACCESS), and you only take the book the moment they hand it across the counter (completion).
You write the call number on a slip (PADDR) and tick the borrow, not return, box (PWRITE low) — that is SETUP. You hand the slip over and wait while the librarian walks to the shelf; that is ACCESS, and it takes as long as it takes. The book is not yours while they are still walking — anything on the counter before the handoff is not the book you asked for. Only when the librarian places it in your hands (PREADY high) is the book real, and that is the one instant you take it (sample PRDATA). Then you step away from the counter — back to IDLE.
Three refinements make the model precise:
- The subordinate fetches; the manager only receives.
PRDATAis driven by the subordinate's read mux selected byPADDR. The manager presents the address andPWRITElow, then samples — it never drives the data. - The slip stays on the counter until the handoff.
PADDR,PWRITE, andPSELare held stable from SETUP through every access cycle until completion. The librarian must not have the request change mid-fetch. - You take the book on exactly one cycle.
PRDATAis required valid only on the completion cycle. Before it — in SETUP and in any wait cycle — it is don't-care, a draft you must not copy.
4. Real SoC / hardware context
In silicon, a read is how software gets state out of a peripheral — read a status register, poll a FIFO level, check an interrupt cause. The CPU issues a load; the bridge turns it into this exact APB sequence; the addressed peripheral's read mux returns the value. Because control reads are sparse and latency-insensitive, the subordinate's read path is almost always a combinational mux, not a pipeline.
The data-side rule is one line of intent: PRDATA only has to be valid on the read completion edge. The cleanest way to encode that in a manager-side or verification model is to name the commit condition and sample on it:
// Subordinate read path: PRDATA read mux (teaching sketch — not a full slave).
// PADDR selects which register's value is driven onto PRDATA.
logic [31:0] prdata;
always_comb begin
prdata = '0; // clean default: idle / unmapped reads return 0
case (paddr)
ADDR_CTRL: prdata = ctrl_reg;
ADDR_STATUS: prdata = status_reg;
ADDR_DATA: prdata = data_reg;
default: prdata = '0; // unmapped address → 0, never undefined
endcase
end
// CONTRACT: PRDATA is only REQUIRED valid on the read completion edge —
// read_commit = psel & penable & pready & ~pwrite
// The manager samples PRDATA on exactly that edge. In SETUP and in every
// wait cycle, PRDATA is don't-care; the combinational mux off the stable
// PADDR is settled well before that edge, so a clean read needs no pipeline.
wire read_commit = psel & penable & pready & ~pwrite;Two facts make this robust. First, PADDR is held stable from SETUP through the whole access, so the combinational decode is settled long before PREADY rises — the subordinate just has to present the right register on the completion cycle. Second, because read_commit is high on exactly one cycle (low in SETUP where PENABLE is low, low in every wait cycle where PREADY is low), a manager that loads its read register on read_commit captures the value once, at the right edge, with wait states handled for free.
5. Engineering tradeoff table
Laying a read out as a fixed IDLE-to-IDLE sequence with one valid cycle is a deliberate, minimal design. Each property trades a capability APB does not need for the clarity it does.
| Read-transfer property | What it gives up | What it buys | Why it is correct for APB |
|---|---|---|---|
| Mandatory SETUP before ACCESS | A cycle of latency | A decode cycle; address settled before enable | Simple subordinates decode combinationally with margin |
PRDATA valid only at completion | A continuously-driven read value | One unambiguous sample edge | The read mux settles over ACCESS; one capture point |
Subordinate drives PRDATA | A manager-sourced read path | Read data comes from the register that owns it | Address-decoded mux, no contention, no tri-state |
| Wait stretches ACCESS, never restarts SETUP | Bounded, countable latency | Correct read at any subordinate speed | Slow peripherals just hold PREADY low |
PWRITE low set in SETUP and held | Mid-transfer direction change | Direction fixed before any data moves | One decode of read-vs-write per transfer |
The throughline: a read spends one SETUP cycle and one valid cycle and gains a sequence that is identical whether the subordinate is instant or slow. The completion edge is the only data landmark, which is why an APB read is small to build and easy to read.
6. Common RTL / waveform mistakes
7. Interview framing
"Walk me through an APB read" is a staple opener because the answer instantly shows whether you think in signals or in transfers. A weak answer lists PRDATA and PREADY; a strong one narrates the motion.
Lead with the sequence: IDLE → SETUP → ACCESS → COMPLETE → IDLE. Say what each cycle does — SETUP raises PSEL, presents PADDR, drives PWRITE low for a read, keeps PENABLE low; ACCESS raises PENABLE; the subordinate drives PRDATA and asserts PREADY; completion is the cycle all three of PSEL, PENABLE, PREADY are high, where the manager samples PRDATA. Then deliver the two depth points: the subordinate drives PRDATA, valid only at completion and don't-care before (so the read path can be a settled combinational mux), and a wait state stretches ACCESS without moving the sample edge or restarting SETUP. Volunteering "for a read PWRITE is low and PWDATA is unused — the data flows the other way" signals you understand direction, not just timing.
8. Q&A
9. Practice
- Walk the clean read. From IDLE, draw
PSEL,PENABLE,PWRITE,PADDR,PRDATA, andPREADYfor a zero-wait read and mark the single cycle the manager samplesPRDATA. State whatPRDATAis on every earlier cycle. - Insert one wait. Redraw the same read with one wait state. Show that SETUP is not repeated,
PADDRis held across the wait, and the sample edge is still the first access cycle withPREADYhigh. - Set the direction. Explain which signal makes the transfer a read, in which cycle it is presented, and what
PWDATAis doing during the read. - Write the commit wire. From memory, write
read_commit = psel & penable & pready & ~pwriteand say exactly which cycle it is high on for both the clean and one-wait reads. - Find the bug. A manager latches
PRDATAon the first cyclePENABLEis high, ignoringPREADY. On a one-wait read, show which cycle it wrongly samples and what value it captures.
10. Key takeaways
- A read is
IDLE → SETUP → ACCESS → COMPLETE → IDLE. SETUP announces (address,PWRITElow,PENABLElow), ACCESS performs (PENABLEhigh), completion is the cyclePSEL,PENABLE, andPREADYare all high. - The subordinate drives
PRDATA; the manager only samples it.PWRITElow selects the read andPWDATAis unused — the data flows subordinate to manager. PRDATAis valid only on the completion cycle and don't-care everywhere else — in IDLE, in SETUP, and in every wait cycle. The manager samples it on that one edge.PADDR,PWRITE, andPSELare held stable from SETUP through every access cycle until completion, including across a wait state.- A wait state stretches ACCESS without moving the sample edge or restarting SETUP. The clean read and the one-wait read differ only in how wide ACCESS is.
read_commit = psel & penable & pready & ~pwriteis the one wire the read capture hangs off — high on exactly the completion cycle, which is why an APB read is small to build and easy to read.