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:

ValueMeaningDescription
0OFFDisables the constraint
1ONEnables 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

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

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

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
Did you find what you were looking for?

Quiz

Test Your Knowledge

1 of 5 Score: 0 / 5