APB3 can wait and report errors, but it always writes a whole word and it cannot tell who is asking. APB4 adds two signals for that: PSTRB selects which bytes of a write are valid, and PPROT tells the completer whether an access is privileged, Secure or Non-secure, and for data or instructions. APB5 then adds optional extras for power, safety and system-specific information. This article covers each addition and builds an APB4 completer that uses both new signals.

8 min read | Intermediate

What You'll Learn

  • Write single bytes and halfwords with PSTRB
  • Decode the three PPROT bits and protect a register with them
  • Connect APB3 and APB4 blocks safely
  • Recognize the optional APB5 signals: wake-up, user signals, parity and RME

Write Strobes: PSTRB

PSTRB has one bit per byte of the write data. PSTRB[n] covers PWDATA[8n+7:8n], so a 32-bit bus has four strobes. A completer updates only the bytes whose strobe is high and leaves the others alone. That lets software write one byte of a register without first reading it, changing the byte, and writing it back.

Two rules apply. For reads, the requester must drive all PSTRB bits low. And PSTRB is one of the signals that must stay steady while the completer holds PREADY low.

Protection: PPROT

PPROT is three bits that describe the access:

BitLowHigh
PPROT[0]Normal accessPrivileged access
PPROT[1]Secure accessNon-secure access
PPROT[2]Data accessInstruction access

Watch the polarity of bit 1: a high value means Non-secure. Bit 1 is the one most designs care about. In a system with a Secure world, for example running secure firmware next to a normal operating system, a peripheral can refuse Non-secure accesses to its key or configuration registers. The specification treats bit 2 as a hint that might not be accurate, and allows systems to interpret bits 0 and 2 in their own way.

Quick Check

Q: An access arrives with PPROT = 3'b011. Describe it.

Show Answer

Bit 0 = 1: privileged. Bit 1 = 1: Non-secure. Bit 2 = 0: data. A privileged, Non-secure data access, such as an operating system kernel accessing a peripheral.

An APB4 Completer

This completer has two registers. DATA at 0x0 is a normal register that honours PSTRB. KEY at 0x4 may only be accessed by Secure software. A Non-secure access to KEY gets PSLVERR; a Non-secure write is ignored and a Non-secure read returns zero, so the error and the data agree.


