Module 1111 min

UVM RAL: The Register Layer

Verifying registers by name, with a mirror you can trust

Every modern block has dozens or hundreds of configuration and status registers. Poking them with raw bus transactions and remembering addresses by hand does not scale and does not survive a spec change. The UVM Register Abstraction Layer (RAL) lets you read and write registers by name, while keeping a model of what each register should currently hold. It builds a class model of the map: a uvm_reg per register, grouped into a uvm_reg_block, with a uvm_reg_field per field. For every field it tracks a desired value (what you intend to write, set by set() and flushed by update()) and a mirror value (what RAL believes hardware currently holds).

Front-door vs back-door access

AccessPathCostUse it for
Front doorReal bus cycles via the adapter and sequencerSlow, realisticVerifying the bus access path itself
Back doorDirect hierarchical poke or peek into the RTL registerInstant, zero cyclesFast setup of state and golden checks
systemverilog
// Inside a sequence body(); reg model handle is 'regmodel'
uvm_status_e status;
bit [31:0]   rdata;

regmodel.ctrl.write(status, 32'h0000_0003);     // front-door: drives bus cycles
regmodel.ctrl.read(status, rdata);              // front-door read-back
regmodel.ctrl.read(status, rdata, UVM_BACKDOOR);// back-door: zero sim time

regmodel.ctrl.enable.set(1'b1);  // update only the DESIRED value of a field
regmodel.ctrl.update(status);    // writes to HW only if desired != mirror

Built-in register tests

The biggest payoff is the predefined sequences that exercise the map for you. Point them at the model and they generate and self-check the stimulus, so you do not hand-write hundreds of poke-and-compare lines.

  • uvm_reg_hw_reset_seq - checks every register reads its specified reset value.
  • uvm_reg_bit_bash_seq - writes and reads back each writable bit to find stuck or aliased bits.
  • uvm_reg_access_seq - confirms front-door and back-door agree, catching address-decode bugs.
Pro tip

The mirror is what makes RAL a checker, not just an addressing convenience. After a front-door write, get_mirrored_value() holds the predicted contents, so a later read can be compared automatically. Combine a back-door peek (the truth) with a front-door read (the path under test) and you verify the access path and the storage in one step.

Watch out

If RTL changes a register without RAL knowing - hardware sets a status bit, or a clear-on-read field fires - the mirror goes stale and later checks produce false mismatches. Tell RAL about such behavior: model each field access policy (RO, W1C, RC, and so on) correctly, and use a predictor with explicit prediction driven by the monitor so the mirror stays honest.