
SystemVerilog Constraint Layering via
Reusable Randomization Policy Classes
John Dickol
Samsung Austin R&D Center
Austin, TX
j.dickol@samsung.com
Abstract- SystemVerilog provides several mechanisms for layering constraints in an object. Constraints may be
added via inheritance in a derived class. Inline constraints (i.e. randomize with {…} or `uvm_do_with) permit specifying
additional constraints when randomizing an object. Unfortunately, SystemVerilog does not provide a good way to save
these inline constraints for reuse in subsequent “randomize with” calls.
This paper describes a technique for packaging constraints into reusable “randomization policy” objects and using
one or more of them to augment the constraints used while randomizing another object. Examples will be shown for both
native SystemVerilog classes and UVM sequence items.
INTRODUCTION
SystemVerilog[1] classes and random constraints provide a powerful mechanism for creating verification
stimulus. The language provides several mechanisms for layering constraints in a class object. Constraints may be
added via inheritance in a derived class. Inline constraints (i.e. randomize with {…} or `uvm_do_with) permit
specifying additional constraints when randomizing an object. Unfortunately, SystemVerilog does not provide a
good way to save these inline constraints for reuse in subsequent “randomize with” calls.
This paper defines a way to encapsulate constraints into reusable “policy” classes and defines a methodology to
use arbitrary combinations of these policies when randomizing another object. These policies may either be
compiled into the other object or specified prior to randomization. Different test scenarios can use different
combinations of policies as needed. This technique is applicable to native SystemVerilog or to a verification
methodology such as UVM[2].
CONSTRAINT LAYERING SCENARIOS
Consider stimulus generation for a multi-processor memory system. Several types of constraints are typically
needed for generating interesting transaction addresses:
Limit addresses to the address ranges in the system memory map. These ranges may be dynamically
generated at runtime and may change during the simulation.
Avoid addresses in any reserved regions (e.g. “magic” addresses used for testbench control)
Constrain addresses to cause evictions from the data cache. This requires keeping track of what
addresses are currently in the cache and generating addresses which are not already in the cache.
In theory it’s possible to include these types of constraints into a transaction base class with appropriate control
knobs or add them as needed through inheritance. In practice, however, it is difficult to predict exactly what
constraint capabilities a test writer will want to use. So, the test writer will add constraints in a new class derived
from the base transaction. Different combinations of test constraints will require different derived classes.
Using inline constraints (randomize with{} or `uvm_do_with) is feasible for relatively simple constraints (e.g.
number of transactions, simple distributions, etc.), but can be cumbersome for the more complex constraint types
评论0