Skip to content

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; PSEL low; the bus is quiet.
  • SETUPPSEL rises, PADDR holds the read address, PWRITE is low (read), PENABLE stays low. One cycle for the subordinate to decode.
  • ACCESSPENABLE rises; the subordinate drives PRDATA and asserts PREADY when its value is ready.
  • COMPLETE — the access cycle where PREADY is high: the read finishes and the manager samples PRDATA.
  • back to IDLE (or straight to the next SETUP).

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. PWRITE low is what makes this a read, and it is presented in SETUP alongside the address — not negotiated later. For a read PWDATA is unused; the data flows the other way, subordinate to manager, on PRDATA.
  • 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 PRDATA is 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. PRDATA is driven by the subordinate's read mux selected by PADDR. The manager presents the address and PWRITE low, then samples — it never drives the data.
  • The slip stays on the counter until the handoff. PADDR, PWRITE, and PSEL are 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. PRDATA is 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.
An APB read timing diagram with rows PCLK, PSEL, PENABLE, PWRITE, PADDR, PRDATA, PREADY: IDLE then SETUP with PSEL high, address valid and PWRITE low and PENABLE low, then one ACCESS cycle with PENABLE and PREADY both high where PRDATA is valid and sampled, then back to IDLE.
Figure 1 — a complete read transfer with no wait state, walked IDLE to IDLE against PCLK. In IDLE, PSEL is low. SETUP raises PSEL, presents the read address on PADDR, drives PWRITE low to select a read, and keeps PENABLE low. ACCESS raises PENABLE while PSEL, PADDR, and PWRITE stay stable; the subordinate drives the addressed register value onto PRDATA and asserts PREADY, so PSEL, PENABLE, and PREADY are all high and the transfer completes on that single cycle. The dashed marker is that completion edge — the one cycle the manager samples PRDATA. PRDATA is shown don't-care in IDLE and SETUP and valid only at completion; after completion the bus returns to IDLE and PSEL drops.

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:

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
// 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.

An APB read timing diagram with one wait state: SETUP, then two ACCESS cycles where PENABLE is high throughout, PREADY low on the first (PRDATA don't-care) and high on the second where PRDATA is valid and sampled, with the address held stable across the wait.
Figure 2 — the same read with one wait state, against PCLK. SETUP is identical: PSEL high, PADDR holding the read address, PWRITE low, PENABLE low. ACCESS now spans two cycles. In the first, PENABLE is high but the subordinate holds PREADY low — the wait — so the access is held, PRDATA is don't-care, and the manager keeps PADDR, PWRITE, and PSEL stable. In the second, PREADY is high and the subordinate drives PRDATA valid; the dashed marker sits there, the single cycle the manager samples it. SETUP is not repeated and the sample point is still the first access cycle with PREADY high — the wait only stretches ACCESS.

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 propertyWhat it gives upWhat it buysWhy it is correct for APB
Mandatory SETUP before ACCESSA cycle of latencyA decode cycle; address settled before enableSimple subordinates decode combinationally with margin
PRDATA valid only at completionA continuously-driven read valueOne unambiguous sample edgeThe read mux settles over ACCESS; one capture point
Subordinate drives PRDATAA manager-sourced read pathRead data comes from the register that owns itAddress-decoded mux, no contention, no tri-state
Wait stretches ACCESS, never restarts SETUPBounded, countable latencyCorrect read at any subordinate speedSlow peripherals just hold PREADY low
PWRITE low set in SETUP and heldMid-transfer direction changeDirection fixed before any data movesOne 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

  1. Walk the clean read. From IDLE, draw PSEL, PENABLE, PWRITE, PADDR, PRDATA, and PREADY for a zero-wait read and mark the single cycle the manager samples PRDATA. State what PRDATA is on every earlier cycle.
  2. Insert one wait. Redraw the same read with one wait state. Show that SETUP is not repeated, PADDR is held across the wait, and the sample edge is still the first access cycle with PREADY high.
  3. Set the direction. Explain which signal makes the transfer a read, in which cycle it is presented, and what PWDATA is doing during the read.
  4. Write the commit wire. From memory, write read_commit = psel & penable & pready & ~pwrite and say exactly which cycle it is high on for both the clean and one-wait reads.
  5. Find the bug. A manager latches PRDATA on the first cycle PENABLE is high, ignoring PREADY. 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, PWRITE low, PENABLE low), ACCESS performs (PENABLE high), completion is the cycle PSEL, PENABLE, and PREADY are all high.
  • The subordinate drives PRDATA; the manager only samples it. PWRITE low selects the read and PWDATA is unused — the data flows subordinate to manager.
  • PRDATA is 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, and PSEL are 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 & ~pwrite is 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.