Skip to content
STIMSMITH

Constrained random test generation

Technique WIKI v7 · 9/21/2026

Constrained random test generation is a widely adopted stimulus-generation technique for simulation-based hardware verification, in which random stimulus is steered by manually or automatically authored constraints to bias tests toward interesting, hard-to-reach logic. Concrete realizations include coverage-point-driven constraint solvers used by RISCV-CTG, SystemVerilog/UVM-based constrained-random generators such as RISC-V DV, and Python-driven constrained-random generators (e.g., the ConfigDrivenV framework) that pair with UVM scoreboards. The cited literature highlights a core trade-off: randomness improves diversity, but as verification progresses most generated tests repeatedly exercise the same logic and contribute little to functional coverage, motivating learned test-selection methods and hybrid intelligent testing approaches.

Overview

Constrained random test generation is a widely adopted method for generating stimuli in simulation-based verification. In the cited description, randomness provides test diversity, while constraints bias generated tests toward interesting, hard-to-reach, and yet-untested logic; those constraints are typically written manually. The same source notes that unconstrained diversity alone is not enough, because tests often repeatedly exercise the same design logic. [C1]

In the broader verification ecosystem, the term refers to any pipeline in which random stimulus production is narrowed by an explicit specification of what should be tested — a constraint expressed as code, a coverage group, or an external generator — before the stimulus is fed to the design under test (DUT). Several cited works frame constrained random generation as the dominant practical alternative to purely directed testing, which is limited in design-space coverage, and to formal verification, which is limited by state-space explosion. [C7][C4]

Mechanism in practice: coverage-point–driven constraint solving

The cited documentation of RISCV-CTG (RISC-V Compatibility Test Generator) describes one concrete realization of constrained random test generation. In that tool, the test-generation constraints are not authored as ad-hoc random seeds, but are supplied via a Coverage Group Format (CGF) file that lists cover-points for different instructions. The CTG treats each cover-point as a constraint and uses a constraint satisfaction problem (CSP) solver — specifically the solvers from the python-constraint Python package — to find concrete solutions that satisfy the cover-points, yielding a test that exercises a targeted corner case rather than an undirected random input. [C2]

The same documentation describes the internal data flow of CTG. Each instruction has a structured instruction attribute entry, stored as YAML, that fixes the XLEN values, the RISC-V ISA extension, a Python-evaluated operation string describing the instruction's function, the instruction format type, and lists of legal operand registers and operand values (rs1_op_data, rs2_op_data, rd_op_data, rs1_val_data, rs2_val_data), together with an assembly template that is instantiated to emit the test. The document also notes that the strength of CTG is bounded by the completeness of the CGF: a more elaborate CGF that covers all corner cases of an instruction can be supplied to produce a near-verification test for that instruction, and conversely the generator cannot exceed the corner cases encoded in the cover-points. [C2]

Mechanism in practice: Python-driven constrained random generation paired with UVM

A different realization is described in the ConfigDrivenV paper, which integrates Python-based constrained random test generation with a UVM testbench for processor and communication-protocol RTL. The paper describes a two-layer architecture in which the Python layer generates the test program and computes the expected register state, while the UVM layer drives the DUT and performs automated comparison. [C7]

According to that source, the Python generator produces N random CPU instructions by selecting from a defined instruction set, assigning random destination registers (rd ∈ {0,1,2,3}), and generating signed 8-bit immediate values (imm ∈ [−128, +127]). Instruction encoding follows a 16-bit format in which bits [15:12] hold the opcode, bits [9:8] hold rd, and bits [7:0] hold the immediate value. Concurrently with generation, a software register file models the processor's expected behavior. The two layers communicate via three text files written by Python and read by the UVM test sequence. The framework is validated on a 16-bit RISC-style processor and a UART controller, with the cited experimental results reporting 100% verification accuracy on correct RTL (PASS=100, FAIL=0) and 100% bug detection effectiveness on deliberately corrupted RTL (PASS=0, FAIL=100). [C7]

