Unique constraint

The unique constraint ensures that all variables in a list or elements to an array are assigned distinct (non-overlapping) values during randomization. If it is impossible to satisfy the uniqueness condition due to other constraints or limited ranges, the randomization attempt will fail.

Syntax:

constraint constraint_name {
    unique {variable1, variable2, ..., variableN};
}
//for an array
constraint constraint_name {
    unique {array};
} 

How It Works

  1. The unique keyword checks that all specified variables have distinct values.
  2. If the constraint solver cannot find unique values due to conflicts, randomization fails.
  3. unique constraints are typically used in scenarios requiring differentiation among elements.

Example 1: Unique IDs for a Group

Let’s consider a scenario where we need to assign unique IDs to a group of elements.

class UniqueIDExample;
    rand int id1, id2, id3;

    // Constraint to ensure all IDs are unique
    constraint unique_ids {
        unique {id1, id2, id3};
        id1 inside {[1:10]};
        id2 inside {[1:10]};
        id3 inside {[1:10]};
    }
endclass

module tb;
    initial begin
        UniqueIDExample ex = new();

        // Randomize and display results
      repeat (5) begin
            if (ex.randomize()) begin
                $display("Randomized IDs: id1 = %0d, id2 = %0d, id3 = %0d", ex.id1, ex.id2, ex.id3);
            end else begin
                $error("Randomization failed!");
            end
        end
    end
endmodule

Explanation:

  1. Constraint: The unique_ids constraint ensures that id1, id2, and id3 are all distinct.
  2. Range Limitation: Each ID is constrained to a range of [1:10].
  3. Output: The randomization process generates unique IDs for each variable within the specified range.

Output:

Randomized IDs: id1 = 4, id2 = 5, id3 = 8
Randomized IDs: id1 = 7, id2 = 2, id3 = 8
Randomized IDs: id1 = 8, id2 = 2, id3 = 7
Randomized IDs: id1 = 6, id2 = 4, id3 = 3
Randomized IDs: id1 = 3, id2 = 7, id3 = 6

Example 2: Unique Priorities for Tasks

Imagine a scenario where we have multiple tasks, and each task must be assigned a unique priority level.

class TaskPriority;
  rand int priority_array[7]; // Array for task priorities

    // Constraint to ensure unique priorities
    constraint unique_priorities {
      unique {priority_array};
      foreach (priority_array[i]) priority_array[i] inside {[0:20]}; // Priorities range from 0 to 20
    }
endclass

module tb;
    initial begin
        TaskPriority tp = new();

        // Randomize and display results
      repeat (5) begin
            if (tp.randomize()) begin
              $display("Task Priorities: %p", tp.priority_array);
            end else begin
                $error("Randomization failed!");
            end
        end
    end
endmodule

Explanation:

  1. Unique Constraint: The unique keyword ensures all elements in the priority array have distinct values.
  2. Range Specification: Each priority is constrained to be within [0:20].
  3. Output: The generated priorities are unique for each task.

Output:

Task Priorities: '{12, 1, 19, 3, 6, 14, 10} 
Task Priorities: '{2, 16, 3, 4, 11, 5, 13} 
Task Priorities: '{17, 11, 16, 12, 3, 4, 10} 
Task Priorities: '{18, 11, 8, 4, 6, 3, 10} 
Task Priorities: '{4, 9, 14, 8, 12, 16, 18}

Advantages of Using Unique Constraints

  1. Ensures Uniqueness:
    • The unique constraint simplifies enforcing uniqueness across multiple variables, avoiding manual checks or additional logic.
  2. Improves Verification Quality:
    • Ensuring unique values in scenarios like IDs, priorities, or addresses helps uncover edge cases and prevents conflicts in simulation.
  3. Reduces Complexity:
    • Without unique, achieving the same effect would require additional logic and constraints.
  4. Scalable:
    • The unique constraint can handle arrays or sets of variables efficiently, making it suitable for large-scale testbenches.