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 variable id and a constraint (c_id) that ensures the id is less than 25.
  • We then use the randomize() method with an in-line constraint to set the id to 10. This is done using the with 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 set id == 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 set id == 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.

Scroll to Top