Three abbreviations govern every CSR field in the rest of this volume — they’re also the color legend of every CsrMap diagram on this site.
| Software contract | Hardware contract | |
|---|---|---|
| WPRI — reserved | Ignore reads; preserve on writes (read-modify-write discipline) | If unimplemented: read-only zero |
| WLRL — write/read legal only | Write only legal values; don’t trust reads after an illegal write | MAY trap illegal writes, or store deterministic garbage; reads of supported values return full encodings |
| WARL — write any, read legal | Probe support by write-then-readback | NEVER trap; always read back a legal value, deterministic in the written value + architectural state |
2.4 Field modulation
When a write to one CSR changes the legal set of a field in another, that field immediately takes an UNSPECIFIED value from the new legal set — even if its old value was still legal. Special cases: a field flipping from read-only to writable gets an UNSPECIFIED legal value, unless it’s defined as an alias of another field — then it reflects the alias. Such changes are not writes: no side effects fire. ( Modulation csr field modulation When a write to CSR A changes the legal-value set of a field in CSR B, that field immediately takes an UNSPECIFIED value from the new legal set (even if the old value stayed legal) - unless it aliases another field, in which case it reflects the alias. Not a write: no side effects fire. defined in ch. II·2 — open in glossary is why “I wrote misa.F=0 and my fcsr changed” is conformant behavior.)
2.5–2.6 Implicit reads and width changes
Implicit reads (satp during S-mode fetches, mip during interrupt evaluation…) return exactly what an explicit read from a sufficiently-privileged mode would. When a CSR’s width changes (SXLEN/UXLEN switching): copy old value → zero the read-only bits → truncate or zero-extend to the new width → writable fields take same-position bits. Also not a read or write — no side effects.
2.7 CSRs wider than XLEN
Explicit accesses touch the least-significant XLEN bits only. Always-64- bit CSRs (counters, menvcfg, stimecmp…) get RV32 ‘h’ twins high-half csrs RV32 companions (timeh, mcycleh, menvcfgh...) aliasing bits 63:32 of 64-bit CSRs. Exist only when XLEN=32; their addresses are reserved on RV64 and typically raise illegal-instruction. defined in ch. II·2 — open in glossary aliasing bits 63:32 — and those twin addresses are reserved on RV64 (typically illegal-instruction).
Hardware Designer Notes
Keep a WARL policy table in your design docs: one row per WARL field, stating the legalization function (hold / clamp / zero). It becomes the reference-model configuration for every CSR test, and Vol II is about to add several dozen rows to it — starting with misa and mtvec in the next chapter.
Minimal Linux-boot hart MUST
- Make every WARL legalization DETERMINISTIC — pure function of written value + hart state; DV diffing depends on it
- Read-only-zero all unimplemented WPRI fields
- On RV64, trap the high-half CSR addresses; on RV32, alias them to bits 63:32 (same storage)
- Ensure modulation-driven value changes fire no write side effects
MAY simplify / trap-and-emulate
- Legalize WARL writes by keeping the old value, clamping, or mapping to a default — any deterministic policy
- Trap illegal WLRL writes (stricter is simpler to verify than deterministic garbage)
Check yourself — field behaviors
1.Software writes an unsupported value into a WARL field vs a WLRL field. Contrast the outcomes.
2.A write to CSR A shrinks the legal-value set of a field in CSR B — and B's current value is still legal. What may happen to B?
3.RV64 software reads timeh (0xC81). What happens?
4.Why must an unimplemented WPRI field read as zero rather than garbage?