Generate the array of unique values without using random and constraints
In short: When you need an array of distinct values in a mixed order but do not need full randomness, you can skip constraints. Fill the array with known distinct values, such as the index itself, then call the built in shuffle() method to rearrange them. The result has no repeats and a random order, and it solves instantly because there is no constraint solver involved. The catch is that the set of values is fixed; only the order is random.
The constraint solver is powerful but not free. For a set of distinct values where you only care about order, a fill and shuffle is far cheaper and just as correct. It is a handy trick for quick tests and large arrays.
A simple way to picture it
Think of numbered raffle tickets. You print tickets 1 through 10, so they are already all different. Then you drop them in a bag and shake it. When you draw them out, the order is random but you still have exactly tickets 1 through 10 with no repeats. Filling the array is printing the tickets; shuffle() is shaking the bag.
The fill and shuffle method
Fill each element with its index, or any formula that gives distinct values, then call shuffle() on the array. The values stay distinct and the order becomes random.
module tb;
int data[10];
initial begin
foreach (data[i])
data[i] = i; // 0,1,2,...,9 all distinct
data.shuffle(); // mix the order, keep the set
$display("data = %p", data);
end
endmoduleAfter shuffle() the array still holds 0 through 9, but in a mixed order such as 3, 7, 0, 9, 1, and so on. No value repeats because the fill made them distinct to begin with.
Using a formula for the values
The fill does not have to be the plain index. Any formula that gives distinct results works, such as squares or a base plus offset for addresses. Here the array holds ten distinct even numbers, shuffled.
module tb;
int addr[8];
initial begin
foreach (addr[i])
addr[i] = 32'h1000 + (i * 4); // distinct word addresses
addr.shuffle();
$display("addr = %p", addr);
end
endmoduleExpected output, in plain words
The first example prints the numbers 0 through 9 in a mixed order, with each value appearing exactly once. The second prints eight distinct word addresses starting from 0x1000 and spaced by 4, again in a mixed order. The set of values is fixed; only the order changes from run to run.
Note: these outputs describe what the code is written to produce from a read of the IEEE 1800 LRM. The order depends on the seed, so it differs each run. Confirm on your own simulator or EDA Playground.
shuffle vs the unique constraint
These two solve related but different problems. The unique constraint gives a fully random set of distinct values chosen by the solver. Fill and shuffle gives a fixed set in a random order, with no solver cost. Pick based on whether the values themselves need to be random or just their order.
| Point | Fill + shuffle | unique constraint |
|---|---|---|
| Values | Fixed set you choose | Random set the solver picks |
| Order | Random | Random |
| Solver cost | None | Uses the constraint solver |
| Speed | Very fast | Slower for large or tight sets |
| Best for | Distinct values, order matters | Fully random distinct values |
When to use fill and shuffle
- You need distinct values and only the order must be random.
- You want speed on a large array without the solver cost.
- The value set is known, such as a fixed list of addresses or IDs.
- You are writing a quick test and do not need constrained randomness.
Common mistakes to avoid
- Expecting random values, not just order: the set is fixed by your fill; only the order changes.
- A fill that repeats: if your formula produces duplicates, shuffle will not remove them. Make the fill distinct first.
- Using it when you need constraints: if the values must satisfy rules or ranges, use a rand array with a unique constraint instead.
- Assuming shuffle sorts: it mixes the order; it does not sort.
The fully random alternative
When the values themselves must be random, not just their order, use a rand array with a unique constraint. We cover that in our guide on how to generate an array of unique random values.
For more randomization control, see randomize vs std::randomize and rand_mode and constraint_mode. More is in our SystemVerilog tutorials.
Frequently asked questions
How do I make a unique array without random and constraints?
Fill each element with a distinct value such as its index, then call the built in shuffle() method on the array. The values stay distinct and the order becomes random, with no constraint solver cost.
What does the shuffle() method do?
shuffle() rearranges the elements of an array into a random order in place. It does not add or remove values, so a distinct set stays distinct.
Is fill and shuffle fully random?
No. The set of values is fixed by how you fill the array; only the order is random. For random values, use a rand array with a unique constraint.
When should I use shuffle instead of a unique constraint?
Use shuffle when you need distinct values and only the order must be random, when you want speed on a large array, or when the value set is already known.
What if my fill formula produces duplicates?
shuffle will not remove duplicates; it only mixes the order. Make sure the fill produces distinct values first, for example by using the index or a spaced formula.
Does shuffle sort the array?
No. shuffle mixes the order randomly. If you need the values sorted, sort the array separately after filling it.


