Skip to content

AMBA APB · Module 12

Reserved Fields

Reserved bits as a register map's forward-compatibility mechanism — RAZ/WI (read-as-zero / write-ignore) and RES0/RES1 conventions, the software preserve-on-write discipline, and why a driver that writes zero to reserved bits breaks on a newer chip that defines them.

Reserved fields are not empty space — they are a contract. A register map reserves bits on purpose: to leave room for a future silicon revision to add functionality without moving the fields software already depends on. But that only works if the reserved semantics are defined — what the bits read as, what writes to them do — and if software follows one discipline: preserve reserved bits on every write. Get the semantics and the discipline right and the map evolves for years without breaking a single shipped driver. Get them wrong — write 0 to a reserved bit, or assert it reads 0 — and the driver works perfectly until the chip that defines that bit, then breaks silently or faults. This chapter is the reserved-field (bits within a register) story; 12.2 covered the reserved-address analogue.

1. Problem statement

The problem is how a register map leaves room to grow. A 32-bit register rarely uses all 32 bits on day one — an enable, a 3-bit mode, and a 16-bit threshold leave bits unaccounted for. Those unused bits are not free to ignore: they are the only place a future revision can add a feature without moving an existing field, and moving a field is a breaking change to every driver bound to that layout.

So the unused bits must be specified as reserved, with three things nailed down:

  • What they read as. A reserved bit must return a defined, constant value — typically 0 (read-as-zero). "Undefined" is not a specification; it makes firmware branch on garbage and differ between sim, silicon, and revisions.
  • What writes to them do. Writes to a reserved bit are ignored (write-ignore) — the bit does not store, has no side effect, and reading it back still returns the defined constant. This is what lets the bit later become functional without an old write having quietly armed something.
  • What software is contractually required to do with them. Software must not assume reserved bits are zero forever and must preserve them on read-modify-write — write back what it read — so that when a later revision gives the bit meaning, an old driver does not stamp a wrong value over the new default.

That third point is the crux. Reserved fields are a two-sided contract: hardware promises a defined read value and dropped writes today; software promises not to depend on that staying true tomorrow. The job is to specify both sides so the map is extensible — able to add features in reserved space across silicon revisions without breaking shipped software.

2. Why previous knowledge is insufficient

Chapter 12.1 established the map as a designed hardware/software contract — addressing, field packing, and per-field access types. Chapter 12.2 covered reserved address space: whole offsets left unallocated so a future register can appear without disturbing the existing map. Both are necessary, neither is sufficient here, because reserved fields are a finer-grained and subtler mechanism:

  • 12.1 typed the fields that exist; this chapter governs the bits that don't yet. The access types in 12.1 (RW/RO/W1C/RC/WO) describe defined fields. A reserved bit is not yet a field — it is a placeholder with its own special semantics (RAZ/WI, or RES0/RES1) that exist precisely so it can become a field later. The contract for a not-yet-defined bit is different from the contract for a defined one.
  • 12.2 reserved whole addresses; this is reservation inside a register word. Reserved address space lets a future register appear. Reserved fields let a future bit appear inside an existing register — which is harder, because old software already reads and writes that register, and an old write touches the new bit whether software meant to or not. The address analogue has no equivalent of "an old access accidentally writes the new feature."
  • Neither prior chapter covered the temporal, cross-revision contract. 12.1 and 12.2 are about a single map. Reserved fields are fundamentally about map evolution over time — the forward/backward-compatibility rules that let revision B add a bit revision A's driver keeps working through. That is new: the discipline (preserve-on-write), the reset-value rule (the new bit's default must reproduce the old behaviour), and the failure modes when software violates them.

So the model to add is the forward-compatibility view: reserved fields as the deliberate, defined, disciplined mechanism by which a register map grows across silicon revisions. The best-practices chapter, 12.8, folds this into the broader rules for shippable maps.

3. Mental model

The model: a reserved field is a // TODO left in a published API — with the rule that callers must pass it through untouched. When you publish a struct in a stable library, you leave padding bytes "reserved for future use" and you document one rule for callers: zero them on creation, but if you copy a struct you didn't fully author, preserve the bytes you don't understand. That is exactly the reserved-field contract. The padding exists so you can add a field later without changing the struct's offsets; the preserve rule is what keeps an old caller from clobbering the new field once it has meaning.

