A memory consistency model is the ISA’s answer to one question: which values may a load return? RVWMO (RISC-V Weak Memory Ordering) answers it weakly — single-hart code appears in-order to itself, but other harts may observe your memory operations in a different order unless one of a short list of rules says otherwise. This is the contract your load/ store unit, store buffer, and cache hierarchy sign. (Scope note: this chapter formalizes regular main memory only — I/O ordering, instruction fetch, FENCE.I, and page-table walks are defined elsewhere and not yet folded into the formalism.)
18.1.1 The vocabulary
An execution has a global memory order global memory order A total order over the memory operations of ALL harts in one execution. RVWMO legality = there exists a global memory order respecting preserved program order and the load-value/atomicity/progress axioms. defined in ch. I·18 — open in glossary : one total order over every hart’s memory operations. Memory instructions give rise to operations — load, store, or (for AMOs) both at once — and every operation is single-copy atomic single-copy atomic Property of every RVWMO memory operation: it can never be observed partially complete by anyone. defined in ch. I·18 — open in glossary : nobody ever sees half of one.
Bookkeeping rules that matter to hardware:
- An aligned instruction of ≤ XLEN bits → exactly one operation. Exceptions: a failed SC generates none; RV32 FLD/FSD may generate several.
- Misaligned accesses (and >XLEN FP accesses) may decompose into byte-granularity components, unordered among themselves — the license that makes trap-and-emulate byte loops legal. Inside a misaligned atomicity granule (PMA), no decomposition happens.
- LR and SC are paired when no other LR/SC sits between them.
- Operations may carry annotations:
aqon LR/AMO ⇒ acquire-RCsc,rlon SC/AMO ⇒ release-RCsc; RCpc rcpc/rcsc annotation Acquire/release annotation strengths: RCsc (sequentially-consistent sync ops) is what aq/rl on LR/SC/AMO produce; RCpc (processor-consistent) currently arises only from Ztso's implicit annotations. PPO rules 5-7 define their exact force. defined in ch. I·18 — open in glossary annotations currently arise only from Ztso, but the model is forward-compatible with native load-acquire/store-release instructions.
18.1.2 Syntactic dependencies
RVWMO orders through register dataflow — syntactically, not
semantically. j has a
syntactic dependency syntactic dependency j depends on i when a source register of j traces (possibly through carrying instructions) to a destination register of i. Address/data/control flavors order memory ops via PPO 9-11. Loads, JALR, LR/SC/AMOs carry NO src->dst dependency; successful SC's rd IS a destination.
defined in ch. I·18 — open in glossary
on i if a
source register of j traces back through the register graph (via
instructions that “carry” dependencies) to a destination of i. Three
flavors matter: address (feeds an address source register), data
(feeds a store’s data register), control (a branch/indirect jump in
between depends on i). x0 never participates; the per-instruction
fine print (loads/JALR/AMOs carry nothing; a successful SC’s rd is a
destination; CSR instructions mirror Table 7) is cataloged in
§18.3.
18.1.3 Preserved program order — the 13 rules
The global memory order must respect this subset of each hart’s program order (both operations to regular main memory):
| Rule | What it means for your pipeline | |
|---|---|---|
| 1 · Overlap: b is a store, addresses overlap | Same-address write ordering | No store-store reorder to the same bytes |
| 2 · CoRR: both loads of byte x, no store to x between, values from different writes | Same-address read coherence | Two reads of the same location must not go backwards in time |
| 3 · a from AMO/SC, b load returns its value | Atomic write forwarding orders | A load that consumes an AMO/SC result is ordered after it |
| 4 · A FENCE orders a before b | Explicit fence | Your fence implementation defines the pred/succ drain points |
| 5 · a has an acquire annotation | Acquire keeps everything after it | aq = no later op observed first |
| 6 · b has a release annotation | Release keeps everything before it | SC.rl / AMO.rl: drain prior accesses before it performs |
| 7 · a and b both RCsc | Sync ops totally ordered | All aq/rl-marked ops order among themselves |
| 8 · a paired with b | LR before its SC | Trivially true in any sane LSU |
| 9 · address dependency | b’s address comes from a | No value speculation through addresses |
| 10 · data dependency | b’s store data comes from a | Store data must actually be computed before the store performs globally |
| 11 · control dependency, b is a STORE | No speculative stores | Loads may hoist past branches; stores never |
| 12 · b load returns value of an intervening store m that addr/data-depends on a | Forwarding cannot launder ordering | Store-buffer forwarding keeps the forwarded store’s dependencies |
| 13 · intervening m has an address dependency on a, b is a store | Unresolved addresses block later stores | A store cannot become visible while an older access’s address is unknown |
18.1.4 The three axioms
An execution is legal iff a global memory order exists that respects PPO and satisfies:
- Load Value load value axiom Each byte of a load returns the store latest in {stores earlier in global memory order, stores earlier in PROGRAM order} - the second clause architecturally legalizes store-buffer forwarding of the hart's own not-yet-global stores. defined in ch. I·18 — open in glossary : each byte of a load returns the latest store to that byte among (1) stores earlier in the global memory order and (2) stores earlier in program order. Clause (2) is store-to-load forwarding, architecturally blessed: your store buffer may serve a younger load before the store is globally visible.
- Atomicity atomicity axiom For aligned paired LR/SC: if the LR read byte x from store s, no OTHER hart's store to x may sit between s and the SC's write in the global memory order. defined in ch. I·18 — open in glossary : for an aligned paired LR/SC, no other hart’s store to a read byte may intrude between the store the LR read from and the SC’s own store, in the global order.
- Progress progress axiom No memory operation may be preceded by an infinite sequence of operations in the global memory order - stores eventually become visible; spinloops eventually see updates. defined in ch. I·18 — open in glossary : no operation is preceded by an infinite sequence — stores eventually become visible; spin loops eventually observe updates.
Seeing it: message passing
The canonical two-hart test, in both verdicts — step through the executions:
Hart 0
- li t0, 42
- sw t0, (data)
- li t1, 1
- sw t1, (flag)
Hart 1
- lw a0, (flag)
- lw a1, (data)
Step through one execution that shows how the verdict comes about.
Hart 0
- li t0, 42
- sw t0, (data)
- fence w, w
- li t1, 1
- sw t1, (flag)
Hart 1
- lw a0, (flag)
- fence r, r
- lw a1, (data)
18.2 Dependency granularity through CSRs
Syntactic dependencies thread through CSRs at defined granularities
(Table 12): fflags per-bit (bits 4..0 independent), frm whole,
fcsr per-field — with the aliasing between them tracked. Read-only CSRs
don’t participate. The FP flags are
accumulating CSRs accumulating csr A CSR that is both source and destination of an instruction but carries a dependency only from itself to itself - the FP exception flag bits (NV/DZ/OF/UF/NX), so FP ops never serialize on fflags.
defined in ch. I·18 — open in glossary
: they carry a
dependency only from themselves to themselves, so a chain of FP ops does
not serialize on the flags register.
Hardware Designer Notes
The comforting theorem for a first core: an in-order, single-issue pipeline with a FIFO store buffer that forwards to same-address younger loads and drains on FENCE/aq/rl satisfies RVWMO by construction — every PPO rule falls out of in-order issue. The rules earn their keep the day you add out-of-order load issue, non-FIFO coalescing, or value prediction: then rules 2, 9-13 become real RTL assertions. Write them into your verification plan as litmus tests (the herd/litmus suites for RVWMO exist — run them against your core; the formal machinery lives in the appendices uA/uB).
Minimal Linux-boot hart MUST
- Honor all 13 PPO rules in the LSU: no same-address store reorder, CoRR for loads, dependency-ordered issue (rules 9-13) — syntactic deps included, xor-zero idioms and all
- Never let a control-dependent store drain before its branch resolves
- Keep aq/rl semantics: acquire holds later accesses, release drains earlier ones (scoped per rule 7 for RCsc pairs)
- Deliver the progress axiom: store buffers must drain; snoops must eventually invalidate spinning readers
MAY simplify / trap-and-emulate
- Forward store-buffer data to younger same-address loads (Load Value clause 2)
- Hoist control-dependent LOADS speculatively past branches — rule 11 deliberately omits them
- Reorder independent loads/stores to different addresses arbitrarily — that is the “W” in RVWMO
- Implement fences/aq/rl conservatively as full drains at first — correct, just slower
Check yourself — RVWMO
1.Hart 0: sw data; sw flag. Hart 1: lw flag (sees 1); lw data. No fences, no dependencies. May hart 1 read stale data?
2.Your store buffer forwards a not-yet-visible store to a younger load of the same address. Legal under RVWMO?
3.PPO rule 11 orders a→b when b is a STORE with a control dependency on a. Why doesn't the rule cover control-dependent LOADS?
4.lw a0,(t0); xor t1,a0,a0; add t2,t3,t1; lw a1,(t2). Is the second load ordered after the first?
5.Which annotation set makes an LR/SC pair sequentially consistent in the C++ seq_cst sense?