Skip to content

AMBA APB · Module 7

PWDATA Timing

When PWDATA must be valid and who drives it — the manager's drive obligation to present it in setup and hold it byte-for-byte stable through access until the commit, the mirror of PRDATA's subordinate-owned validity.

Module 3 told you where PWDATA lives — manager-driven, captured at completion. This chapter pins the edges: the precise window during which PWDATA must be valid, who is obligated to keep it there, and the single instant the subordinate consumes it. PWDATA has one timing obligation that belongs entirely to the manager — present the value in SETUP and hold it byte-for-byte stable through every ACCESS cycle, wait states included, until the commit edge. The single idea to carry: the subordinate captures whatever is on PWDATA at the commit edge, so the value is correct only because the manager held it there. Drop it early, or change it mid-access, and the subordinate captures the wrong value — and nothing on the bus warns you.

1. Problem statement

The problem is guaranteeing that the value the subordinate samples on the commit edge is exactly the value the manager intended to write — across a bus where the manager cannot know in advance which cycle will commit.

A write has no data return leg, so there is no read-back inside the transfer to confirm what landed. The subordinate simply latches PWDATA on the one cycle the handshake completes. That creates a timing obligation: the value has to be valid and unchanging on that cycle — but the manager does not choose the cycle. A slow subordinate inserts wait states and completes later; a fast one completes on the first access cycle. The manager has no way to "aim" PWDATA at the right edge. So APB resolves it with a window, not a target:

  • Present in SETUP. PWDATA is driven from the setup cycle, so it is settled a full cycle before any capture can occur.
  • Hold through ACCESS. PWDATA is held byte-for-byte stable through every access cycle — including each wait state where PREADY is low — so the value is still valid on whichever cycle finally commits.
  • Capture once. The subordinate samples on exactly the completion edge — PSEL, PENABLE, PWRITE, and PREADY all high — and never before.

The window absorbs the uncertainty. Because PWDATA is valid across the whole access phase, the same capture rule works whether the commit lands on cycle one or cycle five. The obligation to maintain that window is the manager's, and it is the entire subject of this chapter.

2. Why previous knowledge is insufficient

Module 3 — the PWDATA signal gave you the role and the half-sentence contract: "presented from setup, held through access, captured at completion." That is correct, and you should keep it. What it does not do is treat the hold as a timing obligation with an owner and a failure mode — and that is exactly what you need to drive a real manager or sign off a real write monitor. This chapter drills three things Module 3 stated but did not pin:

  • The manager's drive obligation is a timing contract, not a convenience. Module 3 says the manager "holds" PWDATA. This chapter makes that a duty with an edge: the manager must keep PWDATA valid for every cycle from setup until the commit edge, because it cannot predict the commit cycle. Holding is not the manager being polite — it is the only way a single capture rule can be correct for every subordinate speed.
  • The exact valid window has a near edge and a far edge. Near edge: the setup cycle (driven, settled). Far edge: the commit edge (sampled). Between them, including every wait cycle, PWDATA must not move by a single bit. Module 3 named the endpoints; here we mark the band and the one capture edge on the waveform and reason about why each cycle in between must stay frozen.
  • The capture is "whatever is there now," so the failure mode is silent corruption. Module 3's bug was early capture (committing before completion). This chapter's bug is the mirror: correct-timed capture of a value the manager already corrupted — the manager released or changed PWDATA before the commit, so the subordinate dutifully latches a wrong or partial value at the right edge. That is the deeper, write-specific hazard, and it is the mirror of a read, where the subordinate owns PRDATA validity.

So the model to add is not "where the data lives" but the manager's hold-until-commit obligation and the silent corruption that follows when it breaks.

3. Mental model

The model: PWDATA is a number you write on a whiteboard and must keep your hand off until the clerk copies it down — and the clerk copies whatever the board says at the moment they look, not what you originally wrote.

You write the value the instant you start (presented in SETUP). The clerk is busy and may take a while — you do not know how long — so you must keep the board frozen, hand off, however many cycles it takes (held stable through ACCESS and every wait state). At one unpredictable instant the clerk glances up and copies the board verbatim (captured at the commit edge). If you smudged a digit, erased the top half, or started rewriting it the moment before they looked, the clerk copies that — a wrong number — and walks away satisfied. The board offered the value the whole time; the clerk consumed exactly one snapshot, and they trusted you to keep it true.

