All constraints are enabled by default, and considered by the constraint solver during every call to randomize(). A disabled constraint simply isn't considered at all. Constraints are enabled or disabled at runtime using constraint_mode().
11 min read | Intermediate Level
What You'll Learn
- How
constraint_mode()works both as a task (to enable or disable) and as a function (to check current status) - What actually happens to a variable's legal range once its constraint is disabled
- Why calling
constraint_mode()on a name that isn't an actual constraint is caught at compile time, not run time
Syntax
constraint_mode() can be called both as a task and as a function. Called as a task, it returns nothing, and takes an argument to turn the constraint on or off. Called as a function, it returns the constraint's current state:
// Called as a task
class_obj.const_name.constraint_mode(0); // Turn off the constraint
class_obj.const_name.constraint_mode(1); // Turn on the constraint
// Called as a function
status = class_obj.const_name.constraint_mode(); // status is an int variable to hold return value
constraint_mode() is a built-in method, and cannot be overridden.
Method
When called as a task, the argument means:
| Value | Meaning | Description |
|---|---|---|
| 0 | OFF | Disables the constraint |
| 1 | ON | Enables the constraint |
Example
Here's the effect constraint_mode() has on a simple constraint:
class Fruits;
rand bit[3:0] num; // Declare a 4-bit variable that can be randomized
constraint c_num { num > 4; // Constraint is by default enabled, and applied
num < 9; }; // during randomization giving num a value between 4 and 9
endclass
module tb;
initial begin
Fruits f = new ();
// 1. Print value of num before randomization
$display ("Before randomization num = %0d", f.num);
// 2. Call "constraint_mode" as a function, the return type gives status of constraint
if (f.c_num.constraint_mode ())
$display ("Constraint c_num is enabled");
else
$display ("Constraint c_num is disabled");
// 3. Randomize the class object
f.randomize ();
// 4. Display value of num after randomization
$display ("After randomization num = %0d", f.num);
end
endmodule
Output
ncsim> run Before randomization num = 0 Constraint c_num is enabled After randomization num = 8 ncsim: *W,RNQUIE: Simulation is complete.
With c_num active, num lands within (4, 9) as expected — 8 in this case. Now let's disable the constraint before randomizing:
module tb;
initial begin
Fruits f = new ();
$display ("Before randomization num = %0d", f.num);
// Disable constraint
f.c_num.constraint_mode(0);
if (f.c_num.constraint_mode ())
$display ("Constraint c_num is enabled");
else
$display ("Constraint c_num is disabled");
// Randomize the variable and display
f.randomize ();
$display ("After randomization num = %0d", f.num);
end
endmodule
Output
ncsim> run Before randomization num = 0 Constraint c_num is disabled After randomization num = 15 ncsim: *W,RNQUIE: Simulation is complete.
Turning off the constraint let the solver choose any value the variable's own type supports — num came out as 15, well outside the original (4, 9) window, but still fully valid for a 4-bit variable. Disabling a constraint doesn't set the variable to some fallback value; it simply removes that restriction, reverting the variable to its full natural range.
Quick Check
Q: If f.c_num.constraint_mode(1) were called right after this, then randomize() called again, what range would num fall back into?
Show Answer
(4, 9) again — the same range as the very first example. Re-enabling a constraint restores its original rule exactly, as if it had never been disabled.
Calling constraint_mode() on a Nonexistent Constraint
If constraint_mode() is called on a name that isn't an actual constraint in the class, it's a compile-time error:
module tb;
initial begin
Fruits f = new();
f.c_does_not_exist.constraint_mode(1);
end
endmodule
Output
f.c_does_not_exist.constraint_mode (1);
|
ncvlog: *E,NOTCLM (testbench.sv,11|21): c_does_not_exist is not a class item.
Where Is This Used?
Toggling a constraint at runtime is commonly used to temporarily relax a class's normal legality rules for one specific directed test — deliberately generating an out-of-range or illegal value to check how the DUT handles it — without needing a dedicated subclass just for that one scenario.
Common Beginner Mistakes
Mistake #1: Forgetting constraint_mode() serves two different roles
The same method name works both as a task (with an argument, to set the state) and as a function (with no argument, to query it). Why? Mixing these up — like expecting a return value from the task form, or trying to pass an argument to the function form — won't behave as intended.
Mistake #2: Assuming a disabled constraint sets some fallback value
As the second example shows, disabling c_num didn't reset num to anything specific — it just let the full 4-bit range back in. Why? A disabled constraint is simply removed from consideration; the variable is still randomized, just without that particular restriction.
Mistake #3: Assuming a typo'd constraint name fails silently
As the last example shows, referencing a constraint that doesn't exist is caught at compile time, not left to fail quietly at runtime. Why? This is a genuine compile error (NOTCLM), so a misspelled constraint name will stop compilation rather than producing confusing runtime behavior.
Mistake #4: Assuming constraint_mode() can be overridden
It's explicitly a built-in method. Why? Unlike ordinary class methods, constraint_mode() can't be redefined in a subclass — its behavior is fixed by the language itself.
Practice Exercise
Challenge: Predict the Range Before and After
Given rand bit [5:0] val; and constraint c_val { val inside {[20:30]}; }, what range can val take before disabling c_val, and what range can it take after calling constraint_mode(0) on it?
Hint
Work out the full natural range a 6-bit variable can hold, and compare it against the range the constraint itself specifies.
Solution
Before disabling: 20 to 30, exactly the range c_val specifies. After disabling: 0 to 63, the full range a 6-bit variable can naturally hold — the same pattern as the article's own example, just with a 6-bit variable and a different starting range instead of a 4-bit one.
Summary
In this tutorial, you learned:
constraint_mode()enables or disables a constraint when called as a task with an argument, and reports its current state when called as a function with none- Disabling a constraint doesn't set the variable to a specific value — it simply reverts the variable to its full natural range for that type
- Re-enabling a constraint restores its original rule exactly, as though it had never been turned off
- Calling
constraint_mode()on a name that isn't an actual constraint is a compile-time error, not a silent runtime failure