Skip to content
STIMSMITH

Object-Oriented Verification Methodology

Concept WIKI v1 · 6/4/2026

An object-oriented verification methodology structures constrained-random stimulus generators as a hierarchy of classes — a base class containing common data members, set/print/pack methods, and shared constraints, plus child classes for each opcode category that encapsulate category-specific constraints. Test layers control generation through knobs/weights, and a wrapper class is introduced when the test layer must reach into sub-class fields. Generator performance is monitored using a constraint profiler that reports cumulative, per-call, and per-partition CPU and memory statistics.

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 randomize call site, summed across all invocations. For example, a call at op_gen.sv line 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 randomize call 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.

CITATIONS

8 sources
8 citations
[1] Multi-class randomization splits the opcode class into multiple smaller classes organized as categories that map to the knobs/weights in the test interface. Generating AMD microcode stimuli using VCS constraint solver
[2] A base instruction class holds the data members common to all child classes and contains the set, print, and pack methods, along with constraints common to every opcode. Generating AMD microcode stimuli using VCS constraint solver
[3] Each opcode-category child class contains constraints specific to that set of opcodes, including a set of implication operators based on the opcode type. Generating AMD microcode stimuli using VCS constraint solver
[4] The test layer is controlled by knobs only, choosing the opcode category first so the correct sub-class object can be allocated and added to the sequence, with no test-layer constraints directly controlling sub-class items. Generating AMD microcode stimuli using VCS constraint solver
[5] If the test layer must directly control lower-level items, a wrapper class is required: it is randomized first to constrain the test-controlled variables, then the correct sub-class object is allocated and randomized in a second phase. Generating AMD microcode stimuli using VCS constraint solver
[6] The VCS constraint profiler reports runtime performance in three categories: cumulative randomize calls, per randomize call, and per partition, with analogous memory statistics. Generating AMD microcode stimuli using VCS constraint solver
[7] In the profiled workload, the call with the greatest cumulative CPU impact was at op_gen.sv line 4308, executed 7,104 times and consuming 44 seconds of CPU time, while the slowest individual call took 3.2 seconds but was invoked only twice. Generating AMD microcode stimuli using VCS constraint solver
[8] VCS partitions a randomize call into multiple partitions when random variables that are not related to each other occur in the same call, so the unrelated variables can be solved independently. Generating AMD microcode stimuli using VCS constraint solver