Three refinements make it precise:

  • Reserved bits have defined placeholder semantics, not "no semantics." The standard default is RAZ/WI — Read-As-Zero, Write-Ignore: hardware returns a constant 0 and silently drops writes. ARM's convention names two flavours: RES0 (reserved, should-be-zero — read 0, and software should write 0 or what it read) and RES1 (reserved, should-be-one — read 1, software should write 1). The point is the read value is a known constant and writes have no effect today, so the bit is inert but predictable.
  • The reset value of a newly-defined bit must reproduce the old behaviour. When revision B turns a RES0 bit into a real field, its reset value must be chosen so a driver that never writes it gets the legacy function unchanged — the "new feature defaults to the old behaviour" rule. If the old default was "feature absent," the new bit resets to whatever value means "feature absent / behaves like before."
  • The software discipline is preserve-on-write, not write-zero. A robust driver updates a register by read-modify-write: read the word, change only the bits it owns, write back the rest unchanged. It never forces a value onto a bit it does not understand, and it never asserts a reserved bit reads a particular value. That single discipline is what makes the bit safe to define later.
A CTRL register drawn twice: revision A with EN[0] and MODE[3:1] defined and bits [31:4] reserved RAZ/WI; an arrow down to revision B where bit 4 has become a functional TURBO field with a legacy-preserving reset value while EN and MODE stay in place and [31:5] remain reserved, illustrating forward-compatible map evolution.
Figure 1 — reserved fields as the forward-compatibility mechanism, shown by a CTRL register evolving from revision A to revision B. In revision A, EN[0] and MODE[3:1] are defined RW (blue) and bits [31:4] are reserved (amber) with RAZ/WI semantics: they read as zero and ignore writes, and a revision-A driver preserves them on every read-modify-write. In revision B the same register keeps EN and MODE at their exact positions — nothing moves — and a previously-reserved bit, bit 4, becomes a functional RW field TURBO (green) whose reset value is chosen so the legacy behaviour is preserved when an old driver never touches it; bits [31:5] remain reserved for the next revision. The figure teaches that reserved space plus two rules — a backward-compatible reset value and a software preserve-on-write discipline — is what lets the map add functionality across silicon revisions without moving existing fields or breaking shipped drivers.

4. Real SoC implementation

In real RTL, reserved bits are implemented as a defined constant on read and as dropped bits on write. The map specifies which bits of a register are defined and which are reserved; the read path returns 0 for reserved positions and the write path simply has no storage for them, so writes there are inherently ignored. Crucially, the software side of the contract — read-modify-write preserving reserved bits — is a discipline the driver author must follow; the hardware cannot enforce it, which is exactly why it must be documented in the map.

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
// CTRL @ 0x00 — revision A layout. Defined bits are RW; everything else is RESERVED (RAZ/WI).
//
//  Field      Bits      Reset   Access   Notes
//  EN         [0]       1'b0    RW       enable
//  MODE       [3:1]     3'b0    RW       mode select
//  RESERVED   [31:4]    -       RAZ/WI   read 0, writes dropped; software MUST preserve on RMW
 
localparam DEFINED_MASK = 32'h0000_000F; // bits [3:0] are real; [31:4] reserved
 
logic [31:0] ctrl_q; // storage ONLY for defined bits; reserved bits have no flop
 
always_ff @(posedge pclk or negedge presetn)
  if (!presetn)
    ctrl_q <= 32'h0000_0000;                       // reset values ARE part of the map
  else if (wr_en_ctrl)
    // WI for reserved: mask the incoming write so only defined bits can change.
    // Reserved bit positions are never stored, so any write to them is silently dropped.
    ctrl_q <= (ctrl_q & ~DEFINED_MASK) | (pwdata & DEFINED_MASK);
 
// RAZ for reserved: the read path forces reserved positions to 0, regardless of any
// prior write. Software always sees a defined constant in reserved bits.
assign ctrl_rdata = ctrl_q & DEFINED_MASK;          // [31:4] read back as 0
 