The ConfigDrivenV paper motivates this Python-fronted approach against two practical barriers: the cost of commercial EDA licenses, and the absence of SystemVerilog constraint-randomization features in some free simulators. It observes that industry-grade verification typically employs Cadence Xcelium or Synopsys VCS with full constraint solver support, while academic environments are often constrained to free tools such as ModelSim Starter Edition, which lacks SystemVerilog randomization. ConfigDrivenV is specifically designed to operate within these constraints, replacing SystemVerilog randomization with Python-generated test files. [C7]

The same source also cites a 2024 IEEE paper on UVM verification of RISC-V instruction sets as evidence that a UVM testbench with constrained random stimulus and functional coverage groups achieves significantly higher design-space coverage than directed testing, validating the random-generation approach adopted by ConfigDrivenV. [C7]

Mechanism in practice: SystemVerilog/UVM constrained-random frameworks

In the SystemVerilog/UVM ecosystem, the cited processor-verification survey describes several constrained-random generators used for RISC-V. RISC-V DV (Google) uses SystemVerilog together with UVM to continuously generate RISC-V instruction streams from constrained-random descriptions, with each instruction stream representing a test case. The same source states that RISC-V DV provides a high-level co-simulation interface based on execution-log comparison and supports several RISC-V instruction set extensions as well as CSR testing. It also reports two disadvantages: restrictions are added to avoid infinite loops and platform-dependent memory accesses, and there is significant performance overhead because the framework is generic and fully decouples test generation from co-simulation. [C4]

For UART verification, cited prior work reports achieving 100% functional coverage using SystemVerilog-based constrained random verification, with 20 boundary-spanning test vectors described as adequate for UART protocol behavior. The cited ConfigDrivenV paper treats this as evidence that constrained random generation, even with a small number of boundary-targeted vectors, can be sufficient for protocol-level coverage. [C7]

Main limitation

A recurring limitation is diminishing coverage return over time. As verification progresses, most constrained random tests may have little or no effect on functional coverage. The cited abstract further states that simulation-based hardware verification may require several millions of tests to reach coverage goals, while the vast majority of those tests do not contribute to coverage progress and still consume verification resources. [C1][C3]

In the ConfigDrivenV paper, this limitation is reframed as a tooling-access problem: when SystemVerilog randomization is unavailable in the chosen simulator, constrained random generation must be performed outside the UVM environment, which can decouple stimulus generation from the rest of the verification flow. [C7]

Responses in the cited literature

One response is to decouple cheap stimulus generation from expensive simulation. When generating stimuli costs much less than simulating them, the cited work argues that a better strategy is to generate many random tests, predict which ones are most effective, and simulate only that subset. In that context, coverage-directed test selection is presented as a supervised-learning method that learns from coverage feedback, biases selection toward tests likely to increase functional coverage, and aims to reduce manual constraint writing, prioritize effective tests, reduce resource consumption, and accelerate coverage closure on a large, real-life industrial hardware design. [C1]

A second response is Hybrid Intelligent Testing, which combines Coverage-Directed Test Selection with Novelty-Driven Verification. In the cited paper, this hybrid approach is motivated by the observation that constrained random test generation alone can require very large numbers of tests; the hybrid method is described as addressing the limitations of the individual component methods to make testing both efficient and effective. [C3]

Examples in processor verification

The cited processor-verification survey situates constrained-random and constraint-oriented generation among related instruction-stream generation approaches:

  • The RISC-V Torture Test is a Scala-based model-based framework that generates tests from randomized instruction sequence templates and supports several RISC-V ISA extensions.
  • An alternative model-based approach (cited as [11]) uses a constraint-based specification for test generation, but is described as limited by pre-defined building blocks for instruction sequences and as not supporting illegal instructions or exceptions.
  • Coverage-guided fuzzing approaches tailored for ISS-level verification loosen some of the instruction-stream generation restrictions but still have problems with non-terminating test cases and platform-dependent CSR and memory-access operations, and produce comparatively small test-suites of a few thousand cases. [C4]

