task body();
uvm_status_e status;
uvm_reg_data_t data;
// 1. Frontdoor Write (Uses Bus)
reg_model.ctl_reg.write(status, 32'hDEAD_BEEF);
// 2. Frontdoor Read
reg_model.ctl_reg.read(status, data);
// 3. Backdoor Write (Zero time, bypasses bus)
reg_model.ctl_reg.poke(status, 32'h1234_5678);
// 4. Backdoor Read
reg_model.ctl_reg.peek(status, data);
// 5. Update: Writes only if mirrored value != desired value
reg_model.ctl_reg.set(32'hF00D); // Set desired
reg_model.ctl_reg.update(status); // Write if changed
endtask
RAL Sequences & Access Methods
How to read/write registers using Frontdoor (Physical) and Backdoor (Simulation path) access, plus built-in UVM register tests.
Write & Read Methods
Access Methods Comparison (Interview Essential)
Frequently Asked: "What's the difference between write, poke, set, and update in RAL?"
| Method | Uses Bus | Time | Updates Mirror | Use Case |
|---|---|---|---|---|
write() |
Yes | Sim time | Yes | Normal register access |
read() |
Yes | Sim time | Yes | Normal register read |
poke() |
❌ No (backdoor) | Zero | ❌ No | Fast initialization |
peek() |
❌ No (backdoor) | Zero | ❌ No | Debug/checking |
set() |
❌ No | Zero | Desired only | Prepare for update |
update() |
Yes (conditional) | Sim time | Yes | Efficient bulk writes |
mirror() |
Yes | Sim time | Yes | Read and check against expected |
Built-in Sequences
UVM provides pre-verified sequences to check your register implementation automatically.
| Sequence | Functionality |
|---|---|
uvm_reg_hw_reset_seq
|
Reads all registers and checks against reset value. |
uvm_reg_bit_bash_seq
|
Writes 0/1 to every bit to check accessibility (RW/RO). |
uvm_reg_access_seq
|
Checks Frontdoor vs Backdoor consistency. |
Running Built-in Sequences
class reg_test extends uvm_test;
my_reg_block reg_model;
task run_phase(uvm_phase phase);
uvm_reg_hw_reset_seq reset_seq;
uvm_reg_bit_bash_seq bit_bash;
phase.raise_objection(this);
// 1. Reset Value Check
reset_seq = uvm_reg_hw_reset_seq::type_id::create("reset_seq");
reset_seq.model = reg_model;
reset_seq.start(null);
// 2. Bit Accessibility Check
bit_bash = uvm_reg_bit_bash_seq::type_id::create("bit_bash");
bit_bash.model = reg_model;
bit_bash.start(null);
phase.drop_objection(this);
endtask
endclass
Common Pitfall
Built-in sequences require model to be set before
start(). They also need the adapter connected properly, or they will hang
waiting for bus transactions.