Overview
Constrained-random stimulus generation creates automated random test stimuli while applying constraints that keep generated items legal and useful for verification. In the provided microprocessor verification example, random generators create microcode test sequences and emphasize distribution across meaningful opcode values and other instruction attributes, replacing a diminishing reliance on hand-written directed tests as design complexity grows. [C1]
The technique contrasts with sequential randomization of instruction fields, which the source describes as producing verbose, redundant code and offering limited control over distributions. SystemVerilog constraint constructs provide a concise way to describe possible combinations of microcode-instruction attributes and to control the distribution of values for individual fields. [C2]
Architecture
The cited generator uses a two-layer architecture. The upper layer is implemented with a SystemVerilog random sequence construct and weighted knobs that control high-level item distribution. The lower layer is an opcode class randomized with additional constraints and weights supplied by the upper layer. Tests provide weighted values that direct the generator toward the required instruction mix, and the constraint solver applies these weights to control the distribution of generated opcode types. [C3]
Single-class approach
A simple implementation style places all opcodes in one class. This is flexible because constraints can be applied between any data members in the opcode class, but it can slow randomization because the constraint solver must handle many random variables and a large, complex set of constraints. In the cited prototype, the opcode class contained about 100 random variables and 800 constraint equations. [C4]
In that single-class implementation, the class contained random variables and implication constraints to ensure legal opcodes. Opcode type was a key data member that controlled which instruction type was generated. [C5]
Hierarchical multi-class approach
To reduce the randomization problem size, the opcode class was split into multiple smaller classes. Opcodes were divided into categories that mapped to the knobs or weights used by the test interface. A base instruction class held data members common to child classes, common constraints, and shared methods for setting, printing, and packing data. Each opcode-category child class contained constraints specific to its opcode set, including implication constraints based on opcode type. [C6]
The source reports that partitioning constraints hierarchically into smaller opcode groups reduced memory requirements and increased performance. [C7]
Test-layer control and wrapper considerations
In the cited architecture, the instruction generator was controlled by knobs or switches that let test writers generate constrained stimulus. The test layer did not directly constrain subclass items; instead, the upper-layer random sequence selected the opcode category first, allowing the correct object type to be allocated and added to the sequence. [C8]
If a test layer directly controls lower-level subclass items, the source notes that decisions about which subclass to randomize must be made first. In that case, a wrapper class may be required: the wrapper constrains variables controlled by tests, is randomized first, and then the correct subclass object is allocated and randomized in a second generation phase. [C9]
Profiling and optimization
The VCS constraint profiler is used in the source to analyze generator runtime and memory. It reports runtime performance by cumulative randomize calls, per-randomize call, and per partition. This allows engineers to distinguish between randomize calls that are individually slow and those that dominate total CPU time because they are called many times. [C10]
The profiler can also show solver partitions. VCS partitions a randomize call when possible, especially when unrelated random variables occur within the same randomize call, so independent parts of the problem can be solved separately. [C11]
Role in verification
Within the evidence, constrained-random stimulus generation is positioned as a way to cover stimulus space efficiently, control opcode and instruction-attribute distributions, and bias generation toward corner cases. Its effectiveness depends not only on constraints themselves but also on generator architecture: a single class maximizes cross-field flexibility, while hierarchical multi-class partitioning can reduce solver problem size and improve memory and runtime behavior. [C1] [C4] [C6] [C7]