Skip to content

UVM RAL · Chapter 1 · Register Specification & CSR Thinking

Reset Values

The reset value is the first thing anyone can check about a register, before any configuration or the first functional transaction. It matters for two reasons. It is where RAL's mirror begins, since resetting the model sets every field's mirrored value to its spec reset, which is the reference the first read is checked against. It is also directly verifiable, because a reset test reads every register straight out of reset and compares it field by field against the model, catching tie-off errors, wrong power-on defaults, and mis-transcribed resets in a single sweep. This page follows the reset value from the spec, into the model, into the mirror, and out to the built-in hardware-reset check, covers multiple reset domains, and breaks a register whose modelled reset disagrees with the RTL and puts every later test on the wrong starting line.

Foundation11 min readUVM RALResetMirrorhw_resetReset Domainsuvm_reg_field

Chapter 1 · Section 1.3 · Register Specification & CSR Thinking

1. Why Should I Learn This?

The reset value is the starting line for every test you will ever run against a register. RAL primes the mirror to the spec reset the instant the model resets, so the first read on any register is silently checked against that value — which means if the modelled reset is wrong, your very first check is wrong, and the error propagates into everything that reads the register afterward. Worse, a reset test is often the first thing that runs, so a wrong reset in the model can turn a real DUT tie-off bug into a passing test, or a correct DUT into a failing one, before functional verification even begins.

Learning where the reset value lives and how RAL uses it lets you write the reset test that catches an entire family of power-on bugs cheaply, and keeps you from the frustrating class of failures where 'the register is wrong out of reset' turns out to be the model being wrong, not the silicon. It is a small fact with outsized leverage.

2. Industry Story — the default nobody powered up correctly

A block has a CFG register whose clk_div field, per the spec, must reset to 0x1 — a divide-by-two default so the block runs at a safe clock out of reset. The RTL designer, building the flop, defaults it to 0 (divide-by-one) by habit, because most fields reset to zero. The verification engineer, transcribing the model, reads the spec correctly and configures the reset as 0x1.

The reset test runs first and fails immediately: the model expects clk_div = 1, the DUT powers up with 0. This is the system working exactly as intended — the earliest, cheapest test caught a real power-on bug before a single functional test ran, and it caught it precisely because the model's reset value was transcribed from the spec, not from the RTL. Contrast the counterfactual: had the verification engineer 'helpfully' matched the model's reset to whatever the RTL did (0), the reset test would have passed, the divide-by-one default would have shipped, and the block would have run at twice its safe clock in the field. The lesson the team internalizes: the model's reset value must come from the spec, never from the RTL, because the whole job of the reset test is to check the RTL against the spec — and a check cannot find a disagreement it was built to agree with.

3. Concept — the reset value's path, spec to check

The reset value travels a short, well-defined path, and every stop matters:

  • Spec — the programmer's guide gives each field a reset (power-on) value. This is the authority; the model copies it, the RTL is checked against it.
  • Model — the reset enters the field as the reset argument of configure(). This is the value the field 'knows' it should hold at reset.
  • Mirror — calling reset() on the block (or register) sets every field's mirrored value to its configured reset. This primes the reference before any access, so the first read has something correct to check against.
  • Check — RAL's built-in hardware-reset sequence (uvm_reg_hw_reset_seq) resets the DUT, then reads every register and compares it against the model's reset — a one-pass sweep that catches wrong power-on defaults, bad tie-offs, and mis-transcribed resets.

Two wrinkles the spec assumes you handle. Non-zero resets are common and are exactly where the value is — an ID register resets to a device code, a clk_div to a safe default; do not assume zero. And multiple reset domains exist: a field may respond to a hard/power-on reset, a soft reset, or both, sometimes with different values, and RAL lets you name resets so reset("SOFT") primes the mirror to the soft-reset value while reset("HARD") uses the power-on value. Here is the path as a flow:

