A nightly SoC run reaches a legal sequence that no one placed in a directed test. The failure trace crosses protocol traffic, reset behavior, and subsystem interactions, making the gap in the verification plan clear. Directed tests remain precise, repeatable, and easy to debug. The issue is assuming that a large directed suite can fully cover a complex SoC, rather than recognizing the scenarios it cannot reach.
No team can list every state combination in a complex SoC with directed tests. Independent subsystems, shared buses, concurrent DMA transactions, interrupt handling, and power management combine into sequences absent from the specification. Those interactions are common bug locations, yet directed tests are not structured to discover them.
Directed Tests: Strengths and Limits
Consider a directed AXI interconnect test that checks a 16-beat burst write from master 0 while master 1 reads from another slave. The intent and result are clear. It says nothing about master 1 being retried twice before its read completes, master 2 returning an out-of-order write response, and a power domain transition waiting on the slave under read access at the same time.
Most engineers would not author that sequence as a directed test, and a specification writer would not normally describe it in advance. Still, it is legal SoC behavior. If the interconnect fails under those conditions, a generator must produce that sequence to expose the defect before tape-out.
That is the core argument for constrained random verification. Directed tests remain valid, but their omissions cannot be fixed simply by adding more tests of the same kind.
Constrained Random: Reach and Requirements
In UVM, constrained random verification, or CRV, creates stimulus from randomized transaction objects. SystemVerilog constraints describe legal inputs, and the simulator's constraint solver selects values from that space on each run, creating different stimulus each time.
The constraint is as important as the randomization. With none, the testbench generates illegal or low-value stimulus. With too many, it compresses the space until the result resembles directed testing. Finding the right balance takes substantial engineering effort and is easy to mishandle.
Teams often bias constraints toward the happy path, where transactions are legal, complete, and normally ordered. The result can be many transactions but little exposure to error paths or unusual ordering. Retry behavior, error handling, and boundary conditions remain largely untouched when constraints make them too rare.
Use several constraint modes instead: a base mode for ordinary traffic, plus targeted modes that raise the rate of error injection, boundary conditions, and unusual orderings. Coverage feedback should guide the mode selection, so new runs do not repeatedly target bins that are already closed.
Coverage-Driven CRV: Feedback Loop
Coverage-driven verification connects observed results with the remaining test work. Functional coverage accumulates across simulator runs, then later constraints steer stimulus away from covered bins and toward bins that are still open.
In UVM, a coverage-driven test planner commonly reads the accumulated coverage database and adjusts constraint weights or selects modes before each run. The concept is simple, but operating it adds work. Seed tracking becomes essential: teams need to know which seeds hit particular bins, which produced failures, and how to reproduce a chosen failure.
While developing BigEndian's verification approach, we invested early effort in seed-management tooling. Teams told us the coverage loop was sound in theory but degraded because seed records were kept ad hoc and became hard to search. Reproducing a regression failure from three weeks ago, tied to one seed value and test configuration, is guesswork without a queryable seed database.
Where Directed Tests Win
Directed tests should not disappear. They are more efficient for protocol corner cases with exact timing requirements than waiting for constrained random stimulus to create the needed sequence. Reset sequencing, power-on initialization, and specific error injection are good examples for directed testing.
Across the multi-master cache coherency controllers and high-speed serial interface blocks we have examined, a useful division is clear: use directed tests for paths with exact timing and known failure modes, and CRV for concurrent activity spanning multiple agents.
The distinction is not simply functional correctness versus corner cases. Use directed stimulus when exact sequence order matters, and random stimulus when the space is broad and driven by interactions. The split depends on the module. A simple UART controller leans toward directed tests. A coherency fabric leans toward CRV. A DMA controller with scatter-gather and interrupt generation needs both, with a deliberate division.
Practical Constraint Design
The key constraint decision is which event rates to control. Ask how many transactions should inject errors or trigger boundary conditions. Teams new to CRV commonly set that rate too low, often below 5 percent. Moving it to 20 to 30 percent may feel excessive, but it is generally needed to exercise error paths before coverage closure stops progressing.
Do not keep one constraint set throughout verification. Broad exploration fits the early project stages. As coverage grows, move to targeted constraints for the bins still open. Keeping the initial set through tape-out can leave a team at 90 percent coverage, with the final 10 percent concentrated in the same three difficult bins deferred for two months.
Constraint maintenance deserves dedicated verification ownership. RTL changes can invalidate an existing constraint or leave it incomplete. A constraint that matched the original state machine may no longer describe the revised RTL. Review constraints with RTL changes, rather than waiting until a problem appears.
Directed and constrained random verification work best as complementary methods. Apply each where it delivers the most coverage for the engineering time required.