Skip to content

AMBA APB · Module 6

Read Error Responses

PSLVERR on a read as the validity bit for PRDATA — sampled at completion, it tells the manager whether the returned data is trustworthy; the data-integrity rule (use PRDATA only if PSLVERR is low) and the benign-not-X requirement.

A read asks a question and waits for the answer to travel back — but what if the subordinate cannot answer? A failed read still finishes on exactly one completion edge, and on that edge two bits arrive together: PSLVERR says whether the access succeeded and PRDATA carries what came back. The read-specific data-integrity rule is that these two are coupled: when PSLVERR is high the PRDATA returned on that same edge is not trustworthy, and the manager must discard it rather than use it. The single idea to carry: an APB read error does not abort or retry the transfer — it completes normally and labels the returned data invalid, and treating that labelled-invalid PRDATA as real is the most damaging read-path bug there is.

1. What problem is being solved?

The problem is letting a subordinate complete a read it cannot honour, while telling the manager that the value it just captured is not real.

A read is a round trip: address out, decode, the addressed register routed onto PRDATA, value back. But some reads have no honest answer. The address may decode to nothing; the register may be protection-locked; the read path may detect a parity or ECC error on the value it fetched. In every case the subordinate still has to finish — APB has no abort — so it raises PREADY and lets the transfer complete. The danger is that completion normally means "capture PRDATA," and here the captured value is garbage.

PSLVERR closes that gap on the read path specifically:

  • PSLVERR low at completion means the read succeededPRDATA is the real value of the addressed register, and the manager uses it.
  • PSLVERR high at completion means the read failed — the transfer still completes, but the PRDATA on this edge is not the addressed register's value and must be discarded.

So the problem solved is qualifying the data, not stopping the transfer. The read finishes the same way it always does; PSLVERR is the one bit that decides whether the value the manager just latched is allowed to be used.

2. Why the previous model is not enough

Module 3 — PSLVERR, the subordinate error gave you the generic contract: a one-bit status sampled at the completion edge, high means failed, the transfer completes anyway, recovery is software's job. That is correct, and it is the foundation — but it was written for any transfer, and it deliberately stopped at "the transfer completes; the data may be garbage." That sentence is a placeholder. On a read, the garbage is PRDATA, and PRDATA is the entire point of the transfer — so the data-integrity question that Module 3 set aside is the whole subject here.

What this chapter drills deeper, read-specific:

  • The coupling of PSLVERR and PRDATA. On a read, PSLVERR is not just a pass/fail stamp on an abstract "access" — it is a validity flag on the bus value the manager is about to consume. The two are sampled on the same edge and must be evaluated together: PRDATA is meaningful only when PSLVERR is low. Module 3 never had to say this because a write has no return data to invalidate.
  • What the subordinate must drive on PRDATA during a read error. Module 3 said "the data may be garbage." For a read that is not good enough — the subordinate must drive a benign, defined value (typically all-zeros), never X, so the bus is clean even on a failed read and the manager's capture is deterministic.
  • The manager-side discard rule. A read manager needs an explicit gate — "use PRDATA only if PSLVERR is low" — that a write manager does not. Module 3 described the bridge "latching the error"; here the same edge must also decide whether the captured read data is allowed to propagate to software.

So the model to add is not "errors exist" — you have that. It is the read data-integrity contract: PSLVERR is the validity bit for PRDATA, evaluated on one shared edge, discard-on-error.

3. Mental model

The model: a failed read is a sealed envelope handed back marked "RETURNED — DO NOT OPEN." The clerk still completes the transaction and hands you something; the envelope is even the right shape and weight. But the stamp on it (PSLVERR high) tells you the contents are not your answer — and opening it (using PRDATA) gives you a meaningless page.

You hand in your request slip (PADDR, PWRITE low). The clerk goes to fetch it. They come back and complete the handoff — PREADY high, the transfer finishes exactly as a good read would. On that same handoff they place two things in your hands: the envelope (PRDATA) and the stamp (PSLVERR). If the stamp reads OK, the envelope holds your answer and you read it. If the stamp reads RETURNED, the envelope is a blank — the clerk filled it with plain paper (PRDATA = 0, never gibberish) precisely so nothing dangerous is inside — and you must throw it away, not read it.

