Answer each question out loud before opening it. If you miss more than three in the checkpoint, revisit the lessons linked at the end.
How easily the testbench can drive the design into the state a check needs; depth, coincidence, quiet and fixed configuration reduce it.
How easily a wrong internal value becomes visible to a check: whether it reaches an output, how soon, and how clearly it points to the cause.
Activation is not enough: the wrong value was masked before an observed point, or reached an output no check compared.
Selectively: black-box scoreboards end to end, grey-box checks at stable internal boundaries, designer-owned internal assertions, and never an expected value taken from the design itself.
When it replaces the behaviour under test; use it for setup and keep a frontdoor test for every path it skips.
Status visibility for hidden state, parameterised depths and timers, designer assertions, clean interfaces, deterministic reset, debug counters.
Task. A DMA engine has a 64-entry descriptor queue, a 16-bit idle timeout, an internal retry counter (up to 7 retries per transfer) and a completion interrupt. For each of these four, say how hard it is to reach and to observe from the pins, and what you would do about it.
Descriptor queue: reaching full needs 64 descriptors queued while the engine is stalled; observable only as refused writes. Ask for a depth parameter and an occupancy status field; drive a stalled memory model; cover full. Idle timeout: 65,535 idle cycles is slow to reach; ask for a programmable threshold, test it short, and test the full value once or prove it with formal. Retry counter: reaching 7 retries needs a memory model that errors repeatedly on one transfer; the count is hidden, visible only as a final error. Use error injection to force retries, ask for the retry count in a status register, and add a designer assertion that it never exceeds 7. Completion interrupt: easy to reach, but a missed or duplicated interrupt is visible only if every interrupt is matched to a transfer; check interrupts against completed descriptors and read the interrupt status at the end of each test.
Sleeping (and sleeping with an output locked mid-packet).
About 5,100 on one input.
Losing credits only slows the output; no flit is wrong.
With the sink stalled, exactly 4 flits must leave each output; fewer means credits were lost.
Activation, propagation, detection.
mode was 0, so the mux selected a and the wrong sum never reached y.
It used the FIFO's own full flag, which is where the bug was; the fixed checker keeps its own occupancy count.
Backdoor to set up, frontdoor for the behaviour under check, and a frontdoor test for every path the backdoor skips.
The shipped timer length, its comparison logic and the mode-select logic.
They cost an afternoon then and a change request after RTL freeze, and their savings repeat in every test.