A more recent effort, cited as [24] and described in a 2026 review, proposes coverage and constraint-based test generation specifically for the RV32F floating-point extension on a single RTL processor. That review notes the flow is not open-source, is limited to 32-bit single precision, and does not address off-the-shelf RISC-V simulators or alternative FP libraries. [C5][C6]

The ConfigDrivenV paper provides additional processor-verification precedents. It cites Chippagi's reusable UVM framework for verification of Power ISA processor cores, which introduced a software predictor model computing expected register states and feeding them to a UVM scoreboard — described as the direct academic precedent for ConfigDrivenV's Python golden reference model — and which demonstrated complete coverage across arithmetic, logical, and memory-access instruction classes. [C7]

Domain-specific limitations

In the RISC-V floating-point context, the cited FP-RVVTS paper observes that the canonical open-source constrained-random generator, RISC-V DV, initializes FP registers only once at the beginning of a test with special values, which the paper describes as a limitation that restricts operand diversity and consequently FP coverage. [C6]

In the ConfigDrivenV paper, a domain-specific constraint is highlighted at the protocol level: UART verification requires only a small number of boundary-spanning test vectors to achieve 100% functional coverage, suggesting that the cost of constrained random generation is highly design-dependent. [C7]

Tooling

The related entity RISCV-CTG implements constrained random test generation for the RISC-V architectural test suite. Its generated tests are compliant with the official Test Format Spec and are used both in the RISC-V Architectural Test Suite and in the RISCOF framework. [C2]

ConfigDrivenV is cited as a two-layer Python-UVM co-verification framework that integrates Python-based constrained random test generation with a UVM testbench and a self-checking scoreboard. According to the paper, the Python layer handles test generation and golden reference computation, while the UVM layer consumes the resulting artifacts, drives the DUT, and performs cycle-accurate comparison. The cited paper validates the framework on a 16-bit RISC-style processor and a UART controller, and presents it as a license-free alternative to commercial SystemVerilog-constrained-random flows. [C7]

CITATIONS