Three refinements make the read contract precise:

  • The stamp and the envelope arrive together, read together. PSLVERR and PRDATA are valid on the same completion edge. You never read the envelope before checking the stamp; the gate is "open only if PSLVERR is low."
  • A returned envelope is still a completed transaction. The read completes normally whether the stamp is OK or RETURNED. "Failed" labels the data, it does not cancel the round trip — the bus has already moved on, and there is no automatic re-request.
  • The blank is deliberate, not accidental. The clerk does not hand you torn, unreadable scraps (X on the bus) — they hand you a clean blank (0). A defined benign value keeps the manager's capture deterministic even when the read failed.
Two stacked APB read timing diagrams. The top read completes with PSLVERR low and PRDATA carrying a valid value the manager uses. The bottom read completes identically — PREADY high on the same kind of edge — but PSLVERR is high and PRDATA is a benign zero marked do-not-use, which the manager discards.
Figure 1 — a clean read and a failed read walked side by side against PCLK, showing the PSLVERR–PRDATA coupling. Both transfers take the same SETUP then ACCESS path and both complete on a single cycle where PSEL, PENABLE, and PREADY are all high. In the top, clean read, PSLVERR is low at completion and PRDATA carries the real register value — the manager uses it. In the bottom, failed read, the completion edge is structurally identical (PREADY high, transfer completes normally), but PSLVERR is high and the PRDATA on that edge is a benign default (0, never X) that the manager must discard. The figure stresses that the failed read completes exactly like the clean one — only the PSLVERR label, and therefore the validity of PRDATA, differs.

4. Real SoC / hardware context

In silicon a read error is the read mux and the error logic resolving onto the same completion edge. The subordinate decodes PADDR; the read mux drives PRDATA; in parallel, validity logic decides whether this read is legal and drives PSLVERR. Both are required valid only when PREADY is high. Crucially, on a failed read the subordinate forces PRDATA to a benign constant — it does not let an unmapped offset leave the mux output floating or X.

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
// Subordinate read-error path (teaching sketch — not a full slave).
// On a bad read, drive PSLVERR high at completion AND force a benign PRDATA (0),
// never X. Completion is the cycle PSEL & PENABLE & PREADY are all high.
wire access      = psel && penable;                 // ACCESS phase
wire read        = access && !pwrite;               // this is a read
wire unmapped    = paddr[11:0] > LAST_VALID_OFFSET; // reserved / unmapped address
wire prot_fail   = read && reg_is_protected[paddr]  // protected register...
                        && !pprot_permits_access;   // ...with disallowed PPROT
wire read_bad    = read && (unmapped || prot_fail); // (parity/ECC would OR in here)
 
assign pready  = 1'b1;                               // always ready in this sketch
// PSLVERR qualifies the completing read; valid only when PREADY is high.
assign pslverr = access && pready && read_bad;
// On a failed read, return a DEFINED benign value — never leak X onto the bus.
assign prdata  = read_bad ? '0 : read_mux_value;
 
// ---- Manager side: the read-commit gate (the data-integrity rule) ----
// On read_commit, captured read data is VALID only if PSLVERR is low; if high,
// the data is discarded/flagged and the error is reported upstream — never used.
wire read_commit = psel && penable && pready && !pwrite;
always_ff @(posedge pclk) begin
  if (read_commit) begin
    if (pslverr) begin
      rdata_valid <= 1'b0;            // discard: do NOT expose PRDATA to software
      read_fault  <= 1'b1;            // flag the failed read upstream
    end else begin
      rdata_q     <= prdata;          // use PRDATA only when PSLVERR is low
      rdata_valid <= 1'b1;
      read_fault  <= 1'b0;
    end
  end
end

Two facts make the read-error path robust. First, the subordinate's prdata = read_bad ? '0 : read_mux_value is what keeps a failed read clean on the bus — an unmapped or protection-failed read still drives a defined 0, so the manager captures a deterministic value rather than latching X that would poison downstream logic and randomise simulation. Second, the manager's read_commit gate is the read-specific addition over a generic completion check: it samples PSLVERR and PRDATA on the same edge and only lets the data through when PSLVERR is low. The transfer still completes either way — there is no abort, no retry, no extra wait (the error rides the same edge the manager already samples for PREADY); the gate decides only whether the captured value is used or discarded and reported.

