Skip to content

AMBA APB · Module 10

APB4 Introduction

What APB4 added on top of APB3 — PSTRB byte-lane strobes for sub-word writes and PPROT for an access-protection context — aligning the peripheral bus with the wider AMBA (AXI) feature set, and the silent-corruption trap when a strobed write is down-converted to an APB3 segment.

APB4 is APB3 plus exactly two signals: PSTRB and PPROT. Everything else — the two-phase SETUP/ACCESS handshake, PREADY, PSLVERR — is inherited unchanged from APB3. The single idea to carry out of this chapter: APB4 gave APB two capabilities it had never had — byte-level write granularity (PSTRB, one strobe bit per byte lane) and an access-protection context (PPROT, a 3-bit privilege / security / data-or-instruction tag) — and it did so to close the gap with AXI's WSTRB and AxPROT, so an APB peripheral subsystem speaks the same write-granularity and protection semantics as the wider AMBA fabric. This chapter is the version delta: what APB4 added, why, and what breaks when those signals are dropped at a boundary.

1. Problem statement

By APB3, the peripheral bus could stall (PREADY) and report errors (PSLVERR) — but two real-world needs were still unmet, and both came from APB living next to AXI in modern SoCs.

The first gap is write granularity. Every APB write up to and including APB3 updates the entire data word. There is no way to write just one byte of a 32-bit register. But peripheral register maps are full of byte-packed fields — a 32-bit register holding four independent 8-bit control fields, a FIFO that accepts byte writes, a memory-mapped buffer. Without byte strobes, the only way to update one byte is a software read-modify-write: read the word, change the byte in the CPU, write it back. That is two bus transfers and a race window — and it is impossible at all if the register has read side-effects (read-clear status, a read-popping FIFO).

The second gap is access context. An APB3 transfer carries an address, a direction, and data — but nothing about who is making the access or what kind of access it is. A modern SoC needs to enforce that a non-secure master cannot touch a secure peripheral, that an unprivileged access cannot reach a privileged register, that an instruction fetch is distinguishable from a data access. APB3 has no field to carry any of that, so a slave has nothing on which to base an access-control decision.

APB4 solves exactly these two and nothing else: PSTRB for sub-word writes, PPROT for an access-protection context. It does not touch the handshake, the latency model, or the error mechanism. It is the smallest possible extension that brings APB's write and protection semantics in line with AXI.

2. Why previous knowledge is insufficient

You already understand the layers below this one, and APB4 sits directly on top of them — so the way to learn it is to add precisely two signals to what you know, not to relearn the protocol.

  • You know the APB3 delta. Chapter 10.2 — APB3 Introduction taught that APB3 added PREADY (flow control) and PSLVERR (an error verdict) to the baseline. APB4 keeps both unchanged. If you are fuzzy on the handshake or the error channel, fix that there first — this chapter does not re-teach PREADY or PSLVERR.
  • You know the baseline. Chapter 10.1 — APB2 Baseline established the two-phase SETUP/ACCESS core and the original signal set (PADDR, PWRITE, PSEL, PENABLE, PWDATA, PRDATA). APB4 does not alter a single timing relationship in that core. A PSTRBed write is still SETUP-then-ACCESS; PPROT is just more address-phase context driven alongside PADDR.
  • What's genuinely new here. The two additions are version-4 capabilities that nothing in APB2 or APB3 could express: writing part of a word, and tagging an access with protection context. That is the whole subject of this chapter — the version-level capability each adds, not their full mechanics.
  • You have seen protection as a concept. Module 9 — Protection violations discussed what happens when an illegal access is attempted and how a slave flags it via PSLVERR. APB4's PPROT is the signal that carries the context those checks need — the input side of that decision.

For the full mechanics, this chapter forward-links to two dedicated deep dives: Chapter 10.6 — PSTRB feature deep dive covers every byte-lane case, alignment, and bridge conversion; Chapter 10.7 — PPROT feature deep dive covers the full encoding and enforcement model. Here we cover only what version 4 adds and why — enough to read a waveform, write the slave write-path, and reason about a down-conversion boundary.

3. Mental model

