Skip to content
VLSI Mentor

UVM RAL · Chapter 11 · Debugging RAL

Backdoor Path Debug

Backdoor peek and poke reach a register's RTL storage directly through its HDL path, bypassing the bus, adapter, mirror, and prediction, so a backdoor bug lives in one place: the path does not resolve to the storage you intended. The discipline is simple. Never trust a backdoor value you have not proven resolves. The symptom family is small too. A peek that reads X or a poke with no effect means the path reaches nothing. A value that stays constant regardless of index means a memory path was not indexed. A value that disagrees with a known-good frontdoor read means the path resolves, but to the wrong place. This lesson teaches proving resolution with a known-value probe and the built-in path check, and breaks a peek X from a wrong root that gets misread as a reset bug.

Foundation12 min readUVM RALdebuggingbackdoorhdl_pathresolution

Chapter 11 · Section 11.4 · Debugging RAL

1. Why Should I Learn This?

The backdoor bypasses the bus, adapter, mirror, and prediction, so when a backdoor value is wrong the cause is almost always the hdl_path not resolving — and a backdoor value you have not proven resolves can silently mislead every setup and check that relies on it (8.4). Knowing the small symptom family (X/no-effect, stale-regardless-of-index, disagrees-with-frontdoor) and the prove-it-resolves discipline is what keeps you from building on a path that reaches nothing or the wrong thing.

Learning backdoor path debugging completes the debug quartet: 11.1–11.3 handle the bus-path layers, and this handles the HDL-path layer that sits entirely outside them — and it is the one whose failures most often masquerade as DUT bugs.

2. Industry Story — the reset 'bug' that was an X from nowhere

A team's backdoor peek of a register out of reset returns X. The reading is immediate: 'the DUT is not resetting this register — bit-level X means uninitialized hardware,' and a reset bug is filed against the RTL. A designer investigates correct reset logic for a day, because the register does reset properly.

The peek returned X not because the register held X, but because the hdl_path did not resolve — the hdl_path root was wrong (a mis-named hierarchy level), so the backdoor read reached nothing, and 'nothing' reads as X. The X was not a value the register held; it was the absence of a resolved path. The team misread an unresolved path as a DUT reset bug, chasing hardware that was fine. Running the built-in HDL-path check would have flagged the path as unresolvable in seconds; a known-value probe (poke a value, peek it back) would have shown the poke had no effect — the tell of a path reaching nothing. Once the root was corrected, the peek returned the register's real (correct) reset value. The post-mortem lesson: a backdoor X is usually an unresolved hdl_path (wrong root/hierarchy/slice), not a DUT value — an X is the absence of a resolved path, not 'the register holds X'; never read meaning into a backdoor value you have not proven resolves, and verify paths with the built-in HDL-path check or a known-value probe before trusting (or blaming the DUT for) any backdoor result.

3. Concept — prove resolution; separate 'unresolved' from 'wrong place'

A backdoor failure is a path-resolution failure. The method: prove the path resolves, and classify the symptom.

  • The discipline: prove it resolves first. Do not read meaning into any backdoor value until the path is proven to resolve. Two tools:
    • the built-in HDL-path check (uvm_reg_mem_hdl_paths_seq, 4.7) — validates that every register's path resolves;
    • a known-value probe — poke a known value, peek it back, and cross-check a frontdoor read; agreement proves the path reaches the right storage.
  • Symptom triage:
    • peek reads X / poke has no effect -> the path does not resolve to real storage: a typo, wrong hdl_path root, missing hierarchy level, or wrong slice width. The X is absence of a path, not a held value.
    • Value stale/constant regardless of index -> for a memory, the path is not indexed per location (8.4); or the path resolves to a constant signal.
    • Backdoor disagrees with a known-good frontdoor -> the path resolves, but to the wrong register/bit.
  • The key distinction: does not resolve (X / no-effect — loud, obviously broken) vs resolves to the wrong place (a consistent, plausible, wrong value — subtle and dangerous, because it looks like a real value).

Here is the backdoor symptom-triage flow:

