Overview
Constrained Random Verification (CRV) is a verification approach in which random stimulus is shaped by constraints. The goal is to reach coverage targets by driving the design under test into interesting corner cases while avoiding invalid or illegal scenarios. In SoC verification, CRV is commonly used alongside directed verification: directed tests exercise known features explicitly, while constrained-random tests explore combinations that may be difficult to enumerate manually.
A public SoC verification article describes random traffic as transactions initiated from randomly selected masters to randomly selected slaves, with randomized transaction type, data size, and latency. This kind of traffic can stress buses, gaskets, masters, slaves, and system-level interactions.
How CRV differs from directed verification
Directed verification uses explicitly written stimuli, with each stimulus intended to verify specific design features. As design complexity grows, creating and maintaining enough directed stimuli becomes tedious, and engineers may miss bug scenarios hidden in behavioral corners.
CRV addresses this by generating required stimuli automatically from a constrained solution space. The verification owner specifies constraints and the testbench selects scenarios from the resulting space. The cited SoC article states that constraining data items requires identifying data-item classes and generated fields, then creating derived data-item classes that add or override default constraints.
Testbench structure and setup
A CRV environment requires a self-checking testbench with built-in stimulus generation, drivers, monitoring, scoreboarding, and checking. For SoC designs, the cited methodology includes:
- identifying masters and slaves in the system;
- replacing already-verified IO masters with stubs where appropriate;
- setting weight-based control for random slave selection;
- setting weight-based control for transaction count and size from different masters;
- setting weight-based control for transaction type, such as read, write, or snoopable transactions;
- adding randomized delay between transactions from each master;
- adding standard monitors and system-level scenarios that target functional coverage;
- enabling coverage dumping with an integrated exclude list.
The same source describes a generic stimulus base class from which protocol-specific stimuli can be derived. For example, in a design using AXI, a random_axi stimulus can be derived from the base class to randomize and convert generic commands into AXI commands. Runtime parameter files can control values such as slave weightage, read/write weightage, and maximum transaction size, enabling automated variation of random scenarios.
SoC bug-hunting scenarios
CRV is particularly useful for stressing system-level interactions. The cited SoC article gives examples including:
- multiple masters simultaneously accessing a single slave, to check bus arbitration and response sequencing;
- one master issuing transactions to multiple slaves, including AXI ID-based out-of-order behavior;
- unaligned and boundary address accesses in slave memories;
- back-to-back transactions from IP blocks with randomized inter-transaction delays, to check successful completion and expected minimum/maximum latency;
- cache coherency and stashing scenarios involving IO masters, L2 cache configuration, and core execution.
The same article reports bugs found with randomized procedures, including swapped control signals between modules and latency mismatches against architectural expectations. Latency mismatches were associated with overrun or underrun errors in FIFOs and jitter buffers, and in one described case could cause late packet arrival and dropped packets.
Coverage closure and feedback
CRV is closely tied to functional coverage closure. The SoC article concludes that typical design verification relies on manually developed directed and constrained-random tests to bring functional coverage to desired levels and support systematic bug hunting. It also recommends using grading after the random verification environment is frozen, so scenarios and seeds that contribute more to coverage can be run more often.
In the RISC-V context, RISC-V DV uses SystemVerilog/UVM constraints as the foundation for test generation. A cited RISC-V CRV evaluation identifies coverage feedback as a future direction: coverage information could guide instruction-stream generation toward coverage goals faster, but an efficient loop would require dynamically evolving constraint descriptions at runtime. The same evaluation reports immediate-field coverage statistics, including 100% coverage for SHAMT possible values, 87.77% for I-immediates, 47.07% for S-immediates, 5.18% for B-immediates, 0.01% for J-immediates, and 0.16% for U-immediates.
Limitations and research directions
A public trace-sampling paper identifies a core CRV problem: generating input stimuli that provide good coverage of targeted behavior-space corners. It also notes that existing CRV solutions do not provide formal guarantees on the distribution of system runs, and proposes TraceSampler, an Algebraic Decision Diagram-based tool for sampling bounded traces with provable uniformity or bias guarantees.
Another public study on coverage-driven verification notes that CRV and coverage-driven methodologies can rely on time-consuming and redundant simulation regressions, with manual effort required to adjust constraints and steer stimuli toward coverage objectives. That study proposes supervised machine learning with PyUVM to optimize regressions and reports at least 99% coverage regain with reduced simulation cycles.
For RISC-V CRV, cited future work includes broader mutation testing, more test iterations, evaluation on RTL cores and ISS/RTL cross-level settings, support for instruction-set extensions through generated constraint classes, and use beyond functional verification, such as error-resiliency evaluation, information-flow tracking, and side-channel evaluation.