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
endmodule

Notice 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 state

Specific block vs whole object

CallScopeEffect
obj.c_a.constraint_mode(0)One named blockOnly c_a is switched off
obj.constraint_mode(0)All blocksEvery constraint is switched off
obj.c_a.constraint_mode()One named blockReturns 1 if enabled, 0 if disabled
obj.c_a.constraint_mode(1)One named blockSwitches 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.

Similar Posts