Skip to content
STIMSMITH

Constraint Solver

Concept WIKI v1 · 5/28/2026

A constraint solver, in the provided verification context, is the component of Synopsys VCS that solves SystemVerilog constrained-random randomization problems for opcode and microcode stimulus generation. Its performance depends strongly on the number of random variables and constraints presented to each randomize call; hierarchical partitioning of opcode constraints can reduce memory use and improve runtime.

Overview

In the provided evidence, a constraint solver is discussed in the context of Synopsys VCS and SystemVerilog constrained-random verification. It is used to randomize microcode instruction and opcode objects subject to constraints, weights, and legal combinations of instruction attributes. SystemVerilog constraint-language constructs provide a concise way to describe possible attribute combinations and control the distribution of individual fields, while the VCS constraint solver applies generator-layer weights to control the distribution of opcode types. [1]

Role in opcode stimulus generation

The described opcode generator uses a two-layer architecture. The upper layer is a SystemVerilog random sequence with weighted knobs that control high-level stimulus distribution. The lower layer is an opcode class randomized with additional constraints and weights from the upper layer. Tests provide weighted values that direct the required instruction mix, and the constraint solver applies those weights during generation. [2]

This use of a constraint solver addresses a limitation of traditional serial field randomization: randomizing instruction fields one after another can produce skewed distributions and gives limited control over the overall stimulus distribution. A constrained-random approach can improve distribution control, but if the modeled instruction set is complex, the resulting randomization problem can become too large and slow. [3]

Constraint problem size and architecture

A single-class opcode model is flexible because constraints can be applied across any data members in the opcode class. However, the evidence reports that this style may be slow because the solver receives many random variables and a large, complex constraint set; the cited opcode class contained about 100 random variables and 800 constraint equations. [4]

The evidence describes an object-oriented, hierarchical alternative: a base class contains global constraints shared by all opcodes, while derived subclasses define groups of related opcodes with similar constraints. Partitioning the constraints into smaller opcode groups reduced memory requirements and improved performance. [5]

A key optimization is to randomize the opcode category first, so the solver only sees constraints relevant to that category. In the reported comparison, the newer multiple-class implementation had seven times fewer constraints than the original single-class implementation, allowing the solver to compute solutions more efficiently. [6]

Solver modes and profiling

The evidence identifies two VCS solver modes used in the comparison: the default RACE solver and a BDD solver. The BDD solver elaborates the entire solution space of a randomize call before selecting a solution. This can consume substantial memory and time, but the solution space is cached to accelerate later calls. The BDD solver is described as working well when the randomization problem does not require excessive memory and the same randomize call occurs many times, as in CPU opcode generation. [7]

VCS constraint profiling reports cumulative and individual randomize CPU runtime, individual partition CPU runtime, and memory data. The VCS 2009.12 release also provided testcase extraction for automatically extracting the slowest partition from each randomize call. [8]

Reported performance observations

In the reported AMD microcode stimulus-generation study, the multiple-class architecture was faster than the single-class architecture with both solver modes and for both tested opcodes. The default RACE solver showed a 4x speedup, while the BDD solver showed a 2x speedup. Memory requirements also improved significantly in the multiple-class architecture; the study measured BDD memory because RACE memory use was typically smaller and not the limiting factor. [9]

Practical guidance from the evidence

For constrained-random opcode generation, the evidence supports the following practices:

  • Keep each randomize problem as small as practical by partitioning constraints hierarchically.
  • Separate global opcode constraints from category-specific constraints.
  • Choose a high-level opcode category before randomizing detailed fields, so irrelevant constraints are not included in the solver problem.
  • Use solver profiling to identify slow randomize calls and expensive partitions.
  • Consider the BDD solver when repeated calls can benefit from cached solution spaces, but account for its up-front memory and elaboration cost. [6][7][8]

CITATIONS

9 sources
9 citations
[1] SystemVerilog constraints describe possible microcode instruction attribute combinations and allow distribution control, while the VCS constraint solver applies weights to control opcode-type distribution. Generating AMD microcode stimuli using VCS constraint solver
[2] The opcode generator has an upper SystemVerilog random-sequence layer with weighted knobs and a lower opcode class randomized with constraints and weights. Generating AMD microcode stimuli using VCS constraint solver
[3] Serial instruction-field randomization can produce skewed distributions, while a simple constrained-random approach improves distribution but can hit speed and memory limits for complex x86 instruction generation. Generating AMD microcode stimuli using VCS constraint solver
[4] A single-class opcode model is flexible but can be slow because it presents many variables and constraints to the solver; the reported opcode class had about 100 random variables and 800 constraint equations. Generating AMD microcode stimuli using VCS constraint solver
[5] A hierarchical object-oriented structure with global base-class constraints and opcode-group subclasses reduced memory requirements and improved performance. Generating AMD microcode stimuli using VCS constraint solver
[6] Randomizing the opcode category first reduced the solver problem because only category-specific constraints were present; the newer implementation had seven times fewer constraints than the original. Generating AMD microcode stimuli using VCS constraint solver
[7] The BDD solver elaborates the full solution space before choosing a solution, can use substantial memory and time, caches the solution space, and is suitable when memory is acceptable and the same randomize call repeats often. Generating AMD microcode stimuli using VCS constraint solver
[8] VCS constraint profiling reports randomize CPU runtime, partition CPU runtime, and memory data; VCS 2009.12 provided testcase extraction for the slowest partition of each randomize call. Generating AMD microcode stimuli using VCS constraint solver
[9] In the reported comparison, the multiple-class architecture was faster with both RACE and BDD solvers; RACE showed a 4x speedup, BDD showed a 2x speedup, and BDD memory requirements improved significantly. Generating AMD microcode stimuli using VCS constraint solver