Skip to content

AMBA APB · Module 1

The Register-Access Mental Model

APB as the canonical register-access protocol — the two-phase setup/access transfer, the CSR mental model, and a minimal subordinate in RTL.

This is the chapter where APB stops being a list of signals and becomes the way engineers actually think about it: APB is register access. Every APB transfer reads or writes exactly one register. A peripheral, to the processor, is a map of memory-mapped registers; configuring it is writing those registers, checking it is reading them, and APB is simply the bus that carries those reads and writes. We build the model, then make it concrete in one timing diagram and minimal SystemVerilog.

1. What problem is being solved?

The problem is how software controls hardware — and the answer, almost universally, is memory-mapped register access, which is precisely what APB carries.

Software does not call a hardware API; it writes values into specific addresses and reads values from specific addresses. To enable a UART, the driver writes a bit in a control register; to wait for a transmission, it polls a flag in a status register; to set the baud rate, it writes a divider. Every one of these is a memory access to a fixed address, and the address selects which register of which peripheral. This memory-mapped register interface is the universal contract between software and hardware, and it is astonishingly stable across decades and architectures.

The register-access model frames APB around this contract with three claims:

  • A peripheral is a register map. It occupies a region of the address space from a base address, with its registers at fixed offsets — a control register, a status register, a divider, data registers.
  • A transfer is a single register access. One APB transfer touches one register: a write (PWRITE high, data on PWDATA) or a read (PWRITE low, data on PRDATA).
  • A CPU load/store is an APB read/write. Because peripherals are memory-mapped, a processor reaches a register with an ordinary memory instruction; a store becomes an APB write, a load an APB read.
A table of UART registers — CTRL, STATUS, BAUD, TXDATA, RXDATA — each with its offset, access type, and contents.
Figure 1 — a peripheral as a register map. A UART exposes registers at fixed offsets from its base address: CTRL (0x00, read-write — enable and mode bits), STATUS (0x04, read-only — busy/ready/error flags), BAUD (0x08, read-write — the clock divider), TXDATA (0x0C, write-only — the byte to transmit), RXDATA (0x10, read-only — the received byte). To the processor the entire peripheral is just this set of memory-mapped locations, and every interaction is reading or writing one of them. Configuring or checking the peripheral is nothing more than load and store to these offsets — which is why APB is fundamentally a register-access protocol.

2. Why existing buses were not the right fit

Register access is a control interface — one small access at a time, occasionally — and APB is shaped exactly like that job, while a fast bus is overkill for it.

APB's two-phase transfer is the minimal mechanism to perform one register read or write: present which register (PADDR) and the direction (PWRITE), perform the access and exchange the data (PWDATA or PRDATA), with a ready handshake (PREADY) in case the register is slow. There is no feature in APB that is not in service of single register access — which is why the register-access model is not just a way to understand APB, it is the way: APB is shaped like the job of reading and writing one register at a time, because that is the only job it has.

A fast bus could carry register access too, but it would bring pipelining, outstanding transactions, and ordering machinery a single register poke cannot use — pure cost on every peripheral (see the low-speed peripheral philosophy). The register interface is sparse and ordered; APB is the bus tailored to it. The model also transfers your understanding in both directions: a device driver is, at bottom, a sequence of register reads and writes, and an APB subordinate is, at bottom, an address decode plus a bank of registers — and APB is the thin contract in the middle.

3. APB mental model

The picture: a peripheral is a wall of labeled mailboxes, and APB is putting a letter in one box or reading the letter in one box.

Each register is a numbered mailbox at a fixed offset. A write transfer is dropping a letter in one box (storing a value); a read transfer is opening one box and reading it (loading a value). You touch exactly one box per visit — no "empty all the boxes at once" (no burst) — and finish with one box before the next (no pipelining). The two-phase rhythm is "find the box (SETUP), then put-in or take-out (ACCESS)."

The model makes the signals obvious. PWRITE is which way the letter goes; PADDR is the box number; PWDATA is the letter you drop in, PRDATA the letter you take out; PSEL is "this wall of boxes, not that one"; PENABLE is "I'm reaching into the box now" (the ACCESS cycle); PREADY is the box saying "done." Two refinements keep it precise:

  • Some boxes are one-way. A read-only register (STATUS) can only be read; a write-only register (a TX data register) can only be written. The register map's access type column says which.
  • Writing a box can have side effects. Dropping a letter into the TX data mailbox does not just store a byte — it causes the UART to transmit it. Registers are not passive memory; the act of accessing the box is how you command the hardware. This is why register access is the control interface.
