How PSTRB enables sparse byte-lane writes on a 32-bit APB bus, the exact bit-to-lane mapping, when PSTRB must be driven to zero, Requester/Completer compatibility rules, and practical examples for common byte and half-word writes.
PSTRB (Peripheral Strobe) is an APB4 write strobe signal that enables sparse data transfer — writing to only some byte lanes of the write data bus while leaving other byte lanes unchanged in the peripheral’s register.
Without PSTRB, every APB write updates all bytes of the target register simultaneously. With PSTRB, a write can update only specific byte lanes. This is essential when:
PSTRB is one bit per data byte. On a 32-bit data bus, PSTRB is 4 bits wide. On a 16-bit bus it is 2 bits, and on an 8-bit bus it is 1 bit (which is always 1 during a write — an 8-bit bus has no sub-byte granularity).
The mapping formula from the spec: PSTRB[n] corresponds to PWDATA[(8n+7):(8n)]. Each strobe bit covers exactly 8 bits (one byte) of write data.
The formula expanded for a 32-bit bus:
| PSTRB bit | PWDATA bits covered | Byte position | Meaning when HIGH |
|---|---|---|---|
PSTRB[3] | PWDATA[31:24] | Byte 3 (MSB) | Most-significant byte is valid write data |
PSTRB[2] | PWDATA[23:16] | Byte 2 | Second byte is valid write data |
PSTRB[1] | PWDATA[15:8] | Byte 1 | Third byte is valid write data |
PSTRB[0] | PWDATA[7:0] | Byte 0 (LSB) | Least-significant byte is valid write data |
Here are the most common PSTRB patterns for a 32-bit APB bus:
PSTRB = 4'b1111 — all four bytes written. This is equivalent to a standard APB write without PSTRB.
PSTRB = 4'b0001 — only the LSB byte is written. The upper three bytes of the register are preserved unchanged.
PSTRB = 4'b1000 — only the MSB byte is written.
PSTRB = 4'b0011 — the lower 16 bits are written, the upper 16 bits are preserved.
PSTRB = 4'b1100 — the upper 16 bits are written, the lower 16 bits are preserved.
PSTRB behaves exactly like PADDR and PPROT — it must be presented in the Setup phase and remain stable through all wait states until transfer completion.
PSTRB has the same stability requirement as PADDR: it must not change between the start of the Setup phase and the end of the Access phase (including all wait state cycles). Changing PSTRB mid-transfer is a protocol violation.
The spec states clearly: “For read transfers, the Requester must drive all bits of PSTRB LOW.”
PSTRB has no meaning for read transfers — there is no concept of reading only some byte lanes on APB. The requirement to drive PSTRB=0 on reads exists because:
Since PSTRB is optional, there are four combinations of Requester and Completer having or not having the signal. The spec defines the compatibility and required behaviour for each:
| Completer: PSTRB absent | Completer: PSTRB present | |
|---|---|---|
| Requester: PSTRB absent |
Compatible. Neither side has PSTRB. All writes update all byte lanes. Sparse writes are not supported. Standard APB behaviour. |
Compatible. Completer has PSTRB inputs but Requester doesn’t drive them. Tie the PSTRB inputs to the PWRITE output from the Requester. This drives PSTRB=4’b1111 on writes (all lanes valid) and PSTRB=4’b0000 on reads. Completer treats every write as a full-word write. |
| Requester: PSTRB present |
Compatible. Requester drives PSTRB but Completer doesn’t have it. Sparse writes are not supported — Completer always updates all byte lanes regardless of PSTRB. The Requester’s PSTRB outputs are simply unconnected (or connected to nothing). |
Compatible. Both sides have PSTRB. Full sparse write capability. PSTRB connects Requester→Completer normally. |
The key insight from the compatibility table: all four combinations are compatible. The worst case is that sparse writes degrade to full-word writes — no data corruption occurs. This makes APB systems easy to mix-and-match across different APB versions.
PSTRB = {DATA_WIDTH/8{PWRITE}}. On a write (PWRITE=1) this drives all strobe bits HIGH (full word write). On a read (PWRITE=0) this drives all strobe bits LOW (correct read behaviour). This is the cleanest solution and requires no additional logic.
A typical 32-bit APB register with byte-enable write logic:
always_ff @(posedge PCLK) begin
if (PSELx && PENABLE && PREADY && PWRITE) begin
if (PSTRB[0]) reg_r[7:0] <= PWDATA[7:0];
if (PSTRB[1]) reg_r[15:8] <= PWDATA[15:8];
if (PSTRB[2]) reg_r[23:16] <= PWDATA[23:16];
if (PSTRB[3]) reg_r[31:24] <= PWDATA[31:24];
end
end
Each byte lane is independently gated by its corresponding PSTRB bit. Only lanes with PSTRB=1 are updated. This is the standard pattern for byte-accessible APB registers.
When bridging from AXI to APB, the AXI write strobe (WSTRB) maps directly to APB’s PSTRB. The bridge captures WSTRB from the AXI write data channel and drives it as PSTRB during the APB write transfer. For AXI read transactions, the bridge drives PSTRB=0 (all bits LOW) as required.
If the AXI data bus is wider than the APB data bus (e.g. 64-bit AXI to 32-bit APB), the bridge must select the appropriate half of WSTRB based on the byte address.
An important requirement from the spec: “Parity signals must be driven appropriately to all the bits in the associated payload, whether or not the bits are actively used in the transfer.” For PSTRB this means: even if only PSTRB[0]=1, the Requester must still drive valid data on all byte lanes of PWDATA (even the ones covered by PSTRB=0). The parity check signal PWDATACHK must cover all PWDATA bits including the “don’t care” lanes.
| Item | Rule |
|---|---|
| PSTRB introduced in | APB4 — not available in APB2 or APB3 |
| Width | DATA_WIDTH/8 bits (4 bits for 32-bit bus, 2 for 16-bit, 1 for 8-bit) |
| Bit mapping | PSTRB[n] covers PWDATA[(8n+7):(8n)] |
| PSTRB[n]=1 | Corresponding byte lane contains valid write data — Completer updates this byte |
| PSTRB[n]=0 | Corresponding byte lane should be ignored — Completer preserves existing register byte |
| During reads | Must be all-zero (mandatory, not recommended) |
| Stability | Must be stable from start of Setup phase until transfer completes — same as PADDR |
| Full word write | PSTRB=4’b1111 (all bytes valid) |
| LSB byte only | PSTRB=4’b0001 |
| MSB byte only | PSTRB=4’b1000 |
| Lower half-word | PSTRB=4’b0011 |
| Upper half-word | PSTRB=4’b1100 |
| Req present, Comp absent | Compatible — Completer always does full-word write, ignores PSTRB |
| Req absent, Comp present | Compatible — tie PSTRB inputs to PWRITE (replicates PWRITE to all strobe bits) |
| Both absent | Compatible — no sparse write support, full-word writes only |
| Both present | Compatible — full sparse write support |