Skip to content

AMBA APB · Module 6

PRDATA Timing

When PRDATA must be valid and who drives it — the subordinate's read-mux drive responsibility, the completion-edge valid window, and why PRDATA is don't-care before completion, including during wait cycles.

A read returns a value, but the value is only real for one edge — and the whole skill of building or debugging a read is knowing exactly which edge, what the bus carries before it, and who is on the hook to drive it. This chapter pins the timing of PRDATA down to the cycle: it is don't-care through IDLE, SETUP, and every wait cycle, and is required valid only on the completion edge where PSEL, PENABLE, and PREADY are all high with PWRITE low. The single idea to carry: PRDATA validity is gated by the handshake, not by the access phase — PENABLE going high does not make it valid — and the subordinate carries the timing obligation to have its read mux settled by that one edge.

1. What problem is being solved?

The problem is placing the read value on the bus on exactly the cycle the manager will sample it, and not requiring it a cycle sooner or trusting it a cycle later — so that a combinational read path, a wait state, and an undriven idle bus all coexist without ever handing the manager a wrong or undefined value.

A read value is a moving target in time. The address has to decode, the read mux has to settle, and — if the source is slow — the data may genuinely not exist yet for a cycle or two. APB resolves all of that with a single timing law:

  • PRDATA is required valid on exactly one edge: the completion edge, where read_commit = PSEL & PENABLE & PREADY & ~PWRITE is high.
  • Everywhere before that edge — IDLE, SETUP, and every wait cycle — PRDATA is don't-care, and the manager must not sample it.

That single-edge law is what lets the subordinate drive PRDATA from a plain combinational mux and still be correct: it only has to be settled by the completion edge, not before. The manager's job is the mirror image — sample on that edge and ignore the bus otherwise.

2. Why the previous model is not enough

Module 3 — the PRDATA signal introduced PRDATA as the subordinate-driven read bus and gave you its valid-when-PREADY rule: read data is valid on the completion cycle and don't-care otherwise. That is the correct rule of thumb. But a rule of thumb is not a timing contract, and to drive PRDATA in real RTL or to place a sampling assertion you need three things that the signal page deliberately left at the level of "valid at completion":

  • The exact valid edge, expressed as a commit term, not a phase. Validity is not "during access" — it is the single edge where PSEL & PENABLE & PREADY & ~PWRITE holds. This chapter pins it to that boolean so you can wire it.
  • The don't-care window made explicit through the wait cycles. The trap the role-level view hides is the wait state: PENABLE is already high there, yet PRDATA is still don't-care because PREADY is low. Module 3 stated this; here it is the centre of gravity.
  • The subordinate's timing obligation, not just its ownership. Module 3 told you the subordinate drives PRDATA. This chapter states the harder half: the subordinate must have its read mux settled by the completion edge off the held PADDR, and must drive a clean default so the bus is never X on any other cycle.

So the model this chapter adds is not "PRDATA is the read bus" — you have that. It is the edge-precise drive-and-sample contract: the exact valid edge, the don't-care window that swallows the wait cycles, and the subordinate's obligation to be settled by that edge.

3. Mental model

The model: PRDATA is a stage cue, not a standing line. The actor (the subordinate) must be in position and speaking the right line at exactly the moment the spotlight (the completion edge) hits — but before that cue, whatever is on stage is rehearsal, and the audience (the manager) is told plainly to look away until the light comes up.

The light comes up on exactly one edge: PSEL, PENABLE, and PREADY all high, PWRITE low. Walk the timeline against PCLK:

  • Through IDLE and SETUP, the spotlight is off. PRDATA is don't-care; the manager does not look.
  • Through every wait cycle (PENABLE high but PREADY low), the spotlight is still off. This is the cycle people misread: access has started, but the cue has not landed, so PRDATA remains don't-care. The subordinate is allowed to be mid-fetch.
  • On the completion edge (PREADY finally high), the light comes up. PRDATA is required valid; the manager samples it here and only here.