Three refinements make the timing precise:

  • The far edge is unpredictable, so you hold across the whole window. You cannot aim PWDATA at the commit cycle because the subordinate, via PREADY, decides when that is. You guarantee the value by freezing it for every cycle it could possibly be sampled — setup through completion.
  • A wait state is not permission to touch the data. While PREADY is low the access is held, not paused-for-you. The manager must hold PWDATA exactly as stable during a wait as during a ready cycle. The wait is the subordinate's, but the hold is still yours.
  • The capture is a verbatim snapshot. The subordinate does not validate PWDATA, average it, or wait for it to settle — it latches the literal bus state on the commit edge. Stability is not requested; it is assumed. That is why the corruption is silent.
An APB write timing diagram with rows PCLK, PSEL, PENABLE, PWRITE, PWDATA, PREADY and phases IDLE, SETUP, ACCESS WAIT, ACCESS COMMIT, IDLE: PWDATA is driven from setup as a single stable band 0xA5C3 held across the wait state and into the completion cycle, with a bracket marking the held-stable band and a dashed marker on the commit edge where the subordinate samples it.
Figure 1 — the PWDATA valid window across a write with one wait state, against PCLK. PWDATA is presented by the manager in SETUP and held byte-for-byte stable as one continuous band through the ACCESS wait cycle (PREADY low, the access held) and into the completion cycle. A bracket spans the entire held-stable band — the manager's drive obligation — and a single dashed marker pins the commit edge, the one cycle where PSEL, PENABLE, PWRITE, and PREADY are all high, where the subordinate samples PWDATA. The figure makes the near edge (SETUP, settled) and far edge (commit, sampled) explicit, and shows why the value must survive the wait: the manager cannot predict which access cycle completes, so it freezes PWDATA across all of them.

4. Real SoC implementation

In silicon the contract has two halves that meet at the commit edge. On the manager side, PWDATA is driven from a register loaded when the transfer is launched and held by the manager FSM — the same register output feeds the bus for setup and every access cycle, so the value physically cannot change until the FSM advances past completion. On the subordinate side, PWDATA flows combinationally to every register's data input, and a single gated write-enable clocks it on the commit edge. The correctness of the captured value is not enforced by the subordinate — it is inherited from the manager's hold.

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
// PWDATA timing — manager presents and HOLDS; subordinate captures the snapshot.
// The manager drives wdata_q from setup and holds it; the subordinate samples
// whatever is on PWDATA at the commit edge. Because the manager held it stable,
// the captured value EQUALS the presented value.
 
// --- manager side: drive from setup, hold until the FSM leaves ACCESS ---
always_ff @(posedge pclk or negedge presetn) begin
  if (!presetn)               wdata_q <= '0;
  else if (start_transfer)    wdata_q <= cpu_wdata;   // load once, at launch
  // NOTE: no other assignment. wdata_q is FROZEN across setup + every access
  // cycle, so PWDATA cannot move while the subordinate is deciding when to commit.
end
assign pwdata = wdata_q;                              // held value drives the bus
 
// --- subordinate side: capture the snapshot on the one commit edge ---
wire write_commit = psel & penable & pwrite & pready; // the single capture edge
always_ff @(posedge pclk or negedge presetn) begin
  if (!presetn)                                  ctrl_q <= '0;
  else if (write_commit && (paddr == ADDR_CTRL)) ctrl_q <= pwdata; // verbatim snapshot
end
// ctrl_q == cpu_wdata holds ONLY because pwdata was unchanged from load to commit.

Two facts make the timing robust. First, the manager's wdata_q is assigned in exactly one place — at launch — so there is no RTL path that can change PWDATA mid-transfer; the hold is structural, not a discipline the FSM has to remember each cycle. Second, the subordinate's capture is a verbatim snapshot of the bus on the commit edge: ctrl_q <= pwdata. The equality "captured value equals presented value" is therefore not something the subordinate guarantees — it is a consequence of the manager holding PWDATA from load to commit. Break the hold and the same line silently latches a corrupted value. (The completion edge itself is the subject of the write completion contract; here we care only that PWDATA is valid on it.)

