Skip to content

UVM RAL · Chapter 7 · RAL Sequences

Hardware Reset Sequence

The hardware-reset sequence is the register test you run first, because it is cheap, catches many bugs per line, and needs nothing more than a freshly reset DUT. After the DUT comes out of reset, it reads every register through the frontdoor and compares each value against that register's modelled reset value. The subtle point is what it actually compares: the model against the RTL, not the RTL against the specification. So a mismatch tells you the model and the RTL disagree, but not which one is wrong, and the specification is the tie-breaker. This lesson explains how the sequence works, why it must run before any writing sequence disturbs state, and breaks the most-misdiagnosed bug: a failure caused by a mis-transcribed modelled reset value, where the instinct that the DUT is broken is wrong and the fix belongs in the model.

Foundation12 min readUVM RALhw_resetuvm_reg_hw_reset_seqreset valuesmodel vs RTL

Chapter 7 · Section 7.4 · RAL Sequences

1. Why Should I Learn This?

The hardware-reset sequence is the highest-value-per-effort register check there is — one setup, run first, and it verifies every register's power-on default, the thing the whole system relies on before any configuration happens. But it only helps if you read its results correctly, and the single most important thing to understand is what it compares: the model against the RTL, which means a failure is a question — 'which of these disagrees with the spec?' — not automatically a DUT bug.

Learning how hw_reset works and, crucially, that a mismatch is a model-versus-RTL disagreement to adjudicate against the spec, is what stops you from 'fixing' correct RTL to satisfy a wrong model — or vice-versa. It deepens the reset-value modelling of 1.3 and the built-in-suite overview of 7.2.

2. Industry Story — the reset 'bug' that was in the model

A team runs uvm_reg_hw_reset_seq and it fails on one register: the model says the reset value is 0x0000_0000, but the register reads back 0x0000_0001 out of reset. The conclusion is immediate and confident — 'the DUT has a reset bug, bit 0 is not clearing' — and a bug is filed against the RTL. A designer spends two days staring at correct reset logic, because the RTL is doing exactly what the specification says: this register's bit 0 is an enable that defaults to 1.

The actual defect was in the model: whoever built it transcribed the reset value as 0x0 instead of the spec's 0x1 (1.3). hw_reset did its job perfectly — it found that the model and the RTL disagree — but the team misread which side was wrong, because they assumed hw_reset compares 'RTL against the truth' when it really compares 'RTL against the model,' and the model was the thing that had drifted from the spec. Checking the spec would have settled it in a minute: spec says bit 0 resets to 1, RTL resets to 1, model says 0 — the model is the outlier. The post-mortem lesson: hw_reset compares the model against the RTL; a mismatch means they disagree, not that the RTL is wrong — go to the specification to decide which one to fix, because a mis-transcribed modelled reset value produces exactly the same failure as a genuine DUT reset bug.

3. Concept — read every register after reset, compare to the modelled reset value

The hardware-reset sequence runs after the DUT has been reset and does one thing across the whole model: for every register, it reads the register (frontdoor) and compares the value read against the register's modelled reset value — the value established with .set_reset(...) or the field's reset argument at build time (1.3). A mismatch is reported per register.

Three things make it work and make it interpretable:

  1. It must run on a genuinely reset DUT. The comparison is only meaningful if the DUT is actually in its reset state — so hw_reset runs first, before any writing sequence (bit-bash, access) disturbs register state (7.2). Run it after those and you are comparing 'reset values' against registers that have been written.
  2. It compares model against RTL. The 'expected' side is the model's reset value, not the spec directly. So the sequence verifies that the model and the RTL agree — which is only the same as 'the RTL is correct' if the model's reset value is itself correct.
  3. A mismatch is a question, not a verdict. When they disagree, the specification is the authority: whichever of model or RTL disagrees with the spec is the defect. It could be the RTL (a real reset bug) or the model (a mis-transcribed reset value, 1.3).

Here is the flow, including the interpretation step that the industry story skipped:

