To test that DCRouter's ERR_CNT1 saturates, lesson 4.7 sends 300 faulty packets: thousands of cycles to reach one boundary. A shortcut writes 254 straight into the counter through a hierarchical path, then sends two faulty packets. The test runs a hundred times faster. It also never exercises the increment logic that carried the counter from 0 to 254, and never checks that a counter at 254 is reachable the normal way.
When should a test reach into the design instead of going through its pins?
The obvious answer is to use shortcuts whenever they save time: verification time is precious. But every shortcut replaces a real path with an artificial one. A backdoor write bypasses the logic that would have produced the value; a test mode with a shorter timer is not the mode that ships; a monitor that reads internal signals can fail to notice that the real outputs are wrong. Used without care, shortcuts verify a design that does not exist.
Hook | What it does | Power | Danger |
|---|---|---|---|
Backdoor access | Writes or reads state directly (register file, memory, counter) by hierarchical path or a register-model backdoor | Reaches deep states instantly; loads memories in zero time; reads state with no bus traffic | Skips the real write and read paths, their decoding, side effects and timing |
Test mode | A configuration that shortens timers, shrinks limits, or exposes internal state on pins | Makes rare events common; shortens tests | The shipped mode is not the tested mode; mode-select logic itself can be wrong |
Internal monitor | Watches internal signals to report or check events | Observability of hidden state; precise debug | Tied to the implementation; may be trusted instead of checking outputs |
DCRouter's ERR_CNT registers can be read and cleared over APB but not written. A test can still preload one through the simulator's deposit interface (here UVM's uvm_hdl_deposit, in a UVM environment; without UVM, the simulator's VPI vpi_put_value or a vendor deposit command does the same, as does a register-model backdoor). It must not simply assign the signal from the testbench: a variable driven by an always_ff may not be written by any other process, and a write at the clock edge would race the design's own update.
// snippet: preload ERR_CNT1 by backdoor, then reach saturation through the frontdoor
wait_drain(); // input 1 idle: nothing else updates err_cnt[1]
void'(uvm_hdl_deposit("tb.dut.err_cnt[1]", 254)); // backdoor deposit: skips 254 increments
queue_pkt(1, 0, 0, 2, 1); // two faulty packets through the real path
queue_pkt(1, 0, 0, 2, 1);
wait_drain();
check_reg(8'h14, 255, "ERR_CNT1 saturates at 255");The saturation boundary (254 to 255 to 255) is still exercised by real faulty packets; only the climb from 0 is skipped. That is the safe pattern: backdoor to set up, frontdoor to test the behaviour under check. The climb itself still needs a frontdoor test somewhere, which lesson 4.7's 300-packet loop provides.
One frontdoor path for everything a backdoor touches: every register written by backdoor is also written and read through the bus at least once.
Backdoor for setup, frontdoor for the check: the behaviour a test claims to verify goes through the real path.
Test modes run beside the real mode: a shortened timer is tested, and the full-length timer is tested at least once, perhaps by formal.
Monitors add to output checks, never replace them: an internal event seen is not an output proven right.
Check the hook itself: test-mode select and debug logic ship in silicon and can be wrong.
Practice | Purpose |
|---|---|
Register-model backdoors for fast setup and mirror checks | Load configuration quickly; compare the model's mirror with the design |
Memory preload by backdoor | Load programs and data tables without simulating the load |
Shortened timers under a test parameter | Make timeouts and watchdogs reachable in simulation |
A frontdoor test per register and per memory | Covers the paths the backdoors skip |
A team (illustrative) configured every register by backdoor in all tests, for speed. The register block's address decoder had two registers swapped. No test ever wrote a register through the bus, so the swap was found by the first software bring-up in the lab. A single frontdoor write-and-read test of each register would have found it on the first day.
It verifies saturation at 255 through real faulty packets; it skips the counter's climb from 0 to 254, which another frontdoor test must cover.
The shipped configuration uses the full timer; its length, comparison and mode-select logic are not exercised by the shortened mode.
Backdoors, test modes and internal monitors buy controllability and observability cheaply.
Each one skips a real path: use hooks for setup and the frontdoor for the behaviour under check.
List every hook in the plan with the frontdoor test or proof that covers what it skips.