In SystemVerilog, just like static variables in a class, constraints can also be declared as static. A static constraint is shared across all instances of a class. This article will help you understand how static constraints work, how they differ from non-static constraints, and how to use them effectively in your code.
What Are Static Constraints?
Static constraints in SystemVerilog are constraints that are applied across all instances of a class. This means that when you turn a static constraint on or off, it affects every instance of that class. The main advantage of using static constraints is that they allow you to control constraints globally across multiple class instances.
When using the constraint_mode()
method, static constraints behave differently compared to non-static ones. Non-static constraints are specific to each instance, while static constraints are shared across all instances of a class.
Syntax for Static Constraints
To declare a static constraint, simply use the static
keyword before the constraint definition, like this:
class [class_name];
...
static constraint [constraint_name] [definition];
endclass
Non-Static Constraints: The Default Behavior
By default, constraints in SystemVerilog are non-static. This means each instance of a class gets its own copy of the constraint. Here’s an example showing two non-static constraints that apply to a class:
class ABC;
rand bit [3:0] a;
// Non-static constraints
constraint c1 { a > 5; }
constraint c2 { a < 12; }
endclass
module tb;
initial begin
ABC obj1 = new;
ABC obj2 = new;
for (int i = 0; i < 5; i++) begin
obj1.randomize();
obj2.randomize();
$display ("obj1.a = %0d, obj2.a = %0d", obj1.a, obj2.a);
end
end
endmodule
Explanation:
- Both
obj1
andobj2
will have their variablesa
constrained between 5 and 12 because both objects have the same non-static constraints. - Even though random values are generated, the constraints still enforce the limits.
Simulation Output:
obj1.a = 9, obj2.a = 6
obj1.a = 7, obj2.a = 11
obj1.a = 6, obj2.a = 6
obj1.a = 9, obj2.a = 11
obj1.a = 6, obj2.a = 9
ncsim: *W,RNQUIE: Simulation is complete.
Static Constraints: When You Want Global Control
Static constraints, on the other hand, apply globally to all instances of a class. Let’s see how static constraints behave differently from non-static ones.
Turning Off Non-Static Constraints
Let’s turn off a non-static constraint using the constraint_mode()
method and compare the behavior:
class ABC;
rand bit [3:0] a;
// Non-static constraint c1, static constraint c2
constraint c1 { a > 5; }
static constraint c2 { a < 12; }
endclass
module tb;
initial begin
ABC obj1 = new;
ABC obj2 = new;
// Turn off non-static constraint
obj1.c1.constraint_mode(0);
for (int i = 0; i < 5; i++) begin
obj1.randomize();
obj2.randomize();
$display ("obj1.a = %0d, obj2.a = %0d", obj1.a, obj2.a);
end
end
endmodule
Explanation:
- Here,
c1
is turned off forobj1
, meaningobj1
is no longer constrained bya > 5
. However,c2
, which is static, still applies. - For
obj2
, both constraints are still active.
Simulation Output:
obj1.a = 3, obj2.a = 6
obj1.a = 7, obj2.a = 11
obj1.a = 6, obj2.a = 6
obj1.a = 9, obj2.a = 11
obj1.a = 6, obj2.a = 9
ncsim: *W,RNQUIE: Simulation is complete.
As expected, when the non-static constraint c1
is turned off, obj1
can take values outside the range a > 5
, while obj2
remains constrained by both c1
and c2
.
Turning Off Static Constraints
Now let’s turn off the static constraint c2
and observe how both obj1
and obj2
are affected:
class ABC;
rand bit [3:0] a;
// Non-static constraint c1, static constraint c2
constraint c1 { a > 5; }
static constraint c2 { a < 12; }
endclass
module tb;
initial begin
ABC obj1 = new;
ABC obj2 = new;
// Turn off static constraint
obj1.c2.constraint_mode(0);
for (int i = 0; i < 5; i++) begin
obj1.randomize();
obj2.randomize();
$display ("obj1.a = %0d, obj2.a = %0d", obj1.a, obj2.a);
end
end
endmodule
Explanation:
- When the static constraint
c2
is turned off, bothobj1
andobj2
are affected because static constraints apply to all instances of a class. - Both objects can now take values outside the range
a < 12
.
Simulation Output:
obj1.a = 15, obj2.a = 12
obj1.a = 9, obj2.a = 15
obj1.a = 14, obj2.a = 6
obj1.a = 11, obj2.a = 11
obj1.a = 12, obj2.a = 11
ncsim: *W,RNQUIE: Simulation is complete.
Summary of Differences Between Static and Non-Static Constraints
Constraint Type | Effect on Instances | Applies to All Instances |
---|---|---|
Non-Static | Affects only the instance that calls the constraint | No |
Static | Affects all instances of the class | Yes |
Restrictions for Using Static Constraints
randc
variables are not allowed with static constraints because they are always solved first.- Integral values are required for the variables that are constrained.
- There should not be circular dependencies (e.g.,
solve a before b
combined withsolve b before a
).
Conclusion
Static constraints are powerful tools in SystemVerilog, allowing you to control constraints globally across multiple class instances. By using the static
keyword, you can manage your constraints more efficiently. Understanding how to toggle these constraints using methods like constraint_mode()
can help you create more flexible and controlled simulations.