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


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
                            

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.