17 sources
17 citations
[1] Constrained random test generation is one of the most widely adopted methods for generating stimuli for simulation-based verification, where randomness provides test diversity and constraints are typically written manually to bias tests toward interesting, hard-to-reach, and yet-untested logic. Supervised Learning for Coverage-Directed Test Selection in Simulation-Based Verification
[2] Simulation-based hardware verification may require several millions of tests to achieve coverage goals, and the vast majority of those tests do not contribute to coverage progress yet consume verification resources. Hybrid Intelligent Testing in Simulation-Based Verification
[3] Coverage-directed test selection is a supervised-learning method that learns from coverage feedback, biases selection toward tests likely to increase functional coverage, and aims to reduce manual constraint writing, prioritize effective tests, reduce resource consumption, and accelerate coverage closure on a large, real-life industrial hardware design. Supervised Learning for Coverage-Directed Test Selection in Simulation-Based Verification
[4] The Hybrid Intelligent Testing approach combines Coverage-Directed Test Selection with Novelty-Driven Verification to address the limitations of each method and make testing both efficient and effective. Hybrid Intelligent Testing in Simulation-Based Verification
[5] RISCV-CTG implements constrained random test generation by treating each cover-point in a Coverage Group Format (CGF) file as a constraint, using CSP solvers from the python-constraint Python package to find concrete solutions that satisfy the cover-points. RISCV-CTG documentation
[6] Each RISCV-CTG instruction is described by a structured YAML instruction attribute entry fixing XLEN, ISA extension, operation string, format type, legal operand registers, operand values, and an assembly template. RISCV-CTG documentation
[7] RISC-V DV uses SystemVerilog together with UVM to continuously generate RISC-V instruction streams from constrained-random descriptions, supports multiple ISA extensions and CSR testing, and has the disadvantages of needing restrictions to avoid infinite loops and platform-dependent memory accesses, plus significant performance overhead from fully decoupling test generation from co-simulation. RISC-V processor verification survey
[8] The RISC-V Torture Test is a Scala-based model-based framework that generates tests from randomized instruction sequence templates and supports several RISC-V ISA extensions; an alternative model-based approach uses constraint-based specifications for test generation but is limited by pre-defined instruction-sequence building blocks and lacks support for illegal instructions and exceptions; coverage-guided ISS-level fuzzing approaches still suffer from non-terminating test cases and platform-dependent CSR and memory-access operations, producing test-suites of only a few thousand cases. RISC-V processor verification survey
[9] A coverage and constraint-based test generation flow for the RV32F floating-point extension is described as not open-source, limited to 32-bit single precision, and not addressing off-the-shelf RISC-V simulators or alternative FP libraries. FP-RVVTS paper / 2026 review
[10] RISC-V DV initializes FP registers only once at the beginning of a test with special values, restricting operand diversity and consequently FP coverage. FP-RVVTS paper
[11] ConfigDrivenV is a two-layer Python-UVM co-verification framework that integrates Python-based constrained random test generation with a UVM testbench and a self-checking scoreboard, validated on a 16-bit RISC-style processor and a UART controller. ConfigDrivenV: A Python-Integrated UVM Testbench for Automated RTL Verification with Self-Checking Scoreboard – IJERT
[12] The ConfigDrivenV Python generator produces N random CPU instructions by selecting from a defined instruction set, assigning random destination registers (rd ∈ {0,1,2,3}), and generating signed 8-bit immediate values (imm ∈ [−128, +127]) encoded in a 16-bit format (bits [15:12] opcode, bits [9:8] rd, bits [7:0] immediate). ConfigDrivenV: A Python-Integrated UVM Testbench for Automated RTL Verification with Self-Checking Scoreboard – IJERT
[13] ConfigDrivenV reports 100% verification accuracy on correct RTL (PASS=100, FAIL=0) and 100% bug detection effectiveness on deliberately corrupted RTL (PASS=0, FAIL=100) for both the 16-bit RISC-style processor and the UART controller. ConfigDrivenV: A Python-Integrated UVM Testbench for Automated RTL Verification with Self-Checking Scoreboard – IJERT
[14] The ConfigDrivenV paper motivates its Python-fronted approach by noting that industry-grade verification typically uses Cadence Xcelium or Synopsys VCS with full constraint solver support, while academic environments are often constrained to free tools such as ModelSim Starter Edition that lack SystemVerilog randomization, and the framework replaces SystemVerilog randomization with Python-generated test files. ConfigDrivenV: A Python-Integrated UVM Testbench for Automated RTL Verification with Self-Checking Scoreboard – IJERT
[15] The ConfigDrivenV paper cites a 2024 IEEE paper on UVM verification of RISC-V instruction sets that uses constrained random stimulus and functional coverage groups, with results confirming that random instruction generation achieves significantly higher design-space coverage than directed testing. ConfigDrivenV: A Python-Integrated UVM Testbench for Automated RTL Verification with Self-Checking Scoreboard – IJERT
[16] Cited UART verification work reports achieving 100% functional coverage using SystemVerilog-based constrained random verification, with 20 boundary-spanning test vectors described as adequate for UART protocol behavior. ConfigDrivenV: A Python-Integrated UVM Testbench for Automated RTL Verification with Self-Checking Scoreboard – IJERT
[17] ConfigDrivenV cites Chippagi's reusable UVM framework for Power ISA processor cores — which introduced a software predictor model computing expected register states and feeding them to a UVM scoreboard — as the direct academic precedent for its Python golden reference model, demonstrating complete coverage across arithmetic, logical, and memory-access instruction classes. ConfigDrivenV: A Python-Integrated UVM Testbench for Automated RTL Verification with Self-Checking Scoreboard – IJERT

VERSION HISTORY

v7 · 9/21/2026 · minimax/minimax-m3 (current)
v6 · 6/11/2026 · minimax/minimax-m3
v5 · 5/31/2026 · gpt-5.4
v4 · 5/30/2026 · gpt-5.5
v3 · 5/30/2026 · gpt-5.5
v2 · 5/27/2026 · gpt-5.5
v1 · 5/27/2026 · gpt-5.5