The model: APB4 hands the master a stencil and a badge that APB3 never gave it.

  • PSTRB is the stencil. A write no longer paints the whole register — the master lays a stencil over the data word that exposes only the byte lanes it wants to change. PSTRB is that stencil: a bit-vector with one bit per byte lane (4 bits for a 32-bit bus, 8 bits for a 64-bit bus). Where the strobe bit is 1, that byte of PWDATA commits; where it is 0, that byte is ignored and the corresponding register byte is left untouched. A full-word write is just the stencil with every hole open (PSTRB all ones) — which is exactly what APB3 did implicitly.
  • PPROT is the badge. Every access now carries a 3-bit badge describing the nature of the access: PPROT[0] privileged vs normal, PPROT[1] secure vs non-secure, PPROT[2] instruction vs data. The bus driving it doesn't enforce anything — it just presents the context so a slave (or a downstream protection unit) can decide to allow or deny. It is the access's identity papers.
  • The core is untouched. Crucially, both are additive and live in the address phase / write-data path of the existing two-phase transfer. A strobed write is still one SETUP cycle and one (or more, if PREADY waits) ACCESS cycle. PSTRB and PPROT are driven valid alongside PADDR/PWRITE/PWDATA and held for the transfer. Nothing about when the transfer completes changes — only what it writes and what context it carries.

One sharpening fact to fix now: PSTRB is a write-only feature. On a read (PWRITE low), the strobes have no meaning — the slave returns the full word on PRDATA regardless. Strobes gate write commits, nothing else. PPROT, by contrast, accompanies both reads and writes.

A feature figure showing 32-bit PWDATA split into four byte lanes each gated by one PSTRB strobe bit, with PSTRB=0b0110 committing bytes 1 and 2 in green and preserving bytes 0 and 3 in amber, and below it the three PPROT bits decoded as privilege, security, and data-versus-instruction context.
Figure 1 — the two APB4 additions over APB3. Top: the 32-bit PWDATA bus split into four byte lanes, each gated by one PSTRB bit, so PSTRB is a 4-bit vector for a 32-bit bus. The example PSTRB = 0b0110 is a partial write: byte lanes 1 and 2 have their strobe asserted and commit to the register (green), while lanes 0 and 3 have their strobe deasserted and are preserved unchanged (amber) — a sub-word write APB2 and APB3 could not express. Bottom: the 3-bit PPROT context decoded — PPROT[0] privileged vs normal, PPROT[1] secure vs non-secure, PPROT[2] instruction vs data — a privilege/security/access-type tag the bus never carried before. The figure states the precise version identity: APB4 = APB3 + PSTRB + PPROT, two-phase core unchanged, mirroring AXI's WSTRB and AxPROT.

4. Real SoC implementation