A structural figure split into a write half and a read half. In the write half a MANAGER block drives PWDATA right to a SUBORDINATE block that only captures it. In the read half a SUBORDINATE block drives PRDATA left to a MANAGER block that samples it at completion. Labels state the producer owns stability: the manager for PWDATA, the subordinate for PRDATA.
Figure 2 — the write/read ownership mirror. Top (write): the MANAGER drives PWDATA across the bus to the SUBORDINATE and owns its stability — it must hold PWDATA byte-for-byte from setup until the commit, where the subordinate captures it but never drives it. Bottom (read, the mirror): the SUBORDINATE drives PRDATA back to the MANAGER and owns its stability — it presents PRDATA valid only at completion, where the manager samples it. The figure makes the rule explicit: whoever produces the data owns its timing — the manager for PWDATA on a write, the subordinate for PRDATA on a read — so a write's hold obligation sits on the manager exactly where a read's present-valid obligation sits on the subordinate.

5. Engineering tradeoffs

Placing the entire PWDATA timing obligation on the manager — present early, hold across the whole window — is a deliberate split. Each property trades a capability APB does not need for the timing simplicity it does.

PWDATA timing propertyWhat it gives upWhat it buysWhy it is correct for APB
Presented in SETUP, a cycle before any captureJust-in-time data deliveryA value settled well before the earliest possible commitThe subordinate never sees PWDATA mid-transition
Held stable through every wait cycleFreedom to update data mid-accessA value valid on whichever cycle commitsOne capture rule works at any subordinate speed
Hold owned by the manager (the producer)A shared stability burdenA single, locatable owner of write-data timingThe producer of the data is the one that can hold it
Subordinate captures a verbatim snapshotSubordinate-side data validationA trivially simple capture: one gated flopValidity is guaranteed upstream, so no checking is needed
Far edge (commit) chosen by the subordinateA manager that can aim at a fixed cycleA handshake that decouples data hold from completion timingThe manager holds a window, not a moment

The throughline: APB pays for the manager holding PWDATA across a window it cannot predict, and in return the capture is a single unconditional snapshot that is correct at any subordinate speed. The cost lives entirely on the producer; the consumer just latches. That is the same bargain a read strikes in reverse — there the subordinate, as producer, owns PRDATA's validity, and the manager just samples.

6. Common RTL mistakes

7. Debugging scenario

A write where PWDATA was released or changed before the commit is the mirror of the "write doesn't stick" bug: here the write does stick — it just sticks the wrong value — and like all write bugs it is invisible on the bus.

Two stacked APB write waveforms with one wait state and identical PENABLE and PREADY. The top correct case holds PWDATA at 0xA5C3 from setup to the commit edge and captures 0xA5C3 in green. The bottom buggy case shows PWDATA changing from 0xA5C3 to 0x00C3 during the wait state, and the commit edge captures the wrong 0x00C3 in red.
Figure 3 — the unstable-PWDATA bug, on a write with one wait state. Top (correct, green): PWDATA holds 0xA5C3 byte-for-byte from SETUP through the wait and into the commit edge, so the subordinate captures the intended 0xA5C3. Bottom (bug, red): the manager presents 0xA5C3 in SETUP but changes PWDATA mid-access during the wait — the high byte drops, leaving 0x00C3 — so on the same commit edge the subordinate captures 0x00C3, a wrong, partial value. The commit edge is identical in both rows; only the held-stable band differs. The figure shows that the subordinate captures whatever is on PWDATA at the commit edge, so corrupting the data before that edge silently corrupts the write — there is no bus signal that flags it.

8. Verification perspective

PWDATA timing is verified on two fronts: an assertion that the manager honored the hold, and a scoreboard that the captured value equals the presented value. Together they catch the corruption the bus cannot show.

  • Assert the hold, edge for edge. The core property is PWDATA stability across a held write access: while a write is in access and not yet complete, PWDATA must not change. Written as assert property (@(posedge pclk) (psel & penable & pwrite & ~pready) |=> $stable(pwdata));, it fires the instant the manager moves PWDATA during a wait — exactly the debug scenario, now caught automatically and at its source rather than via a downstream mismatch. A companion property can require $stable(pwdata) from the setup cycle through the commit for the whole window.
  • Scoreboard the snapshot against the presentation. The monitor records PWDATA at the setup cycle as presented_data; on write_commit it records the captured bus value and asserts captured == presented. Because the reference model updates model_reg[paddr] = pwdata on the commit and a later read compares PRDATA to the model, a held-then-corrupted write surfaces as both a stability assertion failure and a read-back mismatch — two independent nets under the same bug.
  • Cover the timing corners. Functional coverage must hit a write with PWDATA changing value between back-to-back transfers (to prove the new value, not a stale one, is captured), a write whose commit lands after one wait and after several (to prove the hold survives long waits), and writes to every register (to prove the snapshot reaches the right flop). The cross of "number of wait states" with "register written" closes the gap where a long wait could let PWDATA drift.

