Constraints (SystemVerilog Verification)
Definition
In SystemVerilog, a constraint is a Boolean expression that describes a property of one or more class fields. Constraints are declared as class members, just like fields and methods, using the constraint keyword. They can be written in the original class definition or in a derived (subclass) definition.
"A constraint is a Boolean expression describing some property of a field. Constraints direct the random generator to choose values that satisfy the properties you specify in your constraints. Within the limits of your constraints, the values are still randomly chosen. The process of choosing values that satisfy the constraints is called solving. The verification tool that does this is called the solver; the solver may be embedded in a simulator or be part of a separate testbench generator program." — Doulos tutorial [6fa7d584]
Role in Directed-Random Verification
Constraints are the mechanism that makes pseudo-random stimulus generation tractable. Pure random generation cannot efficiently cover corner cases or respect protocol specifications, while purely directed testing misses classes of bugs. Directed-random verification combines both approaches by letting the user control how random the data values are through constraints.
"In a directed random test, you control how random the data values are using constraints. For example, you might want to make sure that some memory locations are tested exhaustively, and that 'corner cases' (i.e. significant cases such as the minimum and maximum address values) are definitely tested." — Doulos tutorial [2119d9e0]
Syntax and Examples
A constraint is declared with the constraint keyword followed by a name and a Boolean body. For example, in a CAN_Message class modeling a CANbus frame, the 4-bit Data Length Code (DLC) is specified by ISO 11898 to lie in [0:8], even though the field can hold values 0–15:
class CAN_Message;
rand message_t message;
constraint c1 { message.DLC inside {[0:8]}; }
constraint c2 { message.data.size() == message.DLC; }
endclass: CAN_Message
The inside operator expresses range membership; an equivalent numerical inequality such as DLC <= 8 is also valid [6fa7d584, 5204399e].
Constraints may relate multiple fields, including dynamic-array sizes. In c2 above, the size of the payload data queue is constrained to equal the DLC, ensuring consistency between the declared length and the actual payload [5204399e].
Constraint Solving and Failure
The simulator's solver attempts to honor all declared constraints when randomize() is called. If a class's constraints are internally inconsistent, the solver fails to find a solution and randomize() returns 0 (failure). Conflicting constraints are therefore a common source of verification bugs in the testbench itself [5204399e].
Inheriting and Overriding Constraints
Because constraints are class members, a subclass can override a parent class's constraint. For example, a fixed-length CAN_Message_4 subclass can replace c1 with a single-value constraint:
class CAN_message_4 extends CAN_Message;
constraint c1 { message.DLC == 4; } // Overload c1
endclass
[5204399e]
The with Construct for Inline Constraints
Instead of subclassing, callers can apply additional or overriding constraints to a single randomize() call using the with construct:
test_message[0].randomize() with { message.DLC == 4; };
This is semantically equivalent to adding a constraint c3 { message.DLC == 4; } to the class, but is local to the call site [5204399e].
Wider Use of "Constraints" in Other Domains
The term constraint is used in many other formal settings:
- Adversarial machine learning: Domain constraints are relationships between features that an adversary must respect for an input to be realizable. Research has shown that up to 82% of adversarial examples produced by state-of-the-art crafting algorithms violate domain constraints, and enforcing them can improve model accuracy by up to 34% (arXiv:2105.08619).
- Set/cardinality constraints: Cardinality constraints generalize typestate properties in imperative programs, expressing subset and disjointness relations between object states. Satisfiability ranges from polynomial time (for restricted fragments) to NP-hard (arXiv:cs/0508123).
These notions share the constrain the search space intuition with SystemVerilog constraints but target different problem domains.