Enable/Disable specific constraints:
In short: To enable or disable one specific constraint, call constraint_mode() on the named block, not on the whole object: obj.block_name.constraint_mode(0) switches that one rule off, and obj.block_name.constraint_mode(1) switches it back on. Every other constraint keeps working. Called with no argument on a named block it returns the current state, 1 for enabled and 0 for disabled. This lets one reusable class serve many tests, each relaxing just the rule it needs.
A reusable transaction class usually carries several named constraint blocks. A single test often needs to relax only one of them, for example to reach a corner case, while keeping the rest intact. Naming the block in the constraint_mode() call gives you that precise control without editing the class.
A simple way to picture it
Think of a house with several circuit breakers, one per room. If you need to work on the kitchen wiring you flip only the kitchen breaker; the lights in every other room stay on. Flipping the main breaker would kill the whole house. Naming a specific constraint block is flipping one room breaker; calling on the object is the main breaker.
Disabling one named constraint block
Here a class has two rules, c_a and c_b. The test disables only c_a, so a becomes free while b still obeys its rule. Then it re enables c_a and both rules apply again.
class stim;
rand int a, b;
constraint c_a { a == 50; }
constraint c_b { b == 100; }
endclass
module tb;
initial begin
stim s = new();
void'(s.randomize());
$display("1: a=%0d b=%0d", s.a, s.b); // 50, 100
s.c_a.constraint_mode(0); // disable ONLY c_a
void'(s.randomize());
$display("2: a=%0d b=%0d", s.a, s.b); // a free, b=100
s.c_a.constraint_mode(1); // re enable c_a
void'(s.randomize());
$display("3: a=%0d b=%0d", s.a, s.b); // 50, 100
end
endmoduleNotice that disabling c_a left c_b untouched. That is the difference from disabling on the object, which would free both.
Checking a constraint state before changing it
Called with no argument, constraint_mode() is a function that returns the block state. This is handy when a base class or an earlier step may already have changed it, and you want to save and restore the state cleanly.
bit was_on;
was_on = s.c_a.constraint_mode(); // read: 1 or 0
s.c_a.constraint_mode(0); // disable for this step
void'(s.randomize());
// ... do the corner case work ...
s.c_a.constraint_mode(was_on); // restore prior stateSpecific block vs whole object
| Call | Scope | Effect |
|---|---|---|
obj.c_a.constraint_mode(0) | One named block | Only c_a is switched off |
obj.constraint_mode(0) | All blocks | Every constraint is switched off |
obj.c_a.constraint_mode() | One named block | Returns 1 if enabled, 0 if disabled |
obj.c_a.constraint_mode(1) | One named block | Switches c_a back on |
Expected output, in plain words
Line 1 prints a equal to 50 and b equal to 100 with both rules on. Line 2 prints a free random value and b still 100, because only c_a was disabled. Line 3 prints 50 and 100 again after c_a is re enabled. The free value on line 2 varies by seed.
Note: this describes what the code is written to produce from a read of the IEEE 1800 LRM. Confirm on your own simulator or EDA Playground.
When to disable a specific constraint
- You need one corner case that a single rule blocks, and you want the other rules to keep protecting the stimulus.
- A test reuses a base transaction but must relax one field, such as allowing an out of range address for an error test.
- You want to save and restore a block state around a short step, using the function form to read it first.
- You are debugging and want to see how one rule shapes the values by toggling just that block.
Common mistakes to avoid
- Disabling on the object by mistake: that frees every rule, not just the one you meant. Name the block.
- Wrong block name: the name must match the constraint block exactly, or the tool flags it.
- Forgetting to re enable: a block left off stays off for later randomize calls on that object. Restore it.
- Confusing it with rand_mode: constraint_mode toggles a rule; to freeze a variable use rand_mode instead.
Disable a rule vs change a rule
Disabling with constraint_mode(0) keeps the rule defined but ignores it for a run. If instead you want the rule to say something different, override it by name in a derived class. Toggling is temporary and per object; overriding changes the rule itself.
For the full method reference including rand_mode, see rand_mode and constraint_mode. To change what a rule says, read constraint override. For the two randomization entry points, see randomize vs std::randomize. More is in our SystemVerilog tutorials.
Frequently asked questions
How do I enable or disable a specific constraint in SystemVerilog?
Call constraint_mode() on the named block: obj.block_name.constraint_mode(0) disables just that rule and obj.block_name.constraint_mode(1) enables it. Other constraints keep working.
How is disabling one block different from disabling all constraints?
Naming the block affects only that rule. Calling constraint_mode(0) on the object affects every constraint block in the class, freeing all of them at once.
How do I check whether a constraint is enabled?
Call constraint_mode() with no argument on the named block. It returns 1 if the block is enabled and 0 if it is disabled, so you can save and restore the state.
Why would I disable just one constraint?
To reach a corner case that a single rule blocks while keeping the other rules protecting the stimulus, for example allowing an out of range address for an error test.
What happens if I forget to re enable a constraint?
It stays disabled for later randomize calls on that object. Save the previous state with the function form and restore it, or explicitly call constraint_mode(1).
What is the difference between disabling and overriding a constraint?
Disabling with constraint_mode(0) keeps the rule defined but ignores it for a run. Overriding by name in a derived class changes what the rule says. One is temporary, the other is a real change.