The point: a write monitor that checks only that PREADY rose has verified the handshake, not the data. The $stable(pwdata)-until-commit assertion is what verifies the manager's actual obligation, and the scoreboard is what proves the snapshot was the intended value.

9. Interview discussion

"When must PWDATA be valid, and whose job is it to keep it valid?" separates someone who memorized "held through access" from someone who understands the timing contract. A weak answer says "the manager drives it." A strong one names the window, the owner, and the failure mode.

Lead with the window and the owner: PWDATA is presented in SETUP and must be held byte-for-byte stable through every ACCESS cycle, wait states included, until the commit edge — and that hold is entirely the manager's obligation, because the manager cannot predict which cycle the subordinate will complete. Then give the consumer's side: the subordinate captures a verbatim snapshot on the commit edge (PSEL & PENABLE & PWRITE & PREADY), so the captured value equals the intended value only because the manager held it. Then deliver the two depth points that mark seniority: the failure mode is silent — releasing or changing PWDATA before the commit makes the subordinate latch a wrong or partial value at the correct edge, invisible on the bus and provable only by read-back or scoreboard — and it is the mirror of PRDATA, where the subordinate is the producer and owns the validity, so the same "producer owns the data's timing" rule explains both directions. Closing with "I'd bind a $stable(pwdata)-until-commit assertion to catch it at the source" signals you verify the obligation, not just the handshake.

10. Practice

  1. Mark the window. On a write waveform with two wait states, draw PWDATA and shade the exact cycles it must be held stable. Mark the near edge, the far edge, and the single capture edge, and state who owns the hold on each cycle in between.
  2. Trace the corruption. Given a waveform where PWDATA changes from 0xA5C3 to 0x00C3 during a wait state, state what the subordinate captures on the commit edge and why the bus shows nothing wrong.
  3. Write the hold. From memory, write the manager-side RTL that drives PWDATA from a value loaded once at launch and held until the FSM leaves access, and explain why a combinational PWDATA source is a latent bug.
  4. Write the assertion. Write the $stable(pwdata)-until-commit SVA property and explain each term, then explain why a PREADY-only check would pass on the corrupted write.
  5. Mirror it to a read. State which side owns data-timing on a read, on which signal, and the analogous obligation — then explain in one sentence why "the producer owns the data's timing" covers both PWDATA and PRDATA.

11. Q&A

12. Key takeaways

  • PWDATA has one timing window — driven from SETUP (near edge), held byte-for-byte stable through every ACCESS cycle, and sampled on the commit edge (far edge). The whole window must stay valid because the far edge is chosen by the subordinate, not the manager.
  • The hold is the manager's obligation. The manager owns PWDATA's stability from setup to commit; the subordinate only captures. A wait state holds the access but never relaxes the manager's hold.
  • The subordinate captures a verbatim snapshot. It latches whatever is on PWDATA at the commit edge with no validation, so the captured value equals the intended value only because the manager held it stable.
  • The failure mode is silent corruption. Releasing or changing PWDATA before the commit makes the subordinate latch a wrong or partial value at the correct edge — invisible on the bus, provable only by read-back or scoreboard.
  • Verify the hold at its source. Bind assert property (@(posedge pclk) (psel & penable & pwrite & ~pready) |=> $stable(pwdata)); and scoreboard the captured value against the value presented in setup; a PREADY-only check verifies the handshake, not the data.
  • It mirrors PRDATA. The producer owns the data's timing — the manager holds PWDATA until the subordinate samples it; the subordinate presents PRDATA valid at completion for the manager to sample. One rule covers write and read data integrity.