Part 9 · Register Model (RAL) · Intermediate
Mixed Access Patterns
Practical strategy: initialize quickly with backdoor, then verify behavior with frontdoor while preserving mirror coherence.
Why mixed access is common
Large environments often need thousands of register writes before meaningful stimulus begins. Doing all of them frontdoor wastes cycles and farm budget.
A pragmatic pattern is: backdoor for deterministic initialization, frontdoor for behavioral proof points, and selective cross-checking to maintain confidence.
[RAL][BUS][HDL] mixed-access strategy
phase A: backdoor preload
- fast deterministic DUT state setup
phase B: frontdoor feature stimulus
- prove adapter, bus decode, side effects
phase C: cross-check
- selective mirror/read verification
- optional uvm_reg_access_seq on focused setMixed access optimizes runtime without sacrificing integration evidence.
Frontdoor should remain mandatory for requirement-linked behaviors.
Backdoor preloads should be visible in logs for reproducibility.
Reference test skeleton
class mixed_access_test extends uvm_test;
`uvm_component_utils(mixed_access_test)
reg_env env;
task run_phase(uvm_phase phase);
phase.raise_objection(this);
backdoor_init_phase();
frontdoor_feature_phase();
crosscheck_phase();
phase.drop_objection(this);
endtask
task backdoor_init_phase();
uvm_status_e status;
`uvm_info("MIXED", "Backdoor init start", UVM_LOW)
env.reg_model.ctrl.write(status, 32'h0000_0001, UVM_BACKDOOR, .parent(this));
env.reg_model.mode.write(status, 32'h0000_0003, UVM_BACKDOOR, .parent(this));
env.reg_model.mask.write(status, 32'h0000_FF00, UVM_BACKDOOR, .parent(this));
// Optional mirror alignment depending on prediction policy
env.reg_model.ctrl.predict(32'h0000_0001, -1, UVM_PREDICT_DIRECT);
env.reg_model.mode.predict(32'h0000_0003, -1, UVM_PREDICT_DIRECT);
env.reg_model.mask.predict(32'h0000_FF00, -1, UVM_PREDICT_DIRECT);
endtask
task frontdoor_feature_phase();
uvm_status_e status;
uvm_reg_data_t data;
`uvm_info("MIXED", "Frontdoor feature phase start", UVM_LOW)
env.reg_model.cmd.write(status, 32'h0000_0001, UVM_FRONTDOOR, .parent(this));
env.reg_model.status.read(status, data, UVM_FRONTDOOR, .parent(this));
if (data[0] != 1'b1)
`uvm_error("MIXED", $sformatf("expected status[0]=1 got=0x%08h", data))
endtask
task crosscheck_phase();
uvm_status_e status;
uvm_reg_data_t fd_data;
uvm_reg_data_t bd_data;
`uvm_info("MIXED", "Cross-check phase start", UVM_LOW)
env.reg_model.status.read(status, fd_data, UVM_FRONTDOOR, .parent(this));
env.reg_model.status.read(status, bd_data, UVM_BACKDOOR, .parent(this));
if (fd_data !== bd_data)
`uvm_error("MIXED", $sformatf("fd=0x%08h bd=0x%08h", fd_data, bd_data))
endtask
endclass[TEST] execution timeline
t0 backdoor_init_phase
t1 feature control writes frontdoor
t2 DUT activity and monitor/predictor updates
t3 crosscheck compares frontdoor and backdoor observations
t4 report pass/fail with intent-tagged logsMirror coherence in mixed flows
Mixed flows can fail noisily if mirror state is not synchronized after backdoor updates. Decide whether to rely on direct predict, explicit reads, or later frontdoor refresh.
[RAL] mirror alignment options after backdoor writes
option 1: reg.predict(value, ..., UVM_PREDICT_DIRECT)
+ fast, explicit
- requires disciplined usage
option 2: immediate backdoor read
+ confirms actual HDL value
- extra calls
option 3: defer until first frontdoor read
+ simpler initial code
- risk of transient false mismatchtask safe_backdoor_set(uvm_reg r, uvm_reg_data_t v);
uvm_status_e status;
uvm_reg_data_t rd;
r.write(status, v, UVM_BACKDOOR, .parent(this));
r.read(status, rd, UVM_BACKDOOR, .parent(this));
if (rd !== v)
`uvm_error("MIXED", $sformatf("backdoor verify failed exp=0x%08h got=0x%08h", v, rd))
r.predict(rd, -1, UVM_PREDICT_DIRECT);
endtaskPick one mirror-alignment policy and apply it consistently.
Do not mix implicit and explicit prediction without documentation.
Cross-check key registers after init before running long sequences.
Pattern catalog
[REG] common mixed-access patterns
Pattern A: boot-config acceleration
backdoor preload large config tables
frontdoor trigger start bit
Pattern B: error-recovery validation
backdoor inject internal fault latch
frontdoor command to clear/recover
Pattern C: reproducible bug replay
backdoor set exact failing internal state
frontdoor execute minimal reproducer
Pattern D: weekly integrity sweep
mixed feature tests daily
full access_seq cross-check nightly[BUS][HDL] evidence strategy
keep artifacts:
- backdoor preload manifest
- frontdoor transaction logs
- mismatch report linking both paths
this preserves speed + traceabilityAnti-patterns and guardrails
[RAL] mixed-flow anti-patterns
anti-pattern 1:
backdoor preload + no mirror sync + immediate mirror check
-> false mismatch noise
anti-pattern 2:
backdoor modifies same register during frontdoor scenario
-> non-deterministic ownership
anti-pattern 3:
frontdoor result claims with no bus monitor evidence
-> weak integration confidence[TEST] guardrail checklist
before run:
define which registers may be backdoor-touched
define mirror sync policy
during run:
log each backdoor write reason
keep feature-critical registers frontdoor-driven
after run:
perform focused cross-check
archive mismatch diagnosticsKey takeaways
Mixed access is the practical default for large RAL regressions.
Backdoor initialization plus frontdoor proof gives strong cost-to-confidence ratio.
Mirror synchronization and ownership discipline prevent false failures.
Common pitfalls
Interleaving unsynchronized backdoor pokes during frontdoor measurements.
No explicit policy on which path owns each phase of the test.
Skipping cross-checks and assuming mixed flow correctness by construction.