// ---------------------------------------------------------------------------
// SOFTWARE DISCIPLINE (driver side — hardware cannot enforce this):
//   uint32_t t = read(CTRL);          // read whole word
//   t = (t & ~MODE_MASK) | new_mode;  // change ONLY the bits we own
//   write(CTRL, t);                   // write back -> reserved bits preserved, never forced to 0
// Never `write(CTRL, new_mode)` (forces reserved bits to 0) and never assert (t & RSVD)==0.

Two facts make this a reserved-field implementation and not just "some unused bits." First, the read path returns a defined constant for reserved positions and the write path has no storage for them — that is RAZ/WI realised in hardware, and it is a map decision (which bits are reserved, what they read as) that the RTL faithfully implements. Second, the forward-compatibility guarantee lives half in hardware and half in software: the hardware makes reserved bits inert and predictable today, but it is the driver's preserve-on-write discipline that keeps an old binary from clobbering a bit that becomes functional tomorrow. The map must document the software rule, because RTL cannot enforce what a driver does with the value it reads.

5. Engineering tradeoffs

Choosing the reserved-field convention is a contract decision: each option fixes what the bit reads as, what writes do, and what software is required to do — with consequences for how safely the map can later define the bit.

ConventionRead behaviourWrite behaviourSoftware ruleWhen used
RAZ/WI (read-as-zero, write-ignore)Returns constant 0Writes dropped (no store, no effect)Preserve on RMW; treat as 0 but don't depend on it staying 0The common default — most bus/peripheral reserved bits
RES0 (ARM reserved-should-be-zero)Returns 0 currentlyWrites have no effect currentlyWrite 0 (or write-back-read); a later revision may define it as a feature that is "off" when 0ARM architectural registers where the bit will likely default to the zero/legacy behaviour
RES1 (ARM reserved-should-be-one)Returns 1 currentlyWrites have no effect currentlyWrite 1 (or write-back-read); preserves "legacy behaviour" semantics that map to a oneARM registers where the legacy/safe behaviour corresponds to a 1, not a 0
Read-undefined (avoid)No guaranteed valueOften unspecifiedMust mask out on read; cannot RMW safelyLegacy/poorly-specified maps — a defect, not a design; forces brittle masking and breaks portability

The throughline: the first three are defined contracts — a known read value, no write effect today, and an explicit software rule — and any of them makes the bit safely definable later, with RES0/RES1 differing only in which constant represents "legacy behaviour." Read-undefined is the anti-pattern: with no guaranteed read value, software cannot reliably preserve the bit on RMW, so the map cannot evolve in that space without risk. Prefer RAZ/WI as the default; choose RES0/RES1 when the architecture's legacy behaviour maps cleanly to a fixed constant; never ship read-undefined.

6. Common RTL mistakes

7. Debugging scenario