Reset value flow: spec to configure() reset argument to the primed mirror to the built-in hardware-reset checkSpec — the authorityeach field's power-on (and soft-reset) value; the model copies it, the RTL is checked against iteach field's power-on (and soft-reset) value; the model copies it, the RTL is checked against itModel — configure() reset argumentthe reset enters the field as the 'reset' arg; the field now knows what it should hold at resetthe reset enters the field as the 'reset' arg; the field now knows what it should hold at resetMirror — primed by reset()reset() sets every field's mirrored value to its configured reset, so the first read has a correct referencereset() sets every field's mirrored value to its configured reset, so the first read has a correct referenceCheck — uvm_reg_hw_reset_seqresets the DUT, reads every register, compares actual vs the modelled reset — a one-pass power-on sweepresets the DUT, reads every register, compares actual vs the modelled reset — a one-pass power-on sweep
Figure 1 — the reset value's path from spec to check. The spec is the authority (top). The model copies the reset into the configure() reset argument. reset() primes the mirror to that value, so the first read has a correct reference. The built-in hw_reset sequence resets the DUT and reads every register, comparing actual against the modelled reset. Crucially, the model's reset comes from the SPEC, not the RTL — otherwise the check compares the RTL against itself and can never find a power-on bug.

4. Mental Model — the reset value is the reference's origin

5. Working Example — resets in the model, and the reset test

Resets enter the model as the fifth configure() argument, copied straight from the spec — including the non-zero ones:

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
class cfg_reg extends uvm_reg;
  `uvm_object_utils(cfg_reg)
  rand uvm_reg_field enable;    // [0]     RW, reset 0
  rand uvm_reg_field clk_div;   // [3:1]   RW, reset 1  (divide-by-two default)
  rand uvm_reg_field mode;      // [5:4]   RW, reset 0
 
  function new(string name = "cfg_reg");
    super.new(name, .n_bits(32), .has_coverage(UVM_NO_COVERAGE));
  endfunction
 
  virtual function void build();
    enable  = uvm_reg_field::type_id::create("enable");
    clk_div = uvm_reg_field::type_id::create("clk_div");
    mode    = uvm_reg_field::type_id::create("mode");
    //             parent size lsb access reset volatile rand indiv
    enable.configure (this, 1, 0, "RW", 0, 0, 1, 0);   // reset 0
    clk_div.configure(this, 3, 1, "RW", 1, 0, 1, 0);   // reset 1 — NOT zero
    mode.configure   (this, 2, 4, "RW", 0, 0, 1, 0);   // reset 0
  endfunction
endclass

Priming the mirror and running the built-in reset check is a few lines — and it is often the first test in the suite:

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
// Prime the model's mirror to the configured reset values (hard reset).
reg_model.reset();                 // every field's mirrored value = its configured reset
if (reg_model.cfg.clk_div.get() != 1)
  `uvm_error("RST", "model reset for clk_div is not the spec default")
 
// The built-in sweep: reset the DUT, then read every register and compare
// actual vs the modelled reset. Catches wrong defaults and bad tie-offs in one pass.
uvm_reg_hw_reset_seq hw_reset = uvm_reg_hw_reset_seq::type_id::create("hw_reset");
hw_reset.model = reg_model;
hw_reset.start(bus_sequencer);     // fails loudly on any register that powers up wrong

The clk_div reset of 1 is the whole lesson in miniature: a field whose interesting behaviour lives in a non-zero default, transcribed from the spec, checked against the DUT by a sequence you did not have to write.

6. Debugging Session — the model reset that was matched to the RTL

1

A model reset value 'corrected' to match the RTL makes the reset test agree with a wrong power-on default and ship it

