SystemVerilog offers a powerful feature known as Implicit Constraints, which help establish conditional relationships between variables. These constraints allow you to control how certain values are assigned based on specific conditions.
In SystemVerilog, two primary constructs are used to declare conditional relationships: Implication Constraints and if-else Constraints.
Implication Constraints
The implication operator ->
is used to define conditional relationships between two variables. This operator ensures that if a specific condition is true, a corresponding constraint must also be true.
Syntax
constraint c_name { condition1 -> condition2; }
Here, if condition1
is true, then condition2
must also be true. If condition1
is false, condition2
is not checked.
Example of Implication Constraint
In the following example, we use the ->
operator to ensure that if mode
equals 2, then len
must be greater than 10.
class ABC;
rand bit [2:0] mode;
rand bit [3:0] len;
constraint c_mode { mode == 2 -> len > 10; }
endclass
module tb;
initial begin
ABC abc = new;
for (int i = 0; i < 10; i++) begin
abc.randomize();
$display ("mode=%0d len=%0d", abc.mode, abc.len);
end
end
endmodule
Simulation Results
ncsim> run
mode=1 len=11
mode=6 len=3
mode=3 len=9
mode=7 len=11
mode=3 len=15
mode=2 len=12
mode=3 len=6
mode=2 len=12
mode=4 len=9
mode=7 len=13
ncsim: *W,RNQUIE: Simulation is complete.
In this simulation, the mode
does not always have to be 2 when len
is greater than 10. However, when mode
is 2, len
will always be greater than 10.
Implication Operator
The implication operator (->
) helps define the relationship between two variables.
If the condition on the left-hand side (LHS) of ->
is true, then the condition on the right-hand side (RHS) must also be satisfied.
Example: Using Implication Operator
class ABC;
rand bit [3:0] mode;
rand bit mod_en;
// If 5 <= mode <= 11, mod_en should be 1
constraint c_mode { mode inside {[4'h5:4'hB]} -> mod_en == 1; }
endclass
module tb;
initial begin
ABC abc = new;
for (int i = 0; i < 10; i++) begin
abc.randomize();
$display ("mode=0x%0h mod_en=0x%0h", abc.mode, abc.mod_en);
end
end
endmodule
Simulation Results
ncsim> run
mode=0xf mod_en=0x1
mode=0x9 mod_en=0x1
mode=0x3 mod_en=0x1
mode=0xe mod_en=0x1
mode=0x1 mod_en=0x1
mode=0x0 mod_en=0x0
mode=0x1 mod_en=0x0
mode=0xe mod_en=0x0
mode=0x5 mod_en=0x1
mode=0x0 mod_en=0x0
ncsim: *W,RNQUIE: Simulation is complete.
As shown, when mode
is between 5 and 11, mod_en
will be 1. If mode
is outside this range, mod_en
can take any random value.
If-Else Constraints
The if-else constraint allows you to specify different sets of constraints based on whether a condition is true or false. If the condition is true, the first set of constraints will be applied. Otherwise, the else part will be used.
Example of If-Else Constraint
In the following code, we use an if-else
block to manage the constraints based on the value of mode
. If mode
is inside the range 5 to 11, mod_en
will be set to 1. If mode
is equal to 1, mod_en
will also be 1. Otherwise, mod_en
will be constrained to 0.
class ABC;
rand bit [3:0] mode;
rand bit mod_en;
constraint c_mode {
if (mode inside {[4'h5:4'hB]})
mod_en == 1;
else {
if (mode == 4'h1)
mod_en == 1;
else
mod_en == 0;
}
}
endclass
module tb;
initial begin
ABC abc = new;
for (int i = 0; i < 10; i++) begin
abc.randomize();
$display ("mode=0x%0h mod_en=0x%0h", abc.mode, abc.mod_en);
end
end
endmodule
Simulation Results
ncsim> run
mode=0xb mod_en=0x1
mode=0x1 mod_en=0x1
mode=0x6 mod_en=0x1
mode=0x7 mod_en=0x1
mode=0x2 mod_en=0x0
mode=0x2 mod_en=0x0
mode=0x2 mod_en=0x0
mode=0x9 mod_en=0x1
mode=0x7 mod_en=0x1
mode=0x8 mod_en=0x1
ncsim: *W,RNQUIE: Simulation is complete.
This example shows how to use if-else constraints in SystemVerilog, making it easier to handle different conditions within a design.
Summary Table: Implication vs If-Else Constraints
Constraint Type | Condition | Result |
---|---|---|
Implication | mode == 2 -> len > 10 | If mode is 2, len will be greater than 10. |
If-Else | if (mode inside {[4’h5:4’hB]}) mod_en == 1; | If mode is within 5 to 11, mod_en will be 1, otherwise 0. |