AMBA APB · Module 4
The Access Phase in Depth
The APB access phase cycle by cycle — PENABLE high, PREADY sampled each cycle, and the completion event where a write commits, read data is valid, and PSLVERR is sampled.
The earlier access-phase lesson told you what the phase is: the cycle where a transfer is performed and finished. This chapter walks it cycle by cycle — the deep timing view a verification or RTL engineer actually reasons with. The single idea to carry: PENABLE is asserted high for the entire access phase, the manager samples PREADY on every access cycle, and exactly the cycle where PREADY is high is completion — the one and only edge on which PRDATA is valid and PSLVERR is meaningful. Everything subtle about APB timing, including error timing, lives in that distinction between the phase (PENABLE) and the finish (PREADY).
1. What problem is being solved?
The problem is reading the access phase one cycle at a time and knowing, for each cycle, exactly what is true — is this a wait, or is this completion, and what may I sample here?
A high-level "setup then access, done" picture is enough to draw a one-cycle transfer. It is not enough to debug a waveform where a subordinate stretches the access, or to write the sampling logic that decides when PRDATA is real. For that you need to treat the access phase as a sequence of cycles, each governed by the same per-cycle question: with PSEL and PENABLE already high, is PREADY high this cycle? If no, the access is held — a wait state — and nothing commits. If yes, this cycle is completion, and on it the write lands, PRDATA is valid, and PSLVERR is sampled. The access phase solves the problem of letting a subordinate take any number of cycles while keeping that per-cycle rule identical on every one of them.
2. Why the previous model is not enough
The setup phase lesson and the first access-phase sketch give you the right shape — PENABLE low in setup, high in access, PREADY marking the finish. But a shape is not a cycle-by-cycle reading, and three things the coarse model glosses over are exactly where APB timing bugs live:
PENABLEdoes not change across the access phase. It is high on the wait cycles and the completion cycle — it is constant. So you cannot usePENABLEto tell wait from complete; only samplingPREADYeach cycle does that. A model that says "PENABLErising is the access" hides thatPENABLEstays high through every wait.- Sampling is a per-cycle decision, not a one-shot. The manager does not assert
PENABLEand then assume done; it re-evaluatesPREADYon every rising edge of the access phase. The coarse model has no cycle granularity to express that loop. - Error timing has no place in the sketch.
PSLVERRis a signal that is meaningful on exactly one cycle — completion — and undefined on the waits. The earlier model never said when you may look at it. A deep reading must, because samplingPSLVERRa cycle early reads garbage.
So what this chapter adds is not a new phase or signal; it is the per-cycle discipline of walking the access phase edge by edge and knowing what each cycle permits.
3. Mental model
The model: the access phase is a polling loop — PENABLE is held high while the manager asks PREADY? once per cycle, and the first "yes" is completion.
Picture the manager standing at the access phase with PENABLE pinned high, holding the address and write data stable. On every clock edge it asks one question: PREADY? As long as the answer is no, it stays in the loop — that cycle is a wait state, nothing is captured, nothing is sampled, and the held signals do not move. The first edge where the answer is yes is completion, and the loop exits: on that edge the write is captured, PRDATA is valid to read, and PSLVERR tells you whether the access succeeded or failed.
Three refinements make the model precise:
- The loop variable is
PREADY, sampled fresh each cycle. NotPENABLE(constant), not the address (constant) — onlyPREADYchanges the loop's decision, and the manager reads it on every access edge. - Holding is the default; completing is the exit. A wait cycle is the loop body: hold everything, commit nothing. There can be zero such cycles (an always-ready subordinate completes on the first access edge) or many. The shape of the loop is identical regardless.
- The exit edge is the only valid sample point.
PRDATAandPSLVERRare products of the loop's exit. Reading them inside the loop (during a wait) reads values that are not yet driven — undefined, not merely stale.
4. Real SoC / hardware context
In hardware the access phase is the manager's sampling loop made literal: PENABLE asserted, the FSM parked in its access state, and PREADY read on every clock until it is high. The subordinate owns the timing — a fast configuration register answers on the first access edge; a register in a slower clock domain, or one behind a bridge, holds PREADY low for a few cycles while its value settles. The whole phase reduces, in RTL terms, to one completion wire that every commit and every sample keys off.
// APB access-phase completion / sampling (teaching sketch — not a full slave).
// access_complete is true on EXACTLY one cycle per transfer: we are in the
// access phase (psel & penable) AND the subordinate is ready (pready).
wire access_complete = psel & penable & pready;
// The MANAGER samples PRDATA and PSLVERR ONLY when access_complete is high.
// While pready is low, access_complete is low: the access is HELD (a wait
// state) — PENABLE stays high, the address/control/PWDATA are held stable,
// and NOTHING commits. PRDATA / PSLVERR are not yet valid during a wait.
always_ff @(posedge pclk) begin
if (access_complete && !pwrite) rdata_q <= prdata; // read data valid here only
if (access_complete) slverr_q <= pslverr; // error sampled here only
endTwo facts make this robust. First, access_complete is low for every setup cycle (PENABLE low) and every wait cycle (PREADY low), so the sampling fires exactly once, on the completion edge — the per-cycle "wait or complete" decision falls out for free. Second, because PSLVERR and PRDATA are captured on the same edge the subordinate completes, the manager never disagrees with the subordinate about when the access happened, and never latches an undriven error or data value from a wait cycle.
Error timing is the sharpest application of the same rule. PSLVERR is just another signal that is only meaningful on the completion edge — but unlike a normal completion, the subordinate is also reporting that the access failed. Crucially, an error completion still completes: APB does not abort, retry, or extend the transfer on an error. The handshake and the timing are identical to a clean completion; only PSLVERR differs.
5. Engineering tradeoff table
Treating the access phase as a per-cycle PREADY-polled loop is a deliberate design choice. Each property trades a convenience APB does not need for the timing certainty it does.
| Access-phase rule | What it gives up | What it buys | Why it is correct for APB |
|---|---|---|---|
PENABLE constant across the phase | A signal that distinguishes wait from complete | One clean "we are in access" marker | Wait-vs-complete is PREADY's job, kept separate |
PREADY sampled every access cycle | A fixed, countable latency | Subordinates of any speed on one bus | Slow registers and bridges must be able to stall |
PRDATA / PSLVERR valid only at completion | Early-available read data / status | One safe sample edge, no undefined reads | The values are only driven when the access finishes |
Error completion = normal completion + PSLVERR | A separate abort/retry mechanism | Trivial, uniform completion handling | The control plane just records the error and moves on |
| Held signals stable through every wait | Freedom to change mid-access | A repeatable, corruption-free access | Changing address or data mid-phase corrupts the transfer |
The throughline: APB spends knowing how long the access takes and gains knowing exactly what is true on every cycle. The phase can be one cycle or ten, clean or errored, but the per-cycle rule — sample PREADY, commit only on the PREADY-high edge — never changes, which is why the manager's logic stays tiny.
6. Common RTL / waveform mistakes
7. Interview framing
This is where an interviewer checks whether you can read a stretched APB waveform, not just a textbook one-cycle transfer. The weak answer is "the access is the second cycle and PREADY says done." The strong answer walks the phase cycle by cycle.
Say it in three moves: PENABLE is asserted high for the entire access phase, waits included, so it marks the phase, not the finish; the manager samples PREADY on every access cycle — low holds the access (a wait state, nothing commits), high is completion; and PRDATA is valid and PSLVERR is sampled only on that one completion edge. Then volunteer the depth point that separates levels: an error completion is a normal completion with PSLVERR high — APB does not abort or retry — and PSLVERR is meaningless on any wait cycle. What the interviewer is really probing is whether you locate the completion edge correctly and understand that the access phase is a per-cycle PREADY poll, which is exactly the skill that lets you debug a wait-state or error waveform. For the full unifying rule, point to the completion contract.
8. Q&A
9. Practice
- Walk the cycles. Given an access phase with one wait then completion, state for each access cycle the value of
PENABLEandPREADYand whether anything commits. - Find the edge. On a transfer with three wait states, mark the single completion cycle and explain how you found it without relying on
PENABLEchanging. - Write the wire. From memory, write
access_complete = psel & penable & preadyand say which two signals the manager samples only when it is high. - Place the error. On a read that completes with
PSLVERRhigh after one wait, mark wherePSLVERRis meaningful and explain why a high on the wait cycle must be ignored. - Defend the timing. In two sentences, justify why an error completion has the same timing as a clean one and why APB does not abort or retry on an error.
10. Key takeaways
PENABLEis asserted high for the entire access phase — every wait cycle and the completion cycle alike. It marks the phase, never the finish.- The manager samples
PREADYon every access cycle. Low holds the access (a wait state, nothing commits); high is completion. It is a per-cycle poll, not a one-shot. - Completion is the single access cycle where
PSEL,PENABLE, andPREADYare all high —access_complete = psel & penable & pready, true on exactly one edge per transfer. PRDATAis valid andPSLVERRis sampled only on that completion edge. On a wait cycle both are undefined; sampling either there reads garbage.- An error completion is a normal completion with
PSLVERRhigh. Same handshake, same timing — APB does not abort, retry, or extend; the manager just records the error. - Wait states stretch the access; they never restart setup.
PENABLEstays high, the held signals stay stable, and only the loop length changes — the per-cycle rule is identical for zero waits or many.