In silicon, the APB4 additions touch exactly one place: the slave write path. Reads are unchanged. The write that was a single ctrl <= pwdata; in an APB3 slave becomes a per-byte-lane gated write, and the slave now has pstrb and pprot inputs it can act on.

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
// APB4 slave write path. WHAT CHANGED FROM APB3:
//   + pstrb[3:0]  : one write-strobe bit per byte lane of pwdata
//   + pprot[2:0]  : access-protection context (privilege/secure/instr)
// The handshake (pready/pslverr) and the two-phase core are unchanged.
module apb4_slave #(parameter AW = 8) (
  input              pclk, presetn,
  input              psel, penable, pwrite,
  input  [AW-1:0]    paddr,
  input  [31:0]      pwdata,
  input  [3:0]       pstrb,    // NEW in APB4: byte-lane write strobes
  input  [2:0]       pprot,    // NEW in APB4: access-protection context
  output reg [31:0]  prdata,
  output             pready,
  output             pslverr
);
  reg [31:0] ctrl;
 
  // One ACCESS-cycle write commit, but now PER BYTE LANE.
  // The transfer fires on (psel & penable & pwrite); each byte of ctrl
  // updates only if its strobe bit is set. Unstrobed bytes are PRESERVED.
  wire wr_fire = psel && penable && pwrite && (paddr == 8'h00);
 
  genvar i;
  generate
    for (i = 0; i < 4; i = i + 1) begin : g_lane
      always_ff @(posedge pclk or negedge presetn) begin
        if (!presetn)
          ctrl[i*8 +: 8] <= 8'h00;
        else if (wr_fire && pstrb[i])          // gate this lane on its strobe
          ctrl[i*8 +: 8] <= pwdata[i*8 +: 8];  // only the strobed byte commits
        // else: lane holds its value -> sub-word write preserves it
      end
    end
  endgenerate
 
  // PPROT is the access context. A secure/privileged register can DENY
  // an access that lacks the right context by raising pslverr (the error
  // mechanism is APB3's; PPROT just supplies the input to the decision).
  // pprot[1]==1 => non-secure. Deny a non-secure write to a secure reg:
  wire prot_fail = wr_fire && pprot[1];        // example policy only
  assign pslverr = prot_fail;
  assign pready  = 1'b1;                        // single-cycle slave
 
  // READ is unchanged from APB3: full word, no strobes on reads.
  always_comb prdata = (paddr == 8'h00) ? ctrl : 32'h0;
endmodule

Two facts define APB4 RTL. First, the write path is now a for-loop over byte lanes, each gated independently on pstrb[i] — that single change is the entire mechanical difference from APB3's full-word write. Get the lane indexing right (pwdata[i*8 +: 8]) and a sub-word write naturally preserves the unstrobed bytes. Second, pprot is an input to a policy, not an enforcement mechanism by itself — the slave reads the context and chooses to deny (here via pslverr); the bus only guarantees the context is presented. Both are forward-detailed in the PSTRB deep dive and the PPROT deep dive.

5. Engineering tradeoffs

APB4 is a deliberately small delta. The table makes the version comparison precise — what each dimension was in APB3 and what APB4 changed it to.

DimensionAPB3APB4Why APB4 changed it
Write granularityFull word only — every write updates all 32 bitsPer-byte-lane via PSTRB (1 strobe bit / byte lane)Native sub-word writes; no software read-modify-write
Access contextNone — address + direction + data onlyPPROT[2:0]: privilege / secure / data-vs-instructionLets slaves enforce protection without a side-band
AXI alignmentMisaligned — AXI had WSTRB, AxPROT; APB had neitherPSTRB ↔ AXI WSTRB; PPROT ↔ AXI AxPROTA peripheral subsystem carries the same write/protection semantics as the fabric
Two-phase coreSETUP/ACCESS, PREADY, PSLVERRIdentical — unchangedThe delta is purely additive; no timing impact
Backward compatAn APB4 master → APB3 slave drops PSTRB/PPROTSafe for PPROT (slave enforces nothing); unsafe for PSTRB (partial write becomes full-word write)

The byte-lane mapping for the canonical 32-bit bus, to fix the indexing:

PSTRB bitByte lanePWDATA bitsRegister byte gated
PSTRB[0]Byte 0 (LSB)PWDATA[7:0]bits [7:0]
PSTRB[1]Byte 1PWDATA[15:8]bits [15:8]
PSTRB[2]Byte 2PWDATA[23:16]bits [23:16]
PSTRB[3]Byte 3 (MSB)PWDATA[31:24]bits [31:24]

The throughline: APB4 paid almost nothing — two signals, one loop in the slave write path — to gain byte-level writes and a protection context, and in doing so it stopped being the AMBA outlier whose write/protection semantics didn't match AXI. The cost is entirely at version boundaries, which is the next section's subject.

6. Common RTL mistakes

7. Debugging scenario

A classic APB4 integration bug: an APB4 master issues a perfectly correct sub-word write, but somewhere on the path a bridge or wrapper down-converts to an APB3 slave and the byte strobes are lost — so the partial write silently becomes a full-word write and clobbers the bytes that should have been preserved.

  • Observed symptom: firmware writes one byte field of a packed 32-bit control register and the other three byte fields read back as garbage afterward — even though nothing wrote them. The same code works in a pure-APB4 unit testbench but corrupts the register once integrated through a particular bridge. The failure is intermittent in a way that tracks which other bytes were last on the bus.
  • Waveform clue: at the master, PSTRB = 0b0010 (byte-1-only write) and PWDATA = 0xZZ_ZZ_AA_ZZ — only lane 1 carries a meaningful value, the rest are don't-care. Trace the same transfer at the slave port: there is no PSTRB line on the slave at all, and the slave's register updates all four bytes to 0xZZ_AA_ZZ_ZZ. The strobe vanished between the two ports.
  • Root cause: the bridge bridging the APB4 segment to an APB3 slave has no PSTRB path — an APB3 slave has no such input — so the bridge drops the strobes. The APB3 slave, having no concept of byte lanes, writes the whole word on every write, including the don't-care lanes the master never intended to commit. The three preserved bytes are overwritten with whatever was on PWDATA[31:24], PWDATA[23:16], and PWDATA[7:0] — silent corruption that no error response flags.
  • Correct RTL: a version-down-converting bridge must never silently drop PSTRB. Either (a) forbid sub-word writes across the boundary and have the bridge raise PSLVERR on any write with PSTRB != all-ones, or (b) have the bridge convert a strobed write into a read-modify-write to the APB3 slave — read the word, merge only the strobed bytes, write the merged word back:
Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
// Bridge down-converting an APB4 strobed write to an APB3 full-word slave.
// Merge strobed bytes over the slave's current value (read-modify-write).
for (int i = 0; i < 4; i++)
  merged[i*8 +: 8] = pstrb[i] ? pwdata[i*8 +: 8]   // master's new byte
                              : rdback[i*8 +: 8];   // preserved old byte
// then drive `merged` as the full-word APB3 write
  • Verification assertion: at any APB4→APB3 boundary, prove the strobes are never silently lost — either the down-conversion preserves the partial-write semantics, or a non-full-word strobe is rejected outright:
Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
// A sub-word write must NOT reach an APB3 slave as a plain full-word write.
// At the bridge boundary, a partial strobe must be merged or errored.
property no_silent_strobe_drop;
  @(posedge pclk) disable iff (!presetn)
    (psel && penable && pwrite && (pstrb != 4'hF))
      |-> (bridge_does_rmw || pslverr);
endproperty
assert property (no_silent_strobe_drop);
  • Debug habit: when a register's untouched bytes change, suspect a strobe-loss boundary before suspecting the slave. Trace PSTRB from the master port to the slave port and confirm it exists and matches at both ends. A whole class of APB4 bugs is "the strobe was right at the source and gone at the sink" — check the signal survives the path, not just that it was driven correctly.
Two stacked cases of a byte-1-only APB4 write. The top correct case shows an APB4 slave honouring PSTRB and preserving three bytes, yielding 0x1122AA44 in green. The bottom buggy case shows a bridge dropping PSTRB at an APB4-to-APB3 boundary so the APB3 slave writes the whole word including don't-care lanes, corrupting the register to 0xZZAAZZZZ in red.
Figure 2 — PSTRB dropped at an APB4→APB3 boundary. An APB4 master issues a byte-1-only write (PSTRB = 0b0010, PWDATA = ZZ ZZ AA ZZ) to a register holding 0x11223344. Top (correct, green): the transfer reaches a true APB4 slave that honours PSTRB, so only byte 1 commits and the result is 0x1122AA44 — the three unstrobed bytes are preserved. Bottom (bug, red): a bridge drops PSTRB at the APB4→APB3 boundary; the APB3 slave has no byte-strobe concept and writes the full 32-bit word including the don't-care lanes, so the register becomes 0xZZAAZZZZ — the three bytes that should have been preserved are silently corrupted with whatever was on the unused PWDATA lanes. The figure teaches that dropping PSTRB is not harmless: it converts a partial write into a full-word write and corrupts the bytes the master intended to keep.

8. Verification perspective

Verifying APB4 is about covering the new state space the two additions opened up — every meaningful byte-strobe pattern, the protection contexts, and the down-conversion seams where version 4 meets version 3.

  • PSTRB pattern coverage. A single full-word check is not enough — the strobes create a combinatorial space that must be sampled. The coverage model must hit: all lanes strobed (PSTRB = 4'hF, the full-word case), a single lane strobed (each of 0001, 0010, 0100, 1000 — proving each byte commits independently and the others are preserved), multiple non-contiguous lanes (e.g. 0101, 1010 — proving lanes are truly independent and there is no carry between them), and zero lanes strobed (PSTRB = 4'h0 — a write that commits nothing; the register must be unchanged). For each pattern, check both that the strobed bytes took the new value and that the unstrobed bytes are bit-exact unchanged.
  • PPROT coverage. Cross the three bits — privilege × security × data/instruction — at least to the legal/illegal boundary the design cares about. For a secure/privileged register, cover the denied contexts (non-secure access, unprivileged access) and confirm the slave raises PSLVERR, and cover the allowed contexts and confirm it does not. Cover PPROT on both reads and writes (unlike PSTRB, it applies to both).
  • Version-down-conversion checks at bridges. This is where the real bugs live. At every APB4→APB3 boundary, assert/cover the adaptation explicitly: what does the bridge do with a partial PSTRB? (Must merge via read-modify-write or error — never silently full-word write, per Beat 7's assertion.) What does it do with PPROT? (Dropping it is safe but must be intentional — cover that the downstream slave's protection isn't silently bypassed.) A directed test that drives PSTRB != 4'hF through the bridge and checks the unstrobed bytes survive is the single highest-value APB4 integration test.

The point: APB4 verification is APB3 verification plus a strobe-pattern coverage model plus a protection-context coverage model plus a hard focus on the down-conversion boundary — because the additions are small but their failure modes (silent byte corruption, silent protection bypass) are severe and late-found.

9. Interview discussion

"What did APB4 add over APB3?" is a precise version-awareness filter, and the clean answer is two signals plus the why.

State it crisply: APB4 = APB3 + PSTRB + PPROT, with the two-phase core unchanged. PSTRB is byte-lane write strobes — one bit per byte lane (4 bits on a 32-bit bus) — gating which bytes of PWDATA commit, enabling native sub-word writes where APB2/APB3 could only write a full word. PPROT is a 3-bit access-protection context: privilege, security, and data-vs-instruction. Then deliver the depth signal: explain whyAXI alignment. AXI already had WSTRB (write strobes) and AxPROT (protection); APB4 added the APB equivalents so a peripheral subsystem carries the same write-granularity and protection semantics as the AXI fabric it hangs off, with no semantic gap at the bridge. Close with the integration trap that proves you've actually built one: at an APB4→APB3 boundary the strobes are dropped, which is safe for PPROT (the slave just enforces nothing) but dangerous for PSTRB — a partial write silently becomes a full-word write and corrupts the bytes that should have been preserved, so a correct bridge must do a read-modify-write or reject the partial write. Naming that failure mode is what separates "read the spec" from "debugged the silicon."

10. Practice

  1. State the delta. From memory, write the exact APB4 additions over APB3 — name both signals, give the bit width of each (including how PSTRB width relates to bus width), and label what each bit of PPROT means.
  2. Decode a strobe. Given a 32-bit register initially 0xDEADBEEF, a write with PWDATA = 0x11223344 and PSTRB = 0b1010, compute the register's final value byte by byte.
  3. Why one bit isn't enough. Explain why PSTRB must be one bit per byte lane rather than a single write-enable, using the example "write only byte 2 of a 32-bit register."
  4. Trace the corruption. Walk an APB4 byte-1 write through a bridge to an APB3 slave that drops PSTRB, and state the exact final register value and why it's wrong — then give two correct bridge behaviours.
  5. Build the policy. Sketch the slave logic that denies a non-secure write to a secure register using PPROT, and state which existing APB3 signal carries the denial back to the master.

11. Q&A

12. Key takeaways

  • APB4 = APB3 + PSTRB + PPROT. Two additive signals; the two-phase SETUP/ACCESS core, PREADY, and PSLVERR are inherited unchanged.
  • PSTRB is byte-lane write strobes — one bit per byte lane (4 bits on a 32-bit bus). Where the bit is 1 the byte of PWDATA commits; where 0 the register byte is preserved. This gives APB native sub-word writes for the first time. It is write-only — meaningless on reads.
  • PPROT is a 3-bit access-protection context: privilege ([0]), security ([1]), data-vs-instruction ([2]). It carries context for a slave to act on; it does not enforce by itself.
  • The reason is AXI alignment. PSTRB mirrors AXI WSTRB and PPROT mirrors AXI AxPROT, so an APB peripheral subsystem speaks the same write-granularity and protection semantics as the wider AMBA fabric.
  • Backward compat is asymmetric. An APB4 master to an APB3 slave drops both — safe for PPROT (no enforcement), dangerous for PSTRB (a partial write silently becomes a full-word write, corrupting the preserved bytes).
  • The bug to fear is silent strobe loss at a boundary. A down-conversion must merge strobed writes via read-modify-write or reject them — never drop PSTRB silently. Full mechanics are in the PSTRB deep dive and the PPROT deep dive.