Backdoor triage: prove resolution, then X/no-effect = unresolved, stale-vs-index = not indexed, disagrees-frontdoor = wrong placeX / no-effectstale vs indexvs frontdoorPROVE the path resolves first (HDL-path check / poke-known-value probe)PROVE the pathresolves first(HDL-path check/…Classify thesymptompeek X / poke no-effect -> path does NOT resolve (wrong root/hierarchy/slice/typo)peek X / pokeno-effect ->path does NOTresolve (wrong…stale/constant regardless of index -> memory path not indexed (8.4) / constant signalstale/constantregardless ofindex -> memorypath not indexe…disagrees with known-good frontdoor -> resolves to the WRONG register/bitdisagrees withknown-goodfrontdoor ->resolves to the…KEY: 'does not resolve' (loud X/no-effect) vs 'resolves to WRONG place' (subtle, plausible-but-wrong)KEY: 'does notresolve' (loudX/no-effect) vs'resolves to…
Figure 1 — triaging a backdoor failure. First PROVE the path resolves (built-in HDL-path check, or a poke-known-value/peek-back probe cross-checked with a frontdoor read). Then classify the symptom: peek X or poke no-effect -> the path does NOT resolve (wrong root/hierarchy/slice/typo) — the X is the absence of a path, not a held value; stale/constant regardless of index -> a memory path not indexed (8.4) or a constant signal; backdoor disagrees with a known-good frontdoor -> the path resolves to the WRONG register/bit. The essential distinction: 'does not resolve' (loud: X/no-effect) vs 'resolves to the wrong place' (subtle: a plausible but wrong value). Never read meaning into an unproven backdoor value.

4. Mental Model — a backdoor value is only meaningful once the address is proven real

5. Working Example — proving resolution with a known-value probe

Prove the path resolves before trusting it, and classify a failure by symptom:

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
// PROVE RESOLUTION with a known-value probe: poke a chosen value, peek it back, cross-check frontdoor.
uvm_reg_data_t pk, fd;  uvm_status_e s;
reg_h.poke(s, 32'hA5A5_1234);      // write a KNOWN value directly to storage
reg_h.peek(s, pk);                 // read it back the backdoor way
reg_h.read(s, fd);                 // and a frontdoor read for cross-check
if (pk !== 32'hA5A5_1234)
  `uvm_error("BKDDBG", "poke had NO EFFECT / peek != poked value -> path does NOT resolve (wrong root/slice)")
else if (fd !== pk)
  `uvm_error("BKDDBG", "peek != frontdoor -> path RESOLVES but to the WRONG register/bit")
else
  `uvm_info("BKDDBG", "poke==peek==frontdoor -> path PROVEN to resolve to the intended storage", UVM_LOW)
Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
// Or use the built-in HDL-path check to validate ALL paths resolve before relying on any of them (4.7):
uvm_reg_mem_hdl_paths_seq hp = uvm_reg_mem_hdl_paths_seq::type_id::create("hp");
hp.model = reg_model;
hp.start(null);   // reports registers whose hdl_path does not resolve — run this BEFORE trusting backdoor
Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
// SYMPTOM triage once you observe a failure:
//   peek X / poke no-effect        -> UNRESOLVED path (typo, wrong root, missing hierarchy, wrong slice)
//   stale/constant regardless of i -> memory path NOT INDEXED (8.4) or a constant signal
//   backdoor != known-good frontdr -> resolves to the WRONG register/bit
// An X is the ABSENCE of a resolved path — NOT 'the register holds X'. Do not file a DUT bug on an X.

The known-value probe (poke/peek/frontdoor agreement) proves the path reaches the intended storage; without that proof, a backdoor value — especially a plausible one — means nothing. The next section is an X misread as a DUT bug.

6. Debugging Session — a peek X misread as a reset bug

1

A backdoor peek returns X because the hdl_path root is wrong, so the path resolves to nothing — and the X is misread as a DUT reset bug instead of an unresolved path

X = UNRESOLVED PATH, NOT A HELD VALUE
Buggy Code
Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
// The hdl_path ROOT is wrong (mis-named hierarchy level), so the backdoor reaches NOTHING:
reg_model.default_map.set_hdl_path_root("tb.dutt");   // BUG: 'dutt' — real hierarchy is 'tb.dut'
status_reg.add_hdl_path_slice("status_q", 0, 32);
// A backdoor peek of status_reg resolves to nothing -> returns X. The register itself resets fine.
Symptom

A backdoor peek of a register out of reset returns X. The immediate (wrong) reading is 'the DUT is not resetting this register — X means uninitialized hardware,' and a reset bug is filed against the RTL. A designer investigates the reset logic — which is correct — and finds nothing, because the register does reset properly. The X is constant (every peek returns X, regardless of DUT state), and a poke to the same register has no effect on a subsequent peek — both tells of a path reaching nothing, but they are easy to miss if you have already decided the X is a held value.

Root Cause

The hdl_path did not resolve: the hdl_path root was mis-named (tb.dutt instead of tb.dut), so the backdoor read reached no signal at all, and an unresolved backdoor read returns X. The X is therefore the absence of a resolved path — 'there is nothing at this address' — not the register's value; the register itself holds its correct reset value, reachable only if the path resolves. The failure was misdiagnosed because X was read as a held value (uninitialized hardware -> reset bug) rather than as unresolved-path. Confirming would have been instant: the built-in HDL-path check would flag status_reg's path as unresolvable, and a known-value probe would show a poke has no effect (peek still X) — the definitive signature of a path reaching nothing. It is not a DUT bug, a mirror bug (11.1), a prediction bug (11.2), or an adapter bug (11.3) — those are all bypassed by the backdoor; it is a path-resolution bug in the HDL-path layer.

Fix

Correct the hdl_path root to the real hierarchy (tb.dut), so the path resolves to the register's actual storage, and the peek returns the correct reset value. Then prove it with a known-value probe (poke/peek/frontdoor agreement) and run the built-in HDL-path check (uvm_reg_mem_hdl_paths_seq) to validate all paths resolve. The method the debug teaches: a backdoor X is almost always an unresolved hdl_path (wrong root/hierarchy/slice), not a DUT value — an X is the absence of a resolved path, so never file a DUT/reset bug on a backdoor X without first proving the path resolves. More generally: prove resolution (HDL-path check or known-value probe) before trusting any backdoor value, and distinguish unresolved (X / no-effect — loud) from resolves-to-the-wrong-place (plausible but wrong — subtle, caught only by cross-checking against a known-good frontdoor).

7. Common Mistakes

  • Reading a backdoor X as a held value. An X is almost always an unresolved path (wrong root/hierarchy/slice) — the absence of a path, not 'the register holds X.' Prove resolution before blaming the DUT.
  • Trusting a plausible backdoor value without proof. A path can resolve to the wrong register and return a believable-but-wrong value — cross-check against a known-good frontdoor.
  • Not proving resolution first. Run the built-in HDL-path check or a poke-known-value/peek-back probe before relying on any backdoor read.
  • Missing memory indexing. A backdoor value stale/constant regardless of index is an unindexed memory path (8.4), not a data bug.
  • Confusing a path bug with mirror/prediction/adapter bugs. The backdoor bypasses all of those — a backdoor failure is a path-resolution bug.

8. Industry Best Practices

  • Prove the path resolves before trusting any backdoor value. Known-value probe (poke/peek/frontdoor agreement) or the built-in HDL-path check (4.7).
  • Treat a backdoor X as an unresolved path. Check the root, hierarchy, and slice before considering a DUT/reset bug.
  • Cross-check backdoor against a known-good frontdoor. Catches a path that resolves to the wrong register — the subtle, plausible-but-wrong case.
  • Run uvm_reg_mem_hdl_paths_seq in bring-up. Validate that every register's path resolves before any test relies on backdoor.
  • Distinguish unresolved from wrong-place. X/no-effect is loud; a consistent wrong value is subtle — different symptoms, both path bugs.

9. Interview / Review Questions

10. Key Takeaways

  • Backdoor peek/poke reach RTL storage through the hdl_path, bypassing the bus, adapter, mirror, and prediction — so a backdoor failure is an HDL-path resolution bug, a layer apart from 11.1/11.2/11.3.
  • Never trust a backdoor value you have not proven resolves — use a known-value probe (poke known value / peek back / cross-check frontdoor) or the built-in HDL-path check (uvm_reg_mem_hdl_paths_seq, 4.7).
  • Symptom triage: peek X / poke no-effect = path does not resolve (wrong root/hierarchy/slice/typo); stale/constant regardless of index = memory path not indexed (8.4) or a constant signal; disagrees with a known-good frontdoor = resolves to the wrong register/bit.
  • A backdoor X is the absence of a resolved path, not 'the register holds X' — the signature bug is an X misread as a DUT/reset bug when the hdl_path root/hierarchy is wrong; never file a DUT bug on an unproven backdoor X.
  • Distinguish 'does not resolve' (loud: X/no-effect) from 'resolves to the wrong place' (subtle: plausible-but-wrong) — the second is more dangerous and is caught only by cross-checking against an independent known-good frontdoor, since a backdoor self-round-trip agrees with itself.

Standards & specifications

Governing standard
IEEE Std 1800.2 (UVM)(opens IEEE in a new tab)

Defines the UVM class library's API and semantics. Testbench structure, naming conventions and project methodology around that API are engineering practice, not requirements of the standard.

Reference implementation
Accellera UVM reference implementation(opens Accellera Systems Initiative in a new tab)

The open-source class library and user guide that most simulators ship. Useful alongside IEEE 1800.2 when a page discusses the implementation rather than the standardised API.

This page also covers RTL structure, verification approach and debugging technique. Those are engineering practice built on the standard, not requirements the standard itself imposes.

Where this fits

Part of UVM RAL Debugging — Mirror Mismatches & Access Failures.