RESET FROM RTL
Buggy Code
Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
// Spec: clk_div resets to 1 (divide-by-two). The RTL wrongly resets it to 0.
// An engineer 'fixes' the reset test by matching the model to the RTL:
clk_div.configure(this, 3, 1, "RW", 0, 0, 1, 0);   // BUG: reset modelled as 0 to match DUT
// The hw_reset sequence now reads clk_div=0 from the DUT and compares to model reset=0.
// UVM_INFO: hw_reset PASSED   <-- the wrong default is now 'verified'
Symptom

The reset test passes, which is the trap — it looks like the register is correct out of reset. In reality the model was bent to agree with a broken DUT: clk_div powers up at 0 (divide-by-one) instead of the spec's 1 (divide-by-two), so the block runs at twice its intended clock out of reset. Nothing in the suite complains, because the one test whose job was to catch this was told to expect the wrong value. The bug ships and surfaces as a block that is over-clocked at power-on in silicon — an expensive miss for a fault a correctly-modelled reset test would have caught on day one.

Root Cause

The model's reset value was taken from the RTL instead of the spec. The reset test compares the DUT's power-on value against the model, so if the model's reset is calibrated to the DUT, the comparison is the DUT against itself and can never fail — the check was disarmed. The original failure (model reset 1 vs DUT reset 0) was not a model bug at all; it was the reset test correctly reporting a DUT bug, and it got 'fixed' by silencing the messenger. The DUT is genuinely wrong; the model was made wrong to match it.

Fix

Restore the reset value from the spec: clk_div.configure(this, 3, 1, "RW", 1, 0, 1, 0);. The reset test now fails again — correctly — and the failure is filed against the RTL, whose flop must default to 1 per the spec. The discipline the bug teaches is the mirror of a real practice: when a reset check fails, the model is guilty until proven innocent only against the spec — confirm the modelled reset matches the programmer's guide, and if it does, the DUT is wrong. Never reconcile a reset mismatch by editing the model to match the DUT; that turns your verification into a rubber stamp for whatever the RTL happens to do.

7. Common Mistakes

  • Assuming every field resets to zero. The valuable resets are the non-zero ones — device IDs, safe clock divides, enabled-by-default bits; read each from its cell.
  • Matching the model's reset to the RTL. This disarms the reset test; the model resets from the spec, always.
  • Forgetting to call reset() before the first read. An unprimed mirror has no correct reference and the first read may mismatch spuriously.
  • Ignoring reset domains. A field with distinct hard- and soft-reset values needs both modelled, or a soft-reset test checks against the wrong value.
  • Skipping the reset test. It is the cheapest, earliest, highest-yield register test; not running it leaves power-on bugs for functional tests to find late, if at all.

8. Industry Best Practices

  • Run uvm_reg_hw_reset_seq first. Make the reset sweep the earliest register test; it catches a whole family of power-on defects in one pass.
  • Transcribe resets from the spec and trace them in review. Every configure() reset argument points at a spec cell — no exceptions, no RTL-matching.
  • Model every reset domain the spec defines. Name resets (HARD, SOFT) so each domain's value is checkable independently.
  • Treat a reset mismatch as a DUT/spec issue, not a model nuisance. Investigate the RTL or clarify the spec; do not silence the model.
  • Prefer generated resets for large maps. IP-XACT/RALF carries reset values, removing the transcription risk entirely (Chapter 13).

9. Interview / Review Questions

10. Key Takeaways

  • The reset value is the mirror's origin and the thing a reset test verifies — it is checked before any functional cycle runs.
  • Its path is spec → configure() reset argument → mirror (reset()) → uvm_reg_hw_reset_seq check; the model copies the spec, the RTL is checked against it.
  • Never source the model's reset from the RTL — doing so disarms the reset test and can ship a wrong power-on default.
  • Do not assume zero; the valuable resets are non-zero, and each field's reset is read from its own spec cell. Model every reset domain the spec defines.
  • The hardware-reset sweep is the earliest, cheapest, highest-yield register test — run it first, and treat a mismatch as a DUT or spec issue, not a model to be silenced.