Two refinements make the timing precise:

  • The cue is gated by the handshake, not the phase. PENABLE high marks the access phase; PREADY high marks the completion edge. PRDATA follows the edge. Trusting PENABLE alone samples a cycle early on any wait read.
  • The actor must be in position by the cue, not before. Because PADDR is held stable from SETUP through completion, the subordinate's combinational read mux settles during access and is guaranteed correct by the completion edge — that is its timing obligation, and a settled mux is all it takes.
An APB read timing diagram with rows PCLK, PSEL, PENABLE, PWRITE, PADDR, PREADY, PRDATA: PRDATA is don't-care across IDLE, SETUP, and the wait cycle where PENABLE is high but PREADY is low, and valid only on the completion cycle where PREADY also goes high, marked with a dashed sample edge.
Figure 1 — the exact PRDATA valid window pinned against PCLK across a one-wait read. PSEL rises in SETUP and holds; PENABLE is high through both ACCESS cycles; PWRITE is low and PADDR holds one stable read address. PREADY is low through SETUP and the first ACCESS cycle (the wait) and high on the second (completion). PRDATA is drawn as a single continuous don't-care band through IDLE, SETUP, and the entire wait cycle — undefined even though PENABLE is already high — and becomes valid only on the completion cycle where PSEL, PENABLE, and PREADY are all high with PWRITE low. A dashed marker labels that completion cycle as the one edge the manager samples PRDATA. The figure's point is that the access phase alone does not make PRDATA valid; the handshake edge does.

4. Real SoC / hardware context

In silicon, PRDATA timing is the meeting of two clocks of responsibility. The subordinate runs a combinational read path — decode the held PADDR, select the register, drive the bus — that must be settled by the completion edge. The manager runs a single registered load that fires on exactly the completion edge and is otherwise blind to the bus. The contract lives in the gap between them, and the don't-care window is what makes that gap cheap: because nothing requires PRDATA before completion, the subordinate may take wait cycles, and the bus may sit at its default, with no violation.

A block diagram with MANAGER on the left driving PADDR and PWRITE low rightward and holding a PRDATA capture register gated by PSEL and PENABLE and PREADY, and SUBORDINATE on the right containing address decode, a read mux over the register file with a default of zero, driving PRDATA leftward back to the manager.
Figure 2 — the read data-path ownership behind PRDATA timing. The manager (left) drives PADDR with PWRITE low outbound and holds a PRDATA capture register on its input that loads only when PSEL, PENABLE, and PREADY are all high with PWRITE low. The subordinate (right) owns the read path: PADDR enters an address decoder, the decode selects a read multiplexer over the register file, and that mux drives PRDATA — with a clean default of zero on unmapped or idle so the bus is never X. A bold arrow carries PRDATA leftward from the subordinate's mux back to the manager's capture register; the address arrow flows right. The figure makes drive direction and ownership unmistakable: address flows right, read data flows left, and the subordinate is the sole driver of PRDATA while the manager only captures on the completion edge.
Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
// Subordinate read path: PRDATA must be SETTLED by the completion edge.
// PADDR is held stable from setup through completion, so this combinational
// mux settles during the access phase and is correct by the time PREADY rises.
always_comb begin
  prdata = '0;                       // clean default: idle/unmapped never X
  case (paddr)
    ADDR_STATUS: prdata = status_q;
    ADDR_COUNT:  prdata = count_q;
    ADDR_ID:     prdata = ID_CONST;
    default:     prdata = '0;        // unmapped read returns 0, deterministic
  endcase
end
 
// The read VALID edge, as a single commit term (manager samples here only):
wire read_commit = psel & penable & pready & ~pwrite;
 
// PRDATA is REQUIRED valid only when read_commit is high. Before it — IDLE,
// SETUP, and every wait cycle (penable high but pready low) — PRDATA is
// don't-care. Optional check that the subordinate is settled at the edge:
// assert property (@(posedge pclk) read_commit |-> !$isunknown(prdata));

Two facts make the timing robust. First, the don't-care window is load-bearing, not slack: it is precisely what lets a slow source hold PREADY low and finish the read late — the subordinate presents valid PRDATA only when its source is ready, and the cycles before are legitimately don't-care, not a violation. Second, the manager's capture must be gated on read_commit, not on PENABLE: gate it on the phase and the very first wait read samples a cycle early and latches the don't-care value. (How the wait cycles are sequenced is the PREADY interaction on reads; this chapter is only about where on the timeline PRDATA is real.)

