Overview
Opcode category partitioning is an object-oriented technique for organizing constrained-random stimulus generators used in microprocessor verification. Rather than describing every opcode in one large class, the opcode definitions and their implication constraints are partitioned hierarchically: a common base class expresses the global constraints that apply to all opcodes, and derived sub-classes capture the constraints that apply to a specific category of related opcodes.
This partitioning is motivated by the observation that putting every opcode in a single class forces the constraint solver to solve one enormous problem with many random variables and many cross-cutting constraints. Splitting the problem along natural opcode categories shrinks the working set that the solver must manipulate, which reduces memory usage and increases randomization throughput.
Background: Single-class Randomization
In the simplest coding style for instruction generation, all opcodes and their constraints are placed in a single SystemVerilog class. This is the most flexible approach because constraints can reference any data member of the opcode class. The trade-off is solver efficiency: the constraint solver is asked to satisfy roughly 100 random variables and 800 constraint equations simultaneously, which makes randomization slow because the problem is large and complex. An opcode_type data member in the class selects which type of instruction is generated, and implication constraints ensure that only legal opcodes are produced.
The Partitioning Strategy
To shrink the randomization problem, the single opcode class is split into multiple smaller classes. A two-level hierarchy is used:
- Base class — holds the global constraints that must hold for every opcode, irrespective of category.
- Derived sub-classes — each defines a group (category) of related opcodes that share similar constraints, such as similar field encodings or similar legal attribute combinations.
The opcodes are divided into a series of these category sub-classes, so that when a particular opcode category is being generated, the constraint solver only has to handle the variables and constraints of that sub-class together with the global constraints of the base class. By partitioning the constraints hierarchically into smaller groups of opcodes, the memory requirements are drastically reduced, which increased performance.
Generator Architecture
Opcode category partitioning is realized inside a two-layer generator:
- Upper layer — a SystemVerilog
random sequenceconstruct with weighted knobs that controls the distribution of high-level instruction items. A test supplies a set of weighted values that direct the generator toward the required mix of instructions. - Lower layer — the opcode class hierarchy itself. It is randomized subject to the additional constraints and weights supplied from the upper layer. The constraint solver applies the upper-layer weights directly to this generator layer to shape the distribution of opcode types that are produced.
The lower layer is precisely where opcode category partitioning lives: the opcode class hierarchy (base class plus category sub-classes) is what the solver randomizes each time a new instruction is needed.
Benefits
The principal benefits of opcode category partitioning reported in the AMD/Synopsys case study are:
- Reduced solver memory footprint — by splitting a single ~100-variable / ~800-constraint problem into a base class plus several smaller category sub-classes, the solver manipulates far fewer constraints and variables per randomization call.
- Improved randomization performance — the smaller per-call problem allows the constraint solver to produce solutions more quickly.
- Preserved expressiveness — the global constraints in the base class ensure cross-category invariants are still enforced, while category sub-classes allow precise, fine-grained control over distributions and biases for hitting corner cases within each opcode group.
Relationship to Other Techniques
Opcode category partitioning is the structural mechanism that enables two higher-level techniques in the same generator flow:
- Multi-class randomization — the multi-class organization of the opcode definitions is the partitioning; it implements opcode category partitioning by trading a single monolithic class for a hierarchy of category classes.
- Hierarchical constrained-random test generation — the overall methodology of layering an upper-level weighted random sequence over a lower-level constrained-random opcode hierarchy relies on opcode category partitioning at the lower level to keep the constraint problem tractable.