A left-to-right flow: CPU, interconnect, bridge, peripheral register, with a store becoming an APB write and a load becoming an APB read, and read data returning on the back path.
Figure 2 — a CPU load/store becomes an APB read/write of a register. The CPU executes a memory instruction to a peripheral address: a store writes a register, a load reads one. The interconnect decodes the address and routes peripheral accesses to the bridge. The bridge translates the access into an APB transfer — a store becomes an APB write (PWRITE high, PADDR, PWDATA), a load becomes an APB read (PWRITE low, PADDR, receiving PRDATA). The addressed register is written or read, and read data plus PREADY return through the bridge to the CPU. To software a peripheral is just memory-mapped registers, so configuring hardware is store instructions and checking status is load instructions — and APB is the bus that carries them down to the registers.

4. Real SoC placement & hardware context

In RTL, the register-access model is almost literal: an APB subordinate is an address decode plus a bank of registers plus a read multiplexer. Here is the minimal shape — the canonical "what an APB peripheral really is." First the register map and the subordinate interface; the whole peripheral is defined by its register offsets and the registers behind them:

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
// Minimal APB3 subordinate: a tiny register block, the canonical shape of
// "a peripheral is a register map reached over APB." Every transfer reads or
// writes exactly one register.
module apb_regs #(
  parameter int ADDR_W = 8,
  parameter int DATA_W = 32
)(
  input  logic              pclk,
  input  logic              presetn,    // active-low reset
  // APB subordinate interface
  input  logic              psel,       // this peripheral is selected
  input  logic              penable,    // ACCESS phase strobe (low in SETUP)
  input  logic              pwrite,     // 1 = write, 0 = read
  input  logic [ADDR_W-1:0] paddr,      // which register (byte offset)
  input  logic [DATA_W-1:0] pwdata,     // write data (store)
  output logic [DATA_W-1:0] prdata,     // read data (load)
  output logic              pready      // 1 = transfer complete this cycle
);
  // The peripheral's register map: fixed byte offsets.
  localparam logic [ADDR_W-1:0] CTRL = 8'h00;  // read-write
  localparam logic [ADDR_W-1:0] BAUD = 8'h08;  // read-write
 
  logic [DATA_W-1:0] ctrl_q, baud_q;

The two-phase protocol shows up as when the access is allowed to happen. A write commits only in the ACCESS phase — psel and penable both high — so the subordinate is never asked to capture data in the same cycle it first sees the address:

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
  // A committed APB WRITE happens in the ACCESS phase: selected + enabled +
  // pwrite. Gating on penable is the whole point of the two-phase model — the
  // SETUP cycle (penable low) is decode/prepare; the commit waits for ACCESS.
  wire write_commit = psel & penable & pwrite;
 
  // ---- Write path: store PWDATA into the addressed register ----
  always_ff @(posedge pclk or negedge presetn) begin
    if (!presetn) begin
      ctrl_q <= '0;
      baud_q <= '0;
    end else if (write_commit) begin
      case (paddr)
        CTRL: ctrl_q <= pwdata;
        BAUD: baud_q <= pwdata;
        default: ;  // write to an unmapped offset: ignored
      endcase
    end
  end

The read path is a pure multiplexer from the addressed register onto PRDATA; the manager samples it in the ACCESS cycle when PREADY is high. This peripheral responds in one cycle, so it never inserts a wait state:

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
  // ---- Read path: drive the addressed register onto PRDATA ----
  always_comb begin
    prdata = '0;                       // default / unmapped read returns 0
    case (paddr)
      CTRL: prdata = ctrl_q;
      BAUD: prdata = baud_q;
      default: prdata = '0;
    endcase
  end
 
  // Single-cycle response → never a wait state: PREADY is always high. A SLOW
  // subordinate would instead drive PREADY low during ACCESS and raise it
  // only when its data is ready (the wait state shown in the timing below).
  assign pready = 1'b1;
endmodule

That is a complete, correct minimal APB subordinate, and it is almost entirely a register bank: a decode (case (paddr)), a write enable gated on the ACCESS phase (write_commit), a read mux, and a ready signal. The protocol is a thin shell; the substance is the registers.

Seeing the lifecycle in time makes the RTL concrete. The diagram below shows a register write (no wait states) followed by a register read that the subordinate stretches with one wait state — covering setup, access, completion, and the wait-state extension a slow register uses:

