3 minutes reading time (604 words)

# Power of SystemVerilog Constraints

SystemVerilog constraints are pretty amazing ! Lets see one use case where constraints are used to generate two queues of random sizes with unique values. Let us assume total number of elements in each queue should be less than or equal to 10.

### Using a loooong way

Consider that both queues are part of a class called ABC. The first logical thing would be to decide the size of each queue which can be maintained in two separate variables that can be randomized. The constraints on these variables ensure that the total number of elements in each queue meets the requirement.

```class ABC;
int l_q[\$];
int l_q2[\$];

rand int l_q_size;
rand int l_q2_size;

constraint c_size { l_q_size inside {[1:9]};
l_q2_size inside {[1:10]};
(l_q_size + l_q2_size) <= 10;
l_q2_size >= 1;
solve l_q_size before l_q2_size;
}
endclass

module tb;
initial begin
ABC abc = new;
abc.randomize();
\$display ("l_q_size=%0d l_q2_size=%0d", abc.l_q_size, abc.l_q2_size);

for (int i = 0; i < abc.l_q_size; i++) begin
int l_num;
std::randomize(l_num) with { l_num inside {[1:10]};
!(l_num inside {abc.l_q});
};
abc.l_q.push_back(l_num);
end

for (int i = 0; i < abc.l_q2_size; i++) begin
int l_num;
std::randomize(l_num) with { l_num inside {[1:10]};
!(l_num inside {abc.l_q2, abc.l_q});
};
abc.l_q2.push_back(l_num);
end

\$display("l_q=%p", abc.l_q);
\$display("l_q2=%p", abc.l_q2);
end
endmodule
```

The class instance abc is randomized to decide on the size for each queue. That many number of elements can be randomized and pushed into the queue using a simple `for` loop. For each iteration, a local variable is randomized using the scope randomizer with inline constraints. These constraints ensure that unique elements are pushed into the queue and each element falls within the valid range.

In a similar way, the second `for` loop pushes a new set of elements into the second queue. Note that the inline constraint has also considered l_q or the first queue to keep elements unique between the two queues.

### Using only constraint solver

This is the fastest way to generate two queues with unique data.

```class ABC;
rand int l_q[\$];
rand int l_q2[\$];

constraint c_q {
l_q.size() + l_q2.size() inside {[1:10]};
l_q2.size() > 0;
l_q.size() > 0;

foreach (l_q[i]) {
l_q[i] inside {[1:10]};
}

foreach (l_q2[i]) {
l_q2[i] inside {[1:10]};
}

unique {l_q, l_q2};
}
endclass

module tb;
initial begin
ABC abc = new;
abc.randomize();
\$display("l_q=%p", abc.l_q);
\$display("l_q2=%p", abc.l_q2);
end
endmodule
```

This could be your next interview question !

#### Related Posts

By accepting you will be accessing a service provided by a third-party external to https://www.chipverify.com/