hw_reset flow: reset DUT, read every register, compare to modelled reset; on mismatch check spec to decide model bug vs DUT bugequaldifferRTL = specmodel = specReset the DUT (run hw_reset FIRST, before any writing sequence)Reset the DUT(run hw_resetFIRST, beforeany writing…Read every register(frontdoor)Compare read value to MODELLED reset value (1.3)Compare readvalue toMODELLEDreset value…Match — power-ondefault verifiedMismatch: model and RTL DISAGREE — check the SPEC (do not assume DUT bug)Mismatch:model and RTLDISAGREE —check the…RTL matches spec -> MODEL mis-transcribed: fix the model (1.3)RTL matches spec-> MODELmis-transcribed:fix the model…Model matchesspec -> real DUTreset bug: fixthe RTL
Figure 1 — the hardware-reset sequence and how to read its result. Reset the DUT, read every register frontdoor, compare each to its MODELLED reset value. A match passes. A mismatch means the model and RTL disagree — do NOT jump to 'DUT bug'; check the SPEC: if the RTL matches the spec, the MODEL is mis-transcribed (fix the model, 1.3); if the model matches the spec, the RTL has a real reset bug. hw_reset must run FIRST, on a genuinely reset DUT, before writing sequences disturb state.

4. Mental Model — hw_reset checks that two copies of the truth agree

5. Working Example — running hw_reset and resolving a mismatch

Running the sequence is a few lines; the discipline is in how you resolve a failure:

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
// Run hw_reset FIRST in the test, on a genuinely reset DUT (before bit_bash/access disturb state, 7.2).
uvm_reg_hw_reset_seq rst = uvm_reg_hw_reset_seq::type_id::create("rst");
rst.model = reg_model;
rst.start(bus_sqr);
// For every register: read (frontdoor) and compare to the MODELLED reset value set in build (1.3).
Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
// The modelled reset value being compared against is the one you set at model-build time:
class blk extends uvm_reg_block;
  // ...
  virtual function void build();
    ctrl = ctrl_reg::type_id::create("ctrl");
    ctrl.configure(this);
    ctrl.build();
    // The reset value hw_reset checks against comes from HERE. If this is mis-transcribed
    // from the spec, hw_reset will 'fail' on correct RTL. Transcribe from the spec carefully.
    ctrl.enable.set_reset(1'b1);   // spec: enable defaults to 1  <-- get this right, or hw_reset lies
  endfunction
endclass
Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
// Resolving a hw_reset mismatch: DO NOT assume the DUT is wrong. Adjudicate against the spec.
// Reported: ctrl read 0x0000_0001, model expected 0x0000_0000.
//   1. Check the SPEC for ctrl's reset value.
//   2. Spec says bit 0 (enable) resets to 1  -> the RTL (0x1) is CORRECT; the MODEL (0x0) is wrong.
//   3. Fix: ctrl.enable.set_reset(1'b1);   // fix the MODEL, not the RTL
// Had the spec said 0, the RTL would be the defect. The spec — not the sequence — decides.

The sequence is trivial to run; the skill is reading a mismatch as a model-versus-RTL disagreement and letting the spec decide which side to fix.

6. Debugging Session — a hw_reset failure whose bug is in the model

1

hw_reset compares model to RTL; a mismatch from a mis-transcribed modelled reset value looks exactly like a DUT bug but is fixed in the model

MODEL VS RTL — SPEC DECIDES
Buggy Code
Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
// The model's reset value was transcribed as 0, but the spec (and the RTL) say bit 0 resets to 1:
class ctrl_reg extends uvm_reg;
  rand uvm_reg_field enable;
  virtual function void build();
    enable = uvm_reg_field::type_id::create("enable");
    enable.configure(this, 1, 0, "RW", 0, 1'b0, 1, 1, 0); // BUG: reset arg = 1'b0; spec says 1
    // ... so the MODEL expects enable=0 at reset, but spec+RTL have enable=1 at reset.
  endfunction
endclass
// hw_reset then reports: enable read 1, expected 0  -> looks like a 'DUT reset bug'. It is not.
Symptom

uvm_reg_hw_reset_seq fails on ctrl: the register reads back 0x0000_0001 out of reset but the model expected 0x0000_0000. The failure message reads like a hardware reset defect — a bit that should be 0 is 1 — and the natural first conclusion is 'the DUT is not clearing bit 0 at reset.' A bug gets filed against the RTL, and a designer investigates reset logic that turns out to be entirely correct, because the RTL matches the specification. Time is lost chasing a defect that is not in the hardware.

Root Cause

hw_reset compares the model's reset value against what the RTL produces at reset — it verifies the two agree, not that the RTL matches the spec directly. Here the RTL is correct (the spec says enable defaults to 1, and the RTL resets it to 1), but the model was mis-transcribed: the field's reset argument was set to 1'b0 instead of 1'b1 (1.3). So the model and RTL genuinely disagree, and hw_reset correctly reports the disagreement — but the disagreeing side is the model, not the RTL. The failure looks identical to a real DUT reset bug (same message, same mismatch) precisely because hw_reset cannot, on its own, tell which copy of the reset value is the wrong one; only the spec can. The 'bug' is a transcription error in the register model, surfaced by hw_reset comparing it to correct hardware.

Fix

Before touching the RTL, check the specification for the register's reset value. Here the spec says bit 0 resets to 1, the RTL matches the spec, so the model is the outlier — fix the model's reset value (enable's reset argument to 1'b1, 1.3) and re-run; hw_reset now passes against the unchanged, correct RTL. The rule the bug teaches: hw_reset compares the model against the RTL, so a mismatch means they disagree — it does not tell you which is wrong. Adjudicate against the spec: if the RTL matches the spec, the model is mis-transcribed and you fix the model; only if the model matches the spec is the RTL the defect. Treating every hw_reset failure as a DUT bug wastes designer time chasing correct hardware and, worse, risks someone 'fixing' correct RTL to satisfy a wrong model.

7. Common Mistakes

  • Assuming a hw_reset mismatch is always a DUT bug. It is a model-versus-RTL disagreement; the model is mis-transcribed as often as the RTL is wrong (1.3). Check the spec.
  • Running hw_reset after writing sequences. It must run first, on a genuinely reset DUT — otherwise you compare 'reset values' against registers that have been written (7.2).
  • Mis-transcribing the modelled reset value. A wrong reset in the model makes hw_reset 'fail' on correct RTL — get the reset values right (1.3).
  • 'Fixing' correct RTL to satisfy a wrong model. The worst outcome — always let the spec, not the sequence, decide which side to change.
  • Skipping hw_reset because it seems trivial. It is the cheapest, highest-yield register check — run it every time.

8. Industry Best Practices

  • Run hw_reset first, every time. Cheapest, highest-yield register check; it goes before bit-bash and access on a genuinely reset DUT (7.2).
  • Treat a mismatch as a spec question. 'The model and RTL disagree — which one matches the spec?' — resolve there, not by assuming a DUT bug.
  • Get modelled reset values right at build time. Transcribe carefully from the spec; a wrong model reset makes hw_reset unreliable (1.3).
  • Never change RTL to satisfy the model without spec confirmation. The spec is the authority for reset values, not the register model.
  • Re-run hw_reset after reset-related RTL or model changes. It is fast and catches reset regressions immediately.

9. Interview / Review Questions

10. Key Takeaways

  • The hardware-reset sequence (uvm_reg_hw_reset_seq) reads every register after reset and compares it to the register's modelled reset value (1.3) — the cheapest, highest-yield register check, run first.
  • It compares the model against the RTL, not the RTL against the spec — so a mismatch means the two disagree, not that the RTL is wrong.
  • A mismatch is a question, not a verdict: check the specification — whichever of model or RTL disagrees with the spec is the defect; a mis-transcribed model reset value (1.3) fails identically to a real DUT reset bug.
  • Never 'fix' correct RTL to satisfy a wrong model — let the spec, not the sequence, decide which side to change.
  • hw_reset must run on a genuinely reset DUT, before any writing sequence (bit-bash, access) disturbs register state (7.2) — otherwise it compares reset values against written registers.