An APB timing diagram across six cycles showing PCLK, PSEL, PENABLE, PWRITE, PADDR, PWDATA, PRDATA, and PREADY for a write transfer and a read transfer, the read with a one-cycle wait state where PREADY is low.
Figure 3 — one APB access lifecycle: a write (no wait) then a read with one wait state, against PCLK. The write: SETUP (PSEL high, PADDR, PWRITE high, PWDATA, PENABLE low), then ACCESS (PENABLE high) where the subordinate captures the data and drives PREADY high, completing in one access cycle. The read: SETUP (PSEL high, PADDR, PWRITE low, PENABLE low), then ACCESS spanning two cycles — in the first the subordinate is not ready so it holds PREADY low (the wait state) while the manager keeps PSEL, PENABLE, and the address stable and waits; in the second it drives the register value onto PRDATA and asserts PREADY, and the manager samples the data. Every access is SETUP then ACCESS; PREADY high marks completion; a slow subordinate stretches the access by holding PREADY low.

Step back to software, and the model unifies the hardware-software boundary: a device driver is a script of register reads and writes, and APB is where that script meets silicon. The driver author and the RTL author describe the same registers from opposite sides — the driver writes them, the RTL implements them — which is why the register map (offsets, access types, bit fields) is a peripheral's central shared artifact, and why most bring-up "bus bugs" are really map-agreement bugs (an APB read returning the wrong value because the driver and RTL disagree about where a field lives).

5. Engineering tradeoffs

The register-access model is itself a set of design choices with clean consequences.

ChoiceUpsideCost / caveat
One register per transferTrivially simple to reason about, in RTL and softwareNo bulk efficiency — move blocks with DMA, not register access
Memory-mappedSoftware reaches hardware with ordinary loads/stores — no special instructionsEach peripheral consumes a slice of the address map an architect must lay out
Side-effecting registersExpressive — a read or write can command the hardwareAccess order and exact count matter; regions must be non-cacheable / non-speculative
Access-type discipline (RO/WO/RW)Encodes safety rules in the mapA write to a read-only register, or read of a write-only one, is a bug class to respect

The throughline: the model makes the common case — configure and observe a peripheral — as simple as load and store, while pushing order- and side-effect-sensitivity into a discipline engineers learn. APB provides the mechanism; the register map provides the contract.

6. Common RTL / architecture mistakes

7. Interview framing

Interviewers love the register-access model because a candidate who has it can fluently connect software, bus, and RTL — and one who lacks it treats APB as disconnected signals.

The strong answer states it crisply: a peripheral is a map of memory-mapped registers; an APB transfer reads or writes exactly one of them; a CPU load/store to a peripheral address becomes an APB read/write of a register through a bridge. Then add the two depth signals: that the write commits in the ACCESS phase (gated on PENABLE) so a simple subordinate is never under same-cycle pressure, and that registers can be side-effecting, so access order and count matter and the regions are non-cacheable. What interviewers are really probing is whether you see the unbroken chain — driver store → CPU access → bridge → APB write → register captured in ACCESS → possible side effect — and know the register map is the shared contract.

8. Q&A

9. Practice

  1. Read the map. Given the Figure 1 UART map, write the sequence of register accesses (read or write, which offset) a driver performs to set the baud rate and transmit one byte.
  2. Trace a store. Describe, phase by phase, the APB write transfer when the CPU stores to the BAUD register at offset 0x08.
  3. Spot the side effect. Identify which registers in the map are side-effecting and state what wrong behavior results from reading or writing one an extra time.
  4. Sketch the RTL. From memory, name the four parts of a minimal APB subordinate and what each does.
  5. Find the bug. A driver reads a status field and always gets zero though the bus signals look correct. Using the model, name the most likely cause and where to look.

10. Key takeaways

  • APB is register access. A peripheral is a map of memory-mapped registers; every APB transfer reads or writes exactly one; the bus exists for nothing else.
  • A CPU load/store is an APB read/write. Memory-mapped registers let software reach hardware with ordinary loads and stores, which a bridge turns into APB transfers.
  • The write commits in the ACCESS phase. Gating the write on PENABLE gives a simple subordinate a stable cycle to decode before it must act.
  • A minimal APB subordinate is a register bank: decode, ACCESS-gated write enable, read mux, PREADY. The protocol is a thin shell.
  • Registers can be side-effecting. The access is the command, so order and exact count matter, and peripheral regions are non-cacheable and non-speculative.
  • The register map is the shared contract. Hardware implements it, software drives it, APB carries accesses to it — and most bring-up 'bus bugs' are really map-agreement bugs.