The signature reserved-field bug is a forward-compatibility break: a driver that worked on every shipped chip stops working on a newer revision that defined a previously-reserved bit — because the old driver wrote 0 to it (or asserted it read 0).

  • Observed symptom: a peripheral driver that has shipped and worked for two years suddenly misbehaves on a new chip revision — a performance feature is mysteriously disabled, or the driver hard-faults during init. Nothing in the driver changed; only the silicon did. The same binary works on the old part and fails on the new one.

  • Waveform clue: on the APB bus, the driver's CTRL update is a full-word write — PWDATA = (MODE << 1) | EN, with bit 4 = 0 — not a read-modify-write. On the old chip, reading CTRL back shows bit 4 = 0 (it was RAZ/WI). On the new chip, CTRL's reset value has bit 4 = 1 (the new TURBO enable, default-on for legacy compatibility), but immediately after the driver's full-word write, bit 4 reads back 0 — the driver's forced zero cleared a feature it never knew existed. (In the assert-variant, the trace shows the driver reading CTRL, seeing bit 4 = 1, and faulting because it asserted reserved == 0.)

  • Root cause: the driver treated a reserved bit as "always 0, always safe to write 0." It used a full-word write that hardwired bit 4 to 0 instead of a read-modify-write that preserves bits it does not own. When the newer revision defined bit 4 as TURBO with a default-on reset, the old driver's forced 0 silently disabled it. The defect is a violation of the software side of the reserved-field contract — preserve, don't force — exposed by a perfectly legal map evolution.

  • Correct RTL: the hardware here is correct — the new chip rightly implemented TURBO with a legacy-preserving reset and the old chip rightly had bit 4 as RAZ/WI. The fix is in the software contract and the driver: drivers must read-modify-write, preserving reserved bits, and must never assert a reserved bit's value. On the hardware side, the discipline the map must guarantee is that reserved bits read as their defined constant and writes to them are dropped — so verify that invariant in RTL so a reserved bit never silently stores a written value before it is defined.

  • Verification assertion: prove the RAZ/WI invariant on the bits that are reserved in this revision — they read as the defined constant and a write to them never changes the stored, read-back value:

    Azvya Education Pvt. Ltd.VLSI Mentor
    Snippet
    // RAZ: reserved bits [31:4] always read back as 0, regardless of any prior write.
    assert property (@(posedge pclk) disable iff (!presetn)
      (ctrl_rdata[31:4] == '0));
     
    // WI: a write to the register never changes what the reserved bits read back.
    assert property (@(posedge pclk) disable iff (!presetn)
      (wr_en_ctrl) |=> $stable(ctrl_rdata[31:4]));
  • Debug habit: when a driver "works on the old chip, breaks on the new one" with no driver change, suspect a reserved-field forward-compatibility break before anything else. Diff the two revisions' register maps for a previously-reserved bit that became defined, then check the driver's write to that register: is it a full-word write (forces reserved bits) or a read-modify-write (preserves them)? The fix is almost always "preserve reserved bits on write, never assert their value" — a software-discipline bug exposed by a legal hardware evolution.

Two cases: top in red shows an old driver's full-word write forcing reserved bit 4 to 0 and silently clearing the newer chip's TURBO feature; bottom in green shows a read-modify-write preserving bit 4 so TURBO keeps its reset value of 1 and the driver works on both revisions.
Figure 2 — writing 0 to a reserved bit breaks on a newer chip, while read-modify-write preserve survives. Top (bug, red): an old driver issues a full-word write that forces reserved bit 4 to 0. On revision A this was harmless (bit 4 was RAZ/WI), but revision B defined bit 4 as TURBO with a default-on reset, so the forced 0 silently clears the new feature — no bus error, no fault, just lost function; a variant that asserts reserved == 0 instead hard-faults when the bit reads back 1. Bottom (correct, green): the driver performs a read-modify-write — reads the whole word, changes only the bits it owns, and writes back the rest unchanged — so TURBO keeps its revision-B reset value and the same binary works on both chips. The figure teaches the failure mode of treating reserved bits as always-zero or always-writable-zero, and the preserve-on-write discipline that lets reserved space become functional safely.

8. Verification perspective

Reserved fields are verified as a forward-compatibility contract: the per-revision RAZ/WI (or RES0/RES1) invariant, the reset value of any newly-defined bit, the software RMW-preserve behaviour, and explicit cross-revision compatibility checks.

  • Assert the RAZ/WI (or RES0/RES1) invariant per revision. For every bit reserved in the current revision, assert it reads as its defined constant (0 for RAZ/RES0, 1 for RES1) regardless of any write, and that writes to it never change the read-back value (write-ignore). A register-abstraction layer (UVM RAL) built from the IP-XACT/SystemRDL source can model reserved fields explicitly and generate these checks, so the reserved semantics are proven from the same source the RTL was generated from. A naive per-register read/write test does not cover this — it must specifically target the reserved bit positions.
  • Check the reset value of every newly-defined bit for backward compatibility. When a revision turns a reserved bit into a real field, the highest-value check is that its reset value reproduces the previous revision's behaviour — the "new feature defaults to legacy" rule. Verify out of PRESETn that the formerly-reserved bit comes up at the value that means "behaves like the old chip," so a driver that never writes it is unaffected.
  • Cover the software RMW-preserve discipline at the system/UVM level. Beyond RTL invariants, exercise the driver behaviour the contract requires: a sequence that performs read-modify-write and confirms reserved bits survive untouched, and (as a negative test) a full-word write that would clobber a reserved bit, to demonstrate the failure mode and guard against it. Coverage should include "a reserved bit was written non-zero and the RAZ invariant still held" and "a reserved bit was preserved across an RMW update."
  • Run cross-revision compatibility checks. Where multiple revisions of an IP exist, diff their register maps and assert that no defined field moved, that previously-reserved bits only ever gained definition (never had their reserved semantics changed under an old driver), and that any newly-defined bit's reset value is legacy-compatible. This is the structural check that catches a map evolution that would break shipped software before silicon, not after.

The point: verify reserved fields as the evolution contract they are — RAZ/WI per revision, legacy-compatible reset on any newly-defined bit, RMW-preserve at the software level, and a cross-revision diff that proves the map only ever grew additively in reserved space.

9. Interview discussion

"What are reserved fields, and why do they matter?" separates engineers who recite "unused bits" from those who understand map evolution under backward-compatibility rules.

Lead with the framing: reserved fields are the forward-compatibility mechanism of a register map — bits deliberately left unused so a later silicon revision can add functionality without moving existing fields or breaking shipped drivers. Then give the two-sided contract: hardware promises a defined read value and dropped writes today — name RAZ/WI (read-as-zero, write-ignore) as the common default, and the ARM RES0 / RES1 conventions (reserved-should-be-zero / -one) as the architectural flavours; software promises not to depend on those bits staying constant — the preserve-on-write (read-modify-write) discipline, "write back what you read for bits you don't own, never assert a reserved bit's value." Then deliver the depth that signals real experience: the reset value of a newly-defined bit must reproduce the old behaviour (new feature defaults to legacy), so a driver that never writes it is unaffected; and the classic failure mode — a driver that wrote 0 to a reserved bit (or asserted it read 0) works on every shipped chip and then breaks on the revision that defines that bit, silently disabling a default-on feature or hard-faulting. Closing with "reserved bits are the field-level analogue of reserved address space (12.2) — both let the map grow additively without breaking what shipped" shows you see the whole evolution story, not just one register.

10. Practice

  1. Specify a reserved field. Given a CTRL register using bits [3:0], specify bits [31:4] as reserved: state the read value, the write behaviour, and the software rule, choosing RAZ/WI versus RES0/RES1 and justifying the choice.
  2. Evolve the map. Define bit 4 as a new TURBO enable in revision B. Choose its reset value so a revision-A driver that never touches it gets the legacy behaviour, and explain why.
  3. Spot the failure. Given a driver that does write(CTRL, (mode << 1) | en), explain exactly what breaks when a newer chip defines bit 4 as a default-on feature, and rewrite the access to be forward-compatible.
  4. Write the assertions. Write SystemVerilog assertions for the revision-A map proving its reserved bits are RAZ (read 0) and WI (a write never changes their read-back value).
  5. Compare conventions. For RAZ/WI, RES0, and RES1, state the read value, the write rule, and one architecture/situation where each is the right choice — and explain why "read-undefined" cannot be made forward-compatible.

11. Q&A

12. Key takeaways

  • Reserved fields are the forward-compatibility mechanism of a register map — bits deliberately left unused so a later silicon revision can add functionality without moving existing fields or breaking shipped drivers.
  • Reserved bits have defined placeholder semantics, not "no semantics." The common default is RAZ/WI (read-as-zero, write-ignore); ARM's RES0 / RES1 are the architectural flavours. The read value is always a known constant and writes have no effect today.
  • The contract is two-sided: hardware promises a defined read value and dropped writes today; software promises not to depend on that staying true — the preserve-on-write (read-modify-write) discipline, write back what you read, never assert a reserved bit's value.
  • A newly-defined bit's reset value must reproduce the old behaviour — new feature defaults to legacy — so a driver that never writes it is unaffected on the chip that defines it.
  • The classic failure mode is a driver that writes 0 to (or asserts 0 on) a reserved bit: it works on every shipped chip, then silently disables a default-on feature or hard-faults on the revision that defines that bit.
  • Verify reserved fields as an evolution contract — RAZ/WI per revision, legacy-compatible reset on any newly-defined bit, RMW-preserve at the software level, and a cross-revision diff proving the map only grew additively in reserved space. This is the field-level analogue of reserved address space (12.2).