5. Engineering tradeoff table

Pinning PRDATA validity to one edge with a wide don't-care window is a deliberate timing choice. Each property trades a capability APB does not need for the simplicity it does.

PRDATA timing propertyWhat it gives upWhat it buysWhy it is correct for APB
Valid only on the completion edgeA continuously-trusted read valueOne unambiguous sample edgeThe mux settles over access; the manager loads once
Don't-care through every wait cycleA value the instant PENABLE risesReads from any-speed source on one busSlow sources hold PREADY low and finish late, legally
Subordinate settled by the edge (not before)An early-presented / pre-staged valueA trivial combinational read muxPADDR held stable → mux is correct by completion
Gated by handshake, not by phaseSampling on PENABLE aloneWait reads are correct without manager reworkPREADY distinguishes the edge from the phase
Clean default (0) on idle/unmappedA "no data" encoding on the busPRDATA is never X off the valid edgeUndefined reads become deterministic and debuggable

The throughline: PRDATA is valid for one edge and don't-care everywhere else, and that single-edge contract is exactly what lets the subordinate stay a settled combinational mux and the manager stay a single gated load — while the don't-care window absorbs any read latency the source needs.

6. Common RTL / waveform mistakes

7. Interview framing

"On which exact edge is PRDATA valid, and what is it during a wait cycle?" separates an engineer who can place a read sample from one who only knows the role. A weak answer says "valid at completion"; a strong one pins the edge and nails the wait cycle.

Lead with the edge as a term, not a phase: PRDATA is required valid only on the completion edge — PSEL & PENABLE & PREADY & ~PWRITE — and is don't-care everywhere before it. Then deliver the discriminating point, the wait cycle: during a wait, PENABLE is high but PREADY is low, so PRDATA is still don't-care — which is exactly why the manager must gate its capture on PREADY, not on PENABLE. Close with the subordinate's obligation: the subordinate must have its read mux settled by that edge off the held PADDR, and drive a clean default so the bus is never X otherwise. Volunteering "the don't-care window during the wait is what lets a slow source finish the read late and still be legal" signals you understand the timing as a contract, not a waveform you memorised.

8. Q&A

9. Practice

  1. Pin the edge. On a one-wait read waveform, mark the single cycle PRDATA is required valid and write the boolean term that identifies it. State what the bus is on every earlier cycle.
  2. Trap the wait. Point to the wait cycle on the same waveform, state both PENABLE and PREADY there, and explain in one line why PRDATA is don't-care despite PENABLE being high.
  3. Find the bug. A manager loads its read register whenever PENABLE is high. On a two-wait read, identify which cycle it wrongly samples, what it captures, and the one-word fix to its load enable.
  4. Defend the default. A subordinate omits the default in its read case. Describe what appears on PRDATA for an unmapped read, why it survives in simulation but bites in silicon, and the fix.
  5. Reconcile slow data. A read source needs three cycles. Describe what PRDATA carries during the two wait cycles, what the combinational mux drives at the completion edge, and why no pipeline is required.

10. Key takeaways

  • PRDATA is required valid on exactly one edge — the completion edge where PSEL & PENABLE & PREADY & ~PWRITE is high — and is don't-care everywhere before it: IDLE, SETUP, and every wait cycle.
  • The wait cycle is the trap. PENABLE is high there but PREADY is low, so PRDATA is still don't-care. Validity follows the handshake edge, not the access phase.
  • The manager must gate its capture on PREADY, not on PENABLE. Gating on the phase samples a cycle early on any wait read and latches the don't-care value.
  • The subordinate's obligation is to be settled by the completion edge, not before it. Because PADDR is held stable across access, a plain combinational read mux meets this with no pipeline.
  • Never leave PRDATA X off the valid edge — drive a clean default (typically 0) on idle and unmapped reads so a mis-timed capture or an unmapped address is deterministic, not garbage.
  • The don't-care window is load-bearing. It is exactly what lets a slow source hold PREADY low and finish the read late, legally — the same single-edge law that keeps the read path a simple settled mux.