AMBA APB · Module 5
Signal-Stability Requirements
The APB stability contract — which signals freeze from setup through completion (PADDR, PWRITE, PWDATA, PSTRB, PPROT, PSEL), which may move, why a violation is silent corruption, and the $stable-until-completion assertion that catches it.
Module 4 showed you when a transfer completes. This deep-drill chapter answers the question that decides whether the value the subordinate commits is the value the manager intended: which signals must hold absolutely stable, and for how long? APB's answer is a hard contract — the access-defining signals presented in setup must not change a single bit until the transfer completes, even across wait states. The single idea to carry: stability is defined relative to completion, not to a cycle count — and a violation does not raise an error, it silently corrupts the access. This chapter makes the contract precise, shows the violation on a waveform, and turns it into an assertion that fails the instant a manager misbehaves.
1. What problem is being solved?
The problem is guaranteeing the subordinate acts on exactly the access the manager presented — the same address, direction, and data — for the entire, possibly multi-cycle, life of the transfer.
A subordinate does not consume the access in one instant. It decodes PADDR in setup, but the decode is only used when the access commits at completion — which may be several wait-state cycles later. In between, the address, the direction, and the write data sit on the bus, and the subordinate's logic (its write-enable, its read mux, its byte-strobe gating) reads them at the completion edge. If any of those signals changed after setup, the subordinate would decode one thing and commit another. So APB fixes a contract:
- The access-defining signals are presented in setup and frozen.
PADDR,PWRITE,PWDATA,PSTRB,PPROT, and the selectedPSELhold byte-for-byte from the setup edge until the completion edge. - The handshake signals are allowed to move.
PENABLE(low→high at the setup→access boundary),PREADY,PRDATA, andPSLVERRchange during the transfer — that is their job.
The contract is what makes a slow, multi-cycle subordinate safe: the access is held perfectly still while the subordinate takes as long as it needs.
2. Why the previous model is not enough
Module 4 told you the access-defining signals "are held stable until completion." That sentence is the rule; this chapter is the contract you can enforce. The mechanics view leaves three things imprecise, and all three are where real bugs live:
- Exactly which signals — and the line between "frozen" and "free". It is not "all signals hold."
PENABLEmust change (it rises into access);PREADY/PRDATA/PSLVERRmust be free to move. Stability applies only to the access-defining set. Getting the partition wrong produces both false bugs and missed ones. - The duration is data-dependent, not a number. "Until completion" means until the first access cycle where
PREADYis high — which the subordinate decides. Stability has no fixed length; it is a contract anchored to an event, so a manager cannot satisfy it by "holding for N cycles." - A violation is silent. Nothing in the protocol flags a mid-access address change. The subordinate just commits the wrong location or wrong data, and the failure surfaces cycles or transactions later as corrupted state. Without an assertion, you debug the symptom, not the cause.
So the model to add is the contract — the precise frozen/free partition, anchored to completion, expressed as something a simulator checks every cycle.
3. Mental model
The model: setup signs a contract, and completion is the only moment it may be torn up. Everything the manager writes on that contract — the address, the direction, the data — is held in escrow, untouchable, until the subordinate stamps it done.
Think of a wire transfer at a bank counter. You fill in the account number and amount on the slip (the access-defining signals, presented in setup) and slide it across. The teller may be slow — checking, stamping, taking several minutes (wait states) — and during that whole time you do not reach over and change the account number on the slip. The teller acts on the slip at the moment of stamping (completion); if the number changed underneath them, the money goes to the wrong account and nothing warns you. What you are free to do is tap your foot, ask "ready yet?", and watch their hands (PENABLE, PREADY) — those are the handshake, not the contract.
Three refinements make it precise:
- Frozen set, free set. Frozen until completion:
PADDR,PWRITE,PWDATA,PSTRB,PPROT, and the assertedPSEL. Free to move:PENABLE(rises once into access),PREADY,PRDATA,PSLVERR. - Anchored to the event, not the clock count. The freeze lasts exactly until the completion edge (
PSEL & PENABLE & PREADY). One wait state or ten, the rule is identical: hold until that edge. - Releasing on the completion edge is legal — and required. On the completion cycle the manager may change everything for the next transfer (drive a new
PADDR, dropPSEL, present the next access). Holding stable means "through completion," not "forever."
4. Real SoC / hardware context
In silicon, the manager is the bridge, and it satisfies the contract by registering the access-defining signals and holding them while its transfer FSM sits in setup and access. The subordinate relies on that hold: it captures only at completion, so the held signals are what it actually consumes.
// Manager side: the access-defining signals are registered when the transfer
// is launched and HELD while the FSM is in SETUP or ACCESS (teaching sketch).
// They are only re-driven on/after the completion edge, for the next transfer.
always_ff @(posedge pclk or negedge presetn) begin
if (!presetn) begin
paddr_q <= '0; pwrite_q <= '0; pwdata_q <= '0;
end else if (launch) begin // launch = leaving IDLE for SETUP
paddr_q <= req_addr; // captured ONCE, then frozen by holding
pwrite_q <= req_wr;
pwdata_q <= req_wdata;
end
// NOTE: there is no branch that updates these mid-transfer — that absence
// IS the stability guarantee. The FSM simply does not touch them until
// it completes and launches the next access.
endOn the subordinate side, the contract is load-bearing: the write-enable and read mux are gated on the completion condition and read the held signals. Because the manager never moves them, paddr_q at the completion edge is the same paddr_q the subordinate decoded in setup — decode and commit agree by construction.
The stability rule is also the single most valuable APB property to assert, because the violation is otherwise invisible. The canonical check says: while a transfer is in flight and not yet complete, the frozen set must be $stable.
// SVA: while a started transfer has NOT yet completed (in ACCESS, PREADY low),
// every access-defining signal must be byte-for-byte stable next cycle.
// This is the one assertion that catches silent mid-access corruption.
property p_apb_stable_until_complete;
@(posedge pclk) disable iff (!presetn)
(psel && penable && !pready) |=>
( $stable(paddr) && $stable(pwrite) && $stable(pwdata)
&& $stable(pstrb) && $stable(pprot) && $stable(psel) );
endproperty
assert property (p_apb_stable_until_complete);Bind that to every APB interface and a manager that changes PADDR during a wait state fails at the offending cycle, naming the signal — instead of you chasing a corrupted register three transactions downstream.
5. Engineering tradeoff table
The stability contract trades manager-side flexibility for subordinate-side simplicity and certainty. Each line is a deliberate choice.
| Stability rule | What it gives up | What it buys | Why it is correct for APB |
|---|---|---|---|
| Access signals frozen setup→completion | Manager freedom to retime address/data | A subordinate that can commit at any later cycle | Decode-in-setup, commit-at-completion must agree |
| Anchored to completion, not a cycle count | A simple fixed-latency window | Correctness at any wait-state count | The subordinate owns how long it takes |
PENABLE/PREADY explicitly free | A "hold everything" simplicity | A working handshake | The handshake must move to function |
| Violation is silent (no protocol error) | Built-in hardware detection | A dead-simple bus with no checker gates | Detection belongs in verification (SVA), not silicon |
| Release allowed on completion | A guaranteed quiet cycle after | Back-to-back transfers with no idle gap | Sparse traffic still benefits from adjacency |
The throughline: APB pushes all the burden onto the manager to hold still, which makes every subordinate trivially correct and every wait state safe. The cost — that violations are silent — is paid in verification, not in gates, which is exactly the APB philosophy.
6. Common RTL / waveform / verification mistakes
7. Interview framing
This is a favorite senior-level APB question because the precise answer proves you understand why a multi-cycle handshake is safe. The weak answer is "the signals stay the same"; the strong answer states the partition, the anchor, and the failure mode.
Say it in three moves: the access-defining signals — PADDR, PWRITE, PWDATA, PSTRB, PPROT, and the asserted PSEL — are frozen from setup through the completion edge, including across every wait state; PENABLE, PREADY, PRDATA, and PSLVERR are free to move because they are the handshake; and a violation is silent — the subordinate commits the wrong access with no protocol error, which is why you bind a $stable-until-completion assertion. The depth signal that lands: stability is anchored to the completion event, not a cycle count, so the rule is identical for a one-cycle and a ten-cycle access. An interviewer hears that and knows you have debugged a real wait-state corruption, not just read a spec.
8. Q&A
9. Practice
- Partition the signals. From memory, list the frozen set and the free set, and state for each free signal why it must be allowed to change.
- Anchor the window. For a transfer with three wait states, mark the first and last cycle of the freeze window and name the event that ends it.
- Spot the violation. Given a waveform where
PWDATAchanges on the second of three access cycles, state whether it is legal, what the subordinate commits, and whether APB flags it. - Write the assertion. From memory, write the
$stable-until-completion SVA property and explain what its antecedent selects. - Find the silent bug. A register intermittently holds a wrong value, only when the subordinate is slow. Using the stability contract, explain the most likely cause and the one assertion that would have caught it.
10. Key takeaways
- APB freezes the access-defining set —
PADDR,PWRITE,PWDATA,PSTRB,PPROT, and the assertedPSEL— byte-for-byte from setup through the completion edge. - The handshake set is free —
PENABLErises into access;PREADY,PRDATA, andPSLVERRchange during the transfer. Freezing them breaks the bus. - Stability is anchored to completion, not a cycle count. One wait state or ten, the freeze lasts until
PSEL & PENABLE & PREADYis high. - A violation is silent. A mid-access change makes the subordinate commit the wrong location or data with no protocol error — corruption that surfaces downstream.
- The manager satisfies the contract by holding — register the access once, never touch it until completion; the absence of a mid-transfer update is the guarantee.
- Assert it. A
$stable-until-completion property is the single highest-value APB assertion: it converts an invisible corruption into a located, named failure.