SystemVerilog provides a useful feature called inline constraints, which allows users to apply additional constraints while randomizing class variables. This feature is particularly useful when you need to use a different set of constraints temporarily, alongside the class’s existing ones. Let’s explore this with easy-to-understand examples.
What Are Inline Constraints?
Inline constraints let you apply constraints on variables at the time of calling the randomize()
method. These constraints are added in-line with the class’s existing constraints. The randomization process considers both the original and in-line constraints, allowing you to impose temporary constraints without modifying the class’s original definition.
Example of Using Inline Constraints
Consider this example where we create a class with an existing constraint, and apply an in-line constraint using the with
construct at the time of randomization.
class Item;
rand bit [7:0] id;
constraint c_id { id < 25; }
endclass
module tb;
initial begin
Item itm = new ();
itm.randomize() with { id == 10; }; // Applying an in-line constraint
$display ("Item Id = %0d", itm.id);
end
endmodule
In this code:
- We define a class
Item
with a variableid
and a constraint (c_id
) that ensures theid
is less than 25. - We then use the
randomize()
method with an in-line constraint to set theid
to 10. This is done using thewith
keyword.
Simulation Output:
run -all;
# KERNEL: Item Id = 10
# KERNEL: Simulation has finished. There are no more test vectors to simulate.
As expected, the id
is randomized successfully to 10, as specified in the in-line constraint.
Handling Conflicting Constraints
Now, let’s see what happens if the in-line constraint conflicts with the existing constraint. Suppose the class has a fixed constraint on id == 25
, and the in-line constraint attempts to set id < 10
.
class Item;
rand bit [7:0] id;
constraint c_id { id == 25; }
endclass
module tb;
initial begin
Item itm = new ();
if (! itm.randomize() with { id < 10; })
$display ("Randomization failed");
$display ("Item Id = %0d", itm.id);
end
endmodule
In this case:
- The in-line constraint tries to set
id < 10
, but the original constraint has setid == 25
. - These two constraints are in direct conflict, which causes the randomization to fail.
Simulation Output:
ncsim> run
if (! itm.randomize() with { id < 10; })
|
ncsim: *W,SVRNDF: The randomize method call failed.
Observed simulation time : 0 FS + 0
ncsim: *W,RNDOCS: These constraints contribute to the set of conflicting constraints:
constraint c_id { id == 25; };
if (! itm.randomize() with { id < 10; })
ncsim: *W,RNDOCS: These variables contribute to the set of conflicting constraints:
rand variables:
id [./testbench.sv, 2]
Randomization failed
Item Id = 0
ncsim: *W,RNQUIE: Simulation is complete.
Since the constraints are incompatible, randomization fails, and id
remains unchanged.
Handling Conflicting Fixed Constraints
Now, let’s look at a situation where both the original constraint and the in-line constraint fix the variable to different values. Here, both constraints attempt to assign id
a fixed value, causing another failure.
class Item;
rand bit [7:0] id;
constraint c_id { id == 25; }
endclass
module tb;
initial begin
Item itm = new ();
if (! itm.randomize() with { id == 10; })
$display ("Randomization failed");
$display ("Item Id = %0d", itm.id);
end
endmodule
In this case:
- The in-line constraint tries to set
id == 10
, but the original constraint has setid == 25
. - Again, these constraints conflict, and randomization fails.
Simulation Output:
ncsim> run
if (! itm.randomize() with { id == 10; })
|
ncsim: *W,SVRNDF: The randomize method call failed.
Observed simulation time : 0 FS + 0
ncsim: *W,RNDOCS: These constraints contribute to the set of conflicting constraints:
constraint c_id { id == 25; };
if (! itm.randomize() with { id == 10; })
ncsim: *W,RNDOCS: These variables contribute to the set of conflicting constraints:
rand variables:
id [./testbench.sv, 2]
Randomization failed
Item Id = 0
ncsim: *W,RNQUIE: Simulation is complete.
Once again, the randomization fails due to conflicting constraints.
Key Takeaways
- Inline constraints are a flexible way to apply additional constraints during randomization without changing the class’s original constraints.
- If conflicting constraints are provided (either within the class or through inline constraints), randomization will fail.
- In-line constraints are not overridden but are considered along with the class’s original constraints during the randomization process.
Summary
Using SystemVerilog inline constraints can be extremely helpful when you need to apply different constraints temporarily. However, always ensure that the constraints you provide do not conflict with each other. The in-line constraints are considered along with the class constraints, making them a powerful feature for flexible testing and simulation scenarios.