Static constraints

The static keyword can be employed in particular scenarios where you want to define constraints that are independent of object instances. The static keyword in SystemVerilog serves two main purposes:

  1. Defining class members: Declares class variables or methods that are shared across all instances of the class.
  2. Defining constraints: Specifies constraints that are evaluated independently of any class instance.

When used in constraints, static ensures that the constraint is evaluated in a context not tied to an object instance. This is useful in scenarios where constraints depend on global or shared data rather than the internal state of an object.

Syntax of static Constraints

The static keyword is used within the constraint block. The syntax follows the structure:

static constraint constraint_name {
    // Define static constraints here
}

The static constraint block can include any logic or condition, but it must not reference any non-static class members, as they belong to specific instances.

Examples of Static Constraints

Example 1: Global Limit for Random Variables

Consider a scenario where you need to limit the range of a random variable across all instances of a class. Using the static constraint, you can enforce this limit globally:

class Packet;
    rand bit [7:0] data;
    static bit [7:0] global_max = 8'h7F;

    static constraint limit_data {
        data < global_max; // Applies to all instances of Packet
    }
endclass

In this example:

  • The global_max variable is declared as static, making it shared across all Packet objects.
  • The static constraint limit_data ensures that the data field for any instance of Packet is less than global_max.

Example 2: Synchronizing Across Multiple Instances

Static constraints can also enforce relationships between random variables in different objects by using shared data.

class Packet;
    rand bit [7:0] data;
    static bit [7:0] global_limit = 8'h50;

    static constraint sync_constraints {
        data <= global_limit;
    }
endclass

module test;
    initial begin
        Packet pkt1 = new();
        Packet pkt2 = new();

        // Modify global_limit
        Packet::global_limit = 8'h30;

        if (pkt1.randomize() && pkt2.randomize()) begin
            $display("Packet 1 Data: %h", pkt1.data);
            $display("Packet 2 Data: %h", pkt2.data);
        end else begin
            $display("Randomization failed!");
        end
    end
endmodule

Key points:

  • The global_limit variable is shared between pkt1 and pkt2.
  • Changing global_limit affects the constraints for both instances, demonstrating the global scope of static constraints.

Output:

Packet 1 Data: 12
Packet 2 Data: 1a

When to Use Static Constraints

Static constraints are particularly useful in the following scenarios:

  1. Global Rules: When rules must apply universally to all instances of a class.
  2. Shared Variables: When the constraint depends on shared or external variables.
  3. Synchronization: When constraints synchronize data generation across multiple instances.