Overview
In an object-oriented verification methodology, constrained-random stimulus generators are decomposed into cooperating classes that mirror the natural taxonomy of the design under test. In the context of microcode stimulus generation, opcodes are partitioned into categories, and each category is represented by a child class that derives from a common base instruction class. This approach replaces a single, monolithic generator with a hierarchy of smaller, more focused randomize problems, which simplifies both the constraint model and the profiling/optimization loop.
Multi-Class Randomization
To reduce the size of the randomization problem, the opcode class is split into multiple smaller classes. The opcodes are divided into a series of categories that map well to the knobs or weights used in the test interface. This multi-class architecture is the principal mechanism by which an object-oriented methodology keeps individual randomize calls tractable for the solver.
Base Class Structure
A base instruction class holds all the data members common to every opcode and contains most of the methods used to set, print, and pack data. Constraints that apply to every opcode are also placed in this base class. Concentrating the common data and behavior in a base class keeps duplication low and ensures that cross-category invariants are enforced uniformly.
Child Class Constraints
Each opcode category child class contains constraints specific to that set of opcodes. Inside each child class, a similar structure to the original single-class code is preserved — notably a set of implication operators keyed on the opcode type. Localizing category-specific constraints in derived classes keeps each child's constraint solver problem small and easier to debug.
Architectural Considerations
The instruction generator is controlled by a set of knobs (switches or weights) that allow the test writer to generate constrained stimulus. In the recommended configuration, there are no constraints in the test layer that directly control items in the sub-classes. The upper-layer random sequence is governed by knobs only and chooses the opcode category first. This sequencing permits the upper layer to allocate the correct sub-class object at the chosen location and add the sub-class instance into the sequence, avoiding premature sub-class decisions.
Wrapper Class for Cross-Layer Constraints
If the test layer must directly control any items in the lower levels, then all decisions related to which sub-class to randomize must be made first. A wrapper class is required in that case: it constrains all of the variables controlled by the tests, is randomized first, and then the correct sub-class object is allocated and randomized in a second phase of generation. The wrapper class therefore acts as a two-phase scheduling boundary between the test layer and the object hierarchy.
Performance Profiling
The VCS constraint profiler is used to analyze the runtime and memory performance of the generators. Runtime details are reported in three categories:
- Cumulative randomize calls — total CPU time consumed by each
randomizecall site, summed across all invocations. For example, a call atop_gen.svline 4308 can be individually fast (microseconds) yet dominate the budget because it is invoked 7,104 times, accumulating 44 seconds of CPU time. - Per-call (individual) randomize calls — slowest individual invocations, often correlating with the cumulative table. The visit-count suffix (e.g.,
op_gen.sv:4308@162) indicates the 162nd execution of that line within a loop; the slowest observed call in this profile took 3.2 seconds, but with only two invocations in the entire simulation so optimizing it has limited impact. - Per-partition randomize calls — the solver partitions a
randomizecall when unrelated random variables appear together, so the unrelated variables can be solved independently. The slowest-partition table typically correlates with both the per-call and cumulative tables.
The same set of statistics is also provided for memory consumption, allowing profiling-driven optimization of the object hierarchy.
Related Techniques
The methodology described here is one concrete implementation of hierarchical constrained-random test generation, in which a generator is organized as a hierarchy of class types with localized constraints and knob-driven selection of sub-classes.