module apb4_regs (
  input             PCLK,
  input             PRESETn,
  input             PSEL,
  input             PENABLE,
  input             PWRITE,
  input      [11:0] PADDR,
  input      [31:0] PWDATA,
  input      [3:0]  PSTRB,
  input      [2:0]  PPROT,
  output reg [31:0] PRDATA,
  output            PREADY,
  output            PSLVERR
);
  reg [31:0] data_r;
  reg [31:0] key_r;

  wire access    = PSEL && PENABLE;
  wire hit_data  = (PADDR == 12'h000);
  wire hit_key   = (PADDR == 12'h004);
  wire nonsecure = PPROT[1];             // PPROT[1]: 0 = Secure, 1 = Non-secure
  wire denied    = hit_key && nonsecure;

  assign PREADY  = 1'b1;
  assign PSLVERR = access && (denied || !(hit_data || hit_key));

  always @(posedge PCLK) begin
    if (!PRESETn) begin
      data_r <= 32'h0;
      key_r  <= 32'h0;
    end
    else if (access && PWRITE) begin
      if (hit_data) begin
        if (PSTRB[0])
          data_r[7:0]   <= PWDATA[7:0];
        if (PSTRB[1])
          data_r[15:8]  <= PWDATA[15:8];
        if (PSTRB[2])
          data_r[23:16] <= PWDATA[23:16];
        if (PSTRB[3])
          data_r[31:24] <= PWDATA[31:24];
      end
      else if (hit_key && !nonsecure) begin
        key_r <= PWDATA;
      end
    end
  end

  always @(*) begin
    if (hit_data)
      PRDATA = data_r;
    else if (hit_key && !nonsecure)
      PRDATA = key_r;
    else
      PRDATA = 32'h0;
  end
endmodule

The four if statements are the whole strobe logic: one byte enable per lane. A wider bus repeats the pattern, often with a for loop.

The Simulation

The write task gets two more arguments, the strobes and the protection bits, and the read task one (strobes are always zero for reads):


apb_write(12'h000, 32'h1111_1111, 4'b1111, 3'b000);   // all four bytes
apb_write(12'h000, 32'hAABB_CCDD, 4'b0101, 3'b000);   // bytes 0 and 2 only
apb_read (12'h000, 3'b000, rdata);
apb_write(12'h004, 32'h5EC0_0001, 4'b1111, 3'b000);   // Secure write to KEY
apb_write(12'h004, 32'hBAD0_0000, 4'b1111, 3'b010);   // Non-secure write: error
apb_read (12'h004, 3'b010, rdata);                    // Non-secure read: error
apb_read (12'h004, 3'b000, rdata);                    // Secure read
Output
45  write 0x000 = 0x11111111 strb=1111 prot=000
75  write 0x000 = 0xaabbccdd strb=0101 prot=000
105  read  0x000 = 0x11bb11dd          prot=000
135  write 0x004 = 0x5ec00001 strb=1111 prot=000
165  write 0x004 = 0xbad00000 strb=1111 prot=010  PSLVERR
195  read  0x004 = 0x00000000          prot=010  PSLVERR
225  read  0x004 = 0x5ec00001          prot=000

The second write changed only bytes 0 and 2, so DATA reads back 0x11BB11DD. The Non-secure write to KEY failed and did not change it: the Secure read at the end still returns 0x5EC00001.

Mixing APB3 and APB4 Blocks

PSTRB and PPROT are optional, so you will meet blocks with and without them. The specification says how to connect them:

  • APB4 requester, completer without PSTRB: compatible, but the completer writes all bytes. Software must not rely on byte writes to that block.
  • Requester without PSTRB, APB4 completer: tie the completer's PSTRB inputs to the requester's PWRITE. Every write then enables all bytes, and every read has strobes low.
  • PPROT: a completer without it ignores protection. A completer that has it, behind a requester that does not, is only compatible if fixed protection values are good enough: its PPROT inputs are tied to a constant, and that constant decides whether it sees every access as Secure or Non-secure.

Quick Check

Q: The APB4 completer above is connected to an old bridge without PPROT, and its PPROT inputs are tied to zero. What happens to the KEY protection?

Show Answer

It disappears. Every access looks Secure, so any software can read and write KEY. Protection only works if the whole path from the processor carries the security state.

What APB5 Adds

APB5 keeps everything in APB4 and adds optional features. Each one is enabled by a property of the interface, so most APB5 blocks use only a few of them.

  • Wake-up (PWAKEUP): a glitch-free signal from the requester that says activity is coming. A clock controller can use it to turn on the clock of a gated peripheral before the transfer arrives. A completer may wait for PWAKEUP before it raises PREADY.
  • User signals (PAUSER, PWUSER, PRUSER, PBUSER): extra bits of request, write data, read data and response information whose meaning the system defines. The specification recommends not using them unless needed, since two blocks may disagree on what they mean.
  • Parity protection: check signals such as PADDRCHK, PWDATACHK and PRDATACHK carry odd parity, one bit per byte, so that safety-critical chips can detect a single-bit error on the wires between blocks.
  • RME (PNSE): the Realm Management Extension adds one bit that, together with PPROT[1], selects one of four physical address spaces instead of two.

Running It in ChipVerify Lab

The example contains the APB4 completer and the testbench. Run it and compare PSTRB with the bytes of DATA that change.

Common Mistakes

Mistake #1: Reading PPROT[1] the wrong way round

PPROT[1] = 1 means Non-secure. A completer that treats 1 as Secure lets Non-secure software in and locks Secure software out.

Mistake #2: Driving PSTRB on reads

The requester must drive all strobes low for a read. A completer should not need them for a read, but a checker will flag a requester that drives them.

Mistake #3: Returning the secret on a refused read

An error on a read does not stop the requester from using PRDATA. A completer that refuses an access must also hide the data, as KEY does by returning zero.

Practice Exercise

Challenge: Privileged and Secure

Tighten KEY: it now needs an access that is both Secure and privileged. Change the completer, then run the unchanged testbench. Which transfers fail now? Then fix the testbench so the Secure accesses to KEY succeed again.

Hint

Privileged is PPROT[0] = 1. The testbench uses 3'b000 for its Secure accesses, which is Secure but not privileged.

Solution

wire denied = hit_key && (nonsecure || !PPROT[0]);   // Secure and privileged only
// and use !denied instead of !nonsecure in the write and read logic

With the unchanged testbench, every access to KEY fails, including the write at 135 and the read at 225, because 3'b000 is not privileged. Change the Secure accesses to 3'b001 and the Non-secure ones to 3'b011:

Output
135  write 0x004 = 0x5ec00001 strb=1111 prot=001
165  write 0x004 = 0xbad00000 strb=1111 prot=011  PSLVERR
195  read  0x004 = 0x00000000          prot=011  PSLVERR
225  read  0x004 = 0x5ec00001          prot=001

Open the ready-made example in the lab and run the simulation.

Summary

  • PSTRB has one bit per byte lane and selects which bytes of a write the completer updates; it is low for reads.
  • PPROT marks an access as privileged (bit 0), Non-secure (bit 1, high = Non-secure) and instruction (bit 2).
  • A completer refusing an access should return PSLVERR and hide the read data.
  • Blocks with and without the APB4 signals can be connected, but byte writes and protection only work where both sides support them.
  • APB5 adds optional wake-up, user signals, parity check signals and RME.
Did you find what you were looking for?

Quiz

No quiz questions available for this article.