System Verilog rand_mode() and constraint_mode()

In short: rand_mode() turns the random nature of a variable on or off, and constraint_mode() turns a constraint block on or off, both at run time. Call obj.rand_mode(0) to freeze all random variables or obj.var.rand_mode(0) for a single one; a frozen variable keeps its current value through randomize. Call obj.constraint_mode(0) to disable all constraints or obj.c_name.constraint_mode(0) for one block; a disabled constraint is ignored by the solver. Pass 1 to turn either back on.

A reusable class often has more randomness and more rules than a single test needs. Rather than editing the class, you switch parts off for one test and back on for the next. rand_mode controls variables; constraint_mode controls rules. Together they give per test control without touching the class source.

A simple way to picture it

Think of a sound mixing board. Each track has a mute button, and there are group mutes too. Muting a track is like rand_mode(0) on one variable: that voice stops changing. Muting a whole effect is like constraint_mode(0) on a rule: that rule stops shaping the sound. You do not rewire the board; you just toggle mutes for the mix you want right now.

rand_mode(): turn randomness on or off

A rand or randc variable can be frozen with rand_mode(0). While off, randomize leaves it at its current value. Turn it back on with rand_mode(1). Called on the object it affects all random variables; called on one variable it affects just that one.

class stim;
  rand  int a;
  randc int b;
endclass

module tb;
  initial begin
    stim s = new();
    void'(s.randomize());
    $display("1: a=%0d b=%0d", s.a, s.b);

    s.rand_mode(0);            // freeze ALL random variables
    void'(s.randomize());
    $display("2: a=%0d b=%0d (unchanged)", s.a, s.b);

    s.rand_mode(1);            // unfreeze all
    void'(s.randomize());
    $display("3: a=%0d b=%0d (random again)", s.a, s.b);
  end
endmodule

rand_mode() on a single variable

Naming one variable freezes only that one. Here a is frozen while b keeps randomizing, then the roles change. This is useful when you want to hold one field steady and vary the rest.

s.a.rand_mode(0);   // freeze only a; b still randomizes
void'(s.randomize());

s.b.rand_mode(0);   // now freeze b too
void'(s.randomize());

s.a.rand_mode(1);   // unfreeze a; b stays frozen
void'(s.randomize());

constraint_mode(): turn a rule on or off

Every constraint block is enabled by default. constraint_mode(0) disables it, so the solver ignores it; constraint_mode(1) enables it again. Called on the object it affects all blocks; called on one block name it affects just that block.

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.constraint_mode(0);      // disable ALL constraints
    void'(s.randomize());
    $display("2: a=%0d b=%0d (free)", s.a, s.b);  // any values

    s.constraint_mode(1);      // enable all again
    void'(s.randomize());
    $display("3: a=%0d b=%0d", s.a, s.b);        // 50, 100
  end
endmodule

constraint_mode() as a function

Called with an argument, constraint_mode() is a task that sets the state. Called with no argument on a named block, it is a function that returns the current state: 1 if the block is enabled, 0 if disabled. This lets you check before you change.

if (s.c_a.constraint_mode())      // reads current state (1 or 0)
  $display("c_a is enabled");
s.c_a.constraint_mode(0);          // disable just c_a
$display("c_a now = %0d", s.c_a.constraint_mode());  // 0

Expected output, in plain words

In the rand_mode example, line 1 shows random values, line 2 shows the same values because randomness was frozen, and line 3 shows fresh random values after unfreezing. In the constraint_mode example, lines 1 and 3 show a equal to 50 and b equal to 100 because the rules are on, while line 2 shows free values because the rules were disabled.

Note: these outputs describe what the code is written to produce from a read of the IEEE 1800 LRM. The free values vary by seed. Confirm on your own simulator or EDA Playground.

rand_mode vs constraint_mode

Pointrand_mode()constraint_mode()
ControlsWhether a variable is randomizedWhether a constraint block applies
Off effectVariable keeps its current valueRule is ignored by the solver
Scope optionsAll variables, or one variableAll blocks, or one block
As a functionReturns a variable stateReturns a block state (1 or 0)
Use it toHold a field steadyRelax or drop a rule for one test

When to use each

  • rand_mode(0) on one variable: hold a field, such as a fixed address, while everything else varies.
  • rand_mode(0) on the object: use the class as a plain container for one step, then re enable.
  • constraint_mode(0) on one block: relax a single rule for a corner case test without editing the class.
  • constraint_mode(0) on the object: generate deliberately illegal stimulus to check error handling.

Common mistakes to avoid

  • Forgetting to re enable: a variable or rule left off stays off for later randomize calls on that object.
  • Wrong scope: calling on the object affects everything; call on the variable or block name for fine control.
  • Confusing the two: rand_mode controls variables, constraint_mode controls rules. Reach for the right one.
  • Using it to permanently change behaviour: for a lasting change to a rule, override the constraint instead.

To change what a rule says rather than toggle it, see constraint override and enable and disable constraint. For the randomization entry points, read randomize vs std::randomize. More is in our SystemVerilog tutorials.

Frequently asked questions

What does rand_mode() do in SystemVerilog?

rand_mode() turns the random nature of a rand or randc variable on or off at run time. rand_mode(0) freezes the variable so randomize leaves it unchanged; rand_mode(1) turns randomization back on.

What does constraint_mode() do?

constraint_mode() turns a constraint block on or off at run time. constraint_mode(0) disables the block so the solver ignores it; constraint_mode(1) enables it again. All blocks are enabled by default.

What is the difference between rand_mode and constraint_mode?

rand_mode controls whether a variable is randomized. constraint_mode controls whether a constraint block applies. One acts on variables, the other on rules.

How do I disable randomization for one variable only?

Call rand_mode on that variable, for example obj.a.rand_mode(0). Only a is frozen; other random variables keep randomizing until you freeze them too.

Can I read the current state of a constraint?

Yes. Called with no argument on a named block, constraint_mode() is a function that returns 1 if the block is enabled and 0 if it is disabled.

When should I use constraint_mode(0) on the whole object?

Use it to generate deliberately illegal stimulus by disabling all constraints, which is handy for checking how the design handles error cases. Re enable afterward.

Similar Posts