Part 9 · Register Model (RAL) · Intermediate
Access Policy Catalog: RW/RO/WO/W1C/RC/W1S
Detailed policy behavior matrix for common field access types and how each policy impacts writes, reads, mirror updates, and side effects.
Why policy fidelity matters
A field access policy is not documentation only. It controls how write/read/mirror semantics are interpreted by RAL. If the policy is wrong, checks become meaningless: expected side effects are missed or false errors appear.
The six policies below cover most production use cases in status/control blocks. Teams often model the first three correctly and drift on side-effect policies (W1C/RC/W1S), which is where most debug churn happens.
[RAL] policy behavior matrix (common subset)
Policy Read behavior Write behavior Typical use
────── ───────────────────────────── ───────────────────────────────── ─────────────────────────────
RW returns current value writes value directly control/config bits
RO returns hw-driven value write ignored status sampled from DUT
WO read may return 0/unknown* write accepted command pulse/mailbox
W1C read returns latched status writing 1 clears bit; 0 no-op interrupt/event status
RC read returns value then clears write ignored or restricted read-to-ack status flags
W1S read returns current value writing 1 sets bit; 0 no-op software set latch/event
* behavior depends on design/spec conventions[UVM][RAL] side-effect intuition
W1C: software writes 1 to acknowledge/clear
RC : software read itself performs clear
W1S: software writes 1 to force/set
These are not "normal writes" with different names.
They are semantic operations with side effects.Policy semantics determine legal stimulus and expected mirror evolution.
W1C/RC/W1S are side-effect contracts, not just access permissions.
Always model from specification wording, not from old register templates.
SystemVerilog field definitions by policy
A compact register with six fields, one per policy. This is useful as a reference model snippet during review:
class status_reg extends uvm_reg;
`uvm_object_utils(status_reg)
uvm_reg_field cfg_mode; // RW
uvm_reg_field hw_state; // RO
uvm_reg_field cmd_kick; // WO
uvm_reg_field irq_pending; // W1C
uvm_reg_field rx_overflow; // RC
uvm_reg_field sw_force; // W1S
function new(string name = "status_reg");
super.new(name, 32, UVM_NO_COVERAGE);
endfunction
virtual function void build();
cfg_mode = uvm_reg_field::type_id::create("cfg_mode");
cfg_mode.configure(this, 2, 0, "RW", 0, 2'h0, 1, 1, 0);
hw_state = uvm_reg_field::type_id::create("hw_state");
hw_state.configure(this, 2, 2, "RO", 1, 2'h0, 1, 0, 0);
cmd_kick = uvm_reg_field::type_id::create("cmd_kick");
cmd_kick.configure(this, 1, 4, "WO", 0, 1'b0, 1, 0, 1);
irq_pending = uvm_reg_field::type_id::create("irq_pending");
irq_pending.configure(this, 1, 5, "W1C", 0, 1'b1, 1, 0, 1);
rx_overflow = uvm_reg_field::type_id::create("rx_overflow");
rx_overflow.configure(this, 1, 6, "RC", 1, 1'b0, 1, 0, 1);
sw_force = uvm_reg_field::type_id::create("sw_force");
sw_force.configure(this, 1, 7, "W1S", 0, 1'b0, 1, 0, 1);
endfunction
endclass[REG][FIELD] bit map
[7] sw_force W1S
[6] rx_overflow RC
[5] irq_pending W1C
[4] cmd_kick WO
[3:2] hw_state RO
[1:0] cfg_mode RWKeep each field declaration aligned with spec bit slice and wording.
Volatile RO/RC fields usually represent DUT-updated status.
Set individually_accessible only when spec allows byte-lane partial access.
Policy walk-through with read/write timelines
W1C timeline
[SW] writes status clear register bit with value 1
│
▼
[RAL][FIELD W1C] interpret as CLEAR operation
│
▼
[DUT] bit transitions 1 -> 0
│
▼
[RAL] mirror predicts cleared value (after successful op)Common bug: modeling this as RW, which causes tests to expect 'written 1 stays 1' and creates persistent mirror drift.
RC timeline
[SW] reads status register
│
▼
[DUT] returns latched event state
│ and clear side effect occurs in hardware
▼
[RAL][FIELD RC] expects post-read clear semantics
▼
next read should show cleared value unless event reassertedRC fields are especially sensitive to monitor/predict setup because reads carry both value delivery and state mutation.
W1S timeline
[SW] write 1 to field
│
▼
[RAL][FIELD W1S] interpret as SET operation
│
▼
[DUT] bit transitions 0 -> 1
│
▼
[SW] write 0 later => no changeW1S is often paired with W1C in control/status structures where software can force events and acknowledge them.
Policy-aware checks in sequences
A policy catalog is useful only if tests actively validate policy semantics. Directed checks for side-effect fields should be part of smoke or bring-up sequences.
task check_w1c_behavior(my_reg_block ral, uvm_reg_map map);
uvm_status_e status;
uvm_reg_data_t rd;
// Precondition: irq_pending starts high
ral.status.irq_pending.set(1);
ral.status.update(status, UVM_FRONTDOOR, map, this);
// Clear via W1C write
ral.status.write(status, 32'h0000_0020, UVM_FRONTDOOR, map, this); // bit5 = 1
ral.status.read(status, rd, UVM_FRONTDOOR, map, this);
if (rd[5] !== 1'b0)
`uvm_error("W1C", $sformatf("Expected clear after W1C write, got %0b", rd[5]))
endtask
task check_rc_behavior(my_reg_block ral, uvm_reg_map map);
uvm_status_e status;
uvm_reg_data_t first, second;
ral.status.read(status, first, UVM_FRONTDOOR, map, this);
ral.status.read(status, second, UVM_FRONTDOOR, map, this);
// Example assumes no new event arrives between reads
if ((first[6] == 1'b1) && (second[6] != 1'b0))
`uvm_error("RC", "Read-to-clear behavior not observed")
endtask[TEST][RAL] policy check strategy
1) setup known precondition
2) perform operation tied to policy semantics
3) read back with explicit expectation
4) isolate one policy at a time for debug clarityKey takeaways
Policy table should drive both model code and directed semantic checks.
W1C/RC/W1S need side-effect-focused tests, not only generic read/write.
Modeling policies correctly reduces false mirror mismatches dramatically.
Treat policy verification as first-class bring-up coverage.
Common pitfalls
Using RW as default for status bits with clear-on-read/write semantics.
Assuming WO read behavior without checking project specification convention.
No directed policy tests, relying only on random traffic.
Ignoring event reassertion windows while testing RC behavior.