A decision figure: the manager captures PRDATA and PSLVERR at the completion edge, then branches on PSLVERR — PSLVERR low routes to 'use PRDATA (valid read)', PSLVERR high routes to 'discard PRDATA, flag fault, report upstream', with the rule 'use PRDATA only if PSLVERR == 0'.
Figure 2 — the manager's read-error decision: capture, then gate on PSLVERR. On the completion edge the manager samples PRDATA and PSLVERR together. It then checks PSLVERR: if low, the read succeeded and PRDATA is the addressed register's value — use it. If high, the read failed — PRDATA is a benign placeholder (not the register), so the manager discards it, flags the read as faulted, and reports the error upstream to software. The figure makes the rule one gate: use PRDATA only if PSLVERR is 0; never consume read data without first checking the error bit it travels with.

5. Engineering tradeoff table

A read error is a one-bit label on a normally-completing transfer with a strict data-validity rule. Each property trades a capability APB does not carry for a clean, deterministic read path.

Read-error propertyWhat it gives upWhat it buysWhy it is correct for APB
Failed read completes normallyA hardware abort/cancelOne uniform completion modelNo special "cancelled read" state to handle
PSLVERR validates PRDATAContinuously-trusted read dataOne gate: use data only if PSLVERR is lowBoth ride the same completion edge — zero extra cost
Benign PRDATA (0) on errorA "don't drive it" shortcutA defined, deterministic bus on failed readsAn X would poison the manager's capture and sim
No retry on a failed readA protocol-level re-requestA clean status-only read contractRetry policy belongs to software, not the bus
One bit, no reason codeAn in-band error causeThe cheapest read-error channelSoftware reads the cause from its own register map

The throughline: an APB read error costs one bit on an edge the manager already samples, completes the transfer unchanged, and demands exactly one discipline in return — never use PRDATA when PSLVERR is high. That single rule is what keeps a failed read from silently corrupting software.

6. Common RTL / waveform mistakes

7. Interview framing

"What happens to the read data when an APB read errors?" separates engineers who memorised PSLVERR from those who understand the read data-integrity contract. The trap answer — "the transfer aborts" or "you read whatever the subordinate put on the bus" — fails both halves.

Lead with the coupling: on a read, PSLVERR is the validity bit for PRDATA; they are sampled together on the completion edge, and PRDATA is usable only when PSLVERR is low. Then state the non-behaviour: the failed read completes normally — same edge, no abort, no retry — PSLVERR only labels the returned data invalid. Then deliver the two depth points that mark a strong answer: the subordinate must drive a benign defined PRDATA (0, never X) on a failed read so the bus stays deterministic, and the manager must gate on PSLVERRread_commit & ~pslverr to use the value, otherwise discard and report the fault upstream. Name real causes — unmapped/reserved address, protection or security violation on a protected register, a parity/ECC error on the read path — to show you know what actually fails a read. That framing — error labels the data, software handles it, never trust PRDATA on error — is exactly what an interviewer is listening for.

8. Q&A

9. Practice

  1. Draw the failed read. Draw a clean read and a failed read back to back; mark that both complete on the same kind of edge (PSEL, PENABLE, PREADY high) and that the only difference is PSLVERR and therefore the validity of PRDATA.
  2. Write the manager gate. Write the one condition under which a manager is allowed to use captured read data, expressed in terms of read_commit and PSLVERR, and state what it does on the failing case.
  3. Fix the X. A subordinate leaves PRDATA undefined on an unmapped read and asserts PSLVERR. Explain why this is still a bug despite the correct error flag, and give the one-line fix.
  4. Name the causes. List three distinct conditions that fail a read and, for each, say whether it is an address, protection, or data-path issue.
  5. Find the bug. A read manager captures and forwards PRDATA to software on every read_commit, ignoring PSLVERR. Describe the failure mode on an unmapped read and the corrected commit condition.

10. Key takeaways

  • On a read, PSLVERR is the validity bit for PRDATA. They are sampled on the same completion edge and evaluated together; PRDATA is usable only when PSLVERR is low.
  • A failed read completes normally — same completion edge as a clean read, no abort, no retry. PSLVERR labels the returned data invalid; it does not change the transfer's shape.
  • When PSLVERR is high the manager must discard PRDATA — never expose it to software — and report the fault upstream. read_commit & ~pslverr is the condition to actually use the data.
  • The subordinate must drive a benign defined PRDATA (0) on a failed read, never X, so the bus stays deterministic and the manager's capture cannot be poisoned.
  • Common read-error causes are a reserved/unmapped address, a protection or security violation on a protected register, and a parity/ECC error on the read path.
  • The cost is one bit on an edge the manager already samples. APB carries read errors at essentially zero structural cost — provided the discard-on-error discipline is honoured.