Part 9 · Register Model (RAL) · Intermediate

Desired vs Mirrored Theory

Two-value model fundamentals: what desired and mirrored represent, how each method changes them, and where policy/volatility alter expectations.

Mental model: intent vs belief

Treat desired as a queued software intent and mirrored as the model's best current estimate of hardware state. These values may intentionally diverge between staging and commit operations.

During a healthy frontdoor flow, divergence is temporary and explainable: set() changes desired only, update() drives bus and then mirror catches up via write response/predictor, read() may correct mirror from DUT observation.

  • desired changes on set(), write(value), and explicit set-like APIs.

  • mirrored changes on predict(), read(), mirror(), and successful write semantics.

  • Divergence is expected during planning; persistent divergence after synchronization is a signal.

  • Volatile and side-effect fields require policy-aware interpretation of mirror values.


Two-value model chart

Use this chart as a ground truth when reviewing code. If a method's expected value transition in logs does not match this table, your model assumptions are wrong.

diagram
[RAL] two-value model chart (single field perspective)

  Method / Event              Bus access?   desired after call       mirrored after call
  ─────────────────────────────────────────────────────────────────────────────────────────────
  set(v)                      No            v                        unchanged
  get()                       No            returns desired          unchanged
  get_mirrored_value()        No            unchanged                returns mirrored
  update(status)              Maybe         unchanged                if write occurs: aligns to desired
  write(status, v)            Yes           v                        expected to become v on success
  read(status, v_out)         Yes           policy-dependent         becomes observed DUT value
  predict(v)                  No            usually unchanged        becomes v
  mirror(status, UVM_CHECK)   Yes           unchanged               becomes observed value if read succeeds
  mirror(status, UVM_NO_CHECK)Yes           unchanged               becomes observed value

  Notes:
    - update() issues bus write only when desired != mirrored (per relevant map/policy).
    - policy-dependent desired updates vary by register/field behavior and access policy.
diagram
[UVM] transition timeline example

  Initial reset:
    desired=0x00, mirrored=0x00

  Test plans new config:
    set(0x2D)   -> desired=0x2D, mirrored=0x00

  Commit staged value:
    update()    -> bus write 0x2D
                  desired=0x2D, mirrored=0x2D

  External master writes 0x3A:
    DUT=0x3A, desired=0x2D, mirrored still 0x2D (until predictor/read)

  Predictor sees monitor txn:
    predict(0x3A) -> mirrored=0x3A (desired unchanged)

  Interpretation:
    Divergence desired!=mirrored now means software intent differs from observed state,
    not necessarily a bug.

SystemVerilog walk-through

The snippet below demonstrates intentional divergence and re-synchronization. Keep this style in diagnostics: print desired and mirrored before and after each operation.

systemverilog
task show_two_value_model(my_reg_block ral, uvm_component parent);
  uvm_status_e   status;
  uvm_reg_data_t rd;

  // Assume reset values are 0.
  `uvm_info("MIRROR", $sformatf("init desired=0x%0h mirrored=0x%0h",
                                 ral.ctrl.get(), ral.ctrl.get_mirrored_value()), UVM_LOW)

  // Stage intent only.
  ral.ctrl.set('h2D);
  `uvm_info("MIRROR", $sformatf("after set desired=0x%0h mirrored=0x%0h",
                                 ral.ctrl.get(), ral.ctrl.get_mirrored_value()), UVM_LOW)

  // Commit staged intent through bus.
  ral.ctrl.update(status, UVM_FRONTDOOR, .parent(parent));
  `uvm_info("MIRROR", $sformatf("after update desired=0x%0h mirrored=0x%0h status=%s",
                                 ral.ctrl.get(), ral.ctrl.get_mirrored_value(), status.name()),
                                 UVM_LOW)

  // Fresh bus read updates mirror with observed value.
  ral.ctrl.read(status, rd, UVM_FRONTDOOR, .parent(parent));
  `uvm_info("MIRROR", $sformatf("after read desired=0x%0h mirrored=0x%0h rd=0x%0h",
                                 ral.ctrl.get(), ral.ctrl.get_mirrored_value(), rd), UVM_LOW)
endtask

Interpreting divergence correctly

  • desired != mirrored can mean staged-but-not-committed intent (normal).

  • mirrored stale after external write means missing predictor/readback (plumbing issue).

  • mirrored changes while desired static often indicates explicit prediction from monitor traffic.

  • After mirror(UVM_CHECK), mismatch message uses mirrored as expected baseline.


Volatile and side-effect fields

Two-value logic is straightforward for plain RW fields and subtle for volatile/W1C/RC fields. Policy semantics determine whether mirrored should be expected to track software intent or hardware-side evolution.

diagram
[RAL] policy-aware expectations

  RW field:
    expected steady state: desired == mirrored (after sync)

  Volatile status counter:
    mirrored may age quickly without fresh predictor/read.
    desired is often irrelevant for pass/fail.

  W1C interrupt bit:
    desired write of 1 means "request clear", not "store 1".
    mirror should reflect post-side-effect state.

  RC field:
    read itself causes state change; mirror update must model clear-on-read behavior.

  Implication:
    Always evaluate failures through access policy before blaming predictor wiring.
systemverilog
// Example: W1C field modeling concept
class status_reg extends uvm_reg;
  `uvm_object_utils(status_reg)
  rand uvm_reg_field intr;

  function new(string name = "status_reg");
    super.new(name, 32, UVM_NO_COVERAGE);
  endfunction

  virtual function void build();
    intr = uvm_reg_field::type_id::create("intr");
    // access = W1C, reset = 0
    intr.configure(this, 1, 0, "W1C", 0, 1'b0, 1, 1, 0);
  endfunction
endclass

Key takeaways

  • desired and mirrored are complementary, not redundant.

  • A divergence is information; classify it before treating it as failure.

  • Policy semantics define what 'correct mirror behavior' means for non-RW fields.

  • Print both values in logs to avoid chasing phantom mismatches.

Common pitfalls

  • Expecting volatile fields to stay equal without prediction/readback.

  • Treating W1C desired=1 as expected mirrored steady state.

  • Using get() in debug output when investigating mirror drift.