Overview
Constraint solving is the task of finding values for variables that satisfy stated constraints over their domains. In the cited evidence it appears as a core technology for hardware verification flows, particularly in constrained random simulation (stimulus generation), SystemVerilog constraint randomization, and the generation of test cases for the functional verification of microprocessors. [C1] [C2] [C3] [C4]
Constraint Solving in Stimulus Generation for Constrained Random Simulation
Constrained random simulation is the main workhorse in hardware verification flows. It requires the random generation of input stimuli that obey a set of declaratively specified input constraints, which are applied to validate design properties by simulation. The efficiency of the overall flow depends critically on two factors: (1) the performance of the constraint solver and (2) the distribution of the generated solutions. [C1]
Research has proposed hybrid solvers based on Markov-chain Monte Carlo methods for efficient constraint solving in stimulus generation for mixed Boolean/integer variable domains, aiming to provide good performance and distribution. [C1]
Use in Theo for Microprocessor Functional Verification
A collection of code generation tools assist designers in the functional verification of high-performance microprocessors. These tools produce interesting test cases by using a variety of code generation methods including heuristic algorithms, constraint-solving systems, user-provided templates, and pseudo-random selection. [C2] [C3]
Run-time analysis and characterization of the generated programs provide an evaluation of their effectiveness in verifying a microprocessor design and suggest improvements to the code generation process. An environment combining code generation tools with analysis tools has provided excellent functional coverage for several generations of high-performance microprocessors. [C4]
Constraint Solving in SystemVerilog Verification
In SystemVerilog constraint randomization, the constraint solving engine is invoked by a randomize() call to generate values for randomized variables that satisfy the user's constraints. Constraint randomization is widely used in hardware design verification to produce realistic and diverse test scenarios. [C2]
From the user's perspective the randomization process is opaque: the simulation user does not have direct visibility into how constrained-random variables are generated. The cited debugging guide decomposes constraint-random generation into four components: [C2]
- Partition: when solving the constraints, the solver engine partitions the constraints into several steps.
- Solving steps: the steps that the engine uses to solve the constraints.
- Constraints: the constraints defined in the user's testbench code.
- Randomized variable: the variable to be generated randomly.
Common issues that arise in SystemVerilog constraint randomization include constraint violations (mis-defined or conflicting constraints), randomization failures (no valid values can be generated), seed-dependent variability between simulation runs, performance degradation from overly complex constraints, constraints that are too strict, and constraints that must change dynamically during simulation. The cited guide recommends reviewing constraint definitions for conflicts, using the solve keyword to guide the order in which constraints are considered, fixing seeds for reproducibility during development, simplifying or partitioning complex constraints, softening constraints with the soft keyword to allow flexibility, and implementing dynamic constraints with conditional statements. [C2]
Best-practice debugging requires a tool that can provide complete visibility into how constraints are resolved and into the randomization steps. The cited Verisium Debug tool integrates tightly with Xcelium, which lets it access the constraint solving and randomization process that occurs when running the simulation. Verisium Debug provides multiple views that help users understand not only how the constraint is coded but also the structure and relations of the constraints. [C3]
The data that Verisium Debug exposes for debugging constraint randomization comprises: [C3]
- Solver steps: the partition of the constraint and how the constraint is resolved in steps.
- Class structure: the class being randomized.
- Variables: the variables that are randomized in the selected solver step.
- Constraint: the constraint related to the selected solver step.
- Source: the randomization call in the source code and the constraint related to the solver step.
Within the Randomization Debug window, users can see how the constraint is partitioned and how many steps are within the same partition. Inspecting the variables and the source code of the constraint and the solving steps helps users further understand what is affecting the variables that are generated. [C3]
Verisium Debug additionally supports a "pre-randomize" capability that lets the user observe the distribution of the randomized values for a selected variable before the actual randomized run. This helps users validate the quality of the constraints and confirm that values are generated properly. [C3]