I am trying to populate unique values into a 2d fixed-size array without using the unique keyword
Can you please help me understand why would my following code not give me unique values?
class packet;
rand bit [3:0] array[4][4];
int i,j,a,b;
constraint unique_elements {foreach (array[i][j]) {
foreach (array[a][b]){
(!(a==i && b==j)) -> array[a][b] != array [i][j];
}
}}
function void print();
for (int i = 0; i < 4; i++) begin
$display("\n");
for (int j = 0; j < 4; j++) begin
$write("[%0d]\t",array[i][j]);
end
end
endfunction
endclass
module test;
packet p;
initial begin
p=new();
p.randomize;
p.print();
end
endmodule
1 Like
In reply to sfenil1804:
The foreach loop you are using is not legal syntax for the very problem you are running into. You are only allowed one set of [] brackets in a foreach loop, and the variables inside the brackets are local iterator variables. In your case, the first set of brackets are being treated as a state variable, whose value is always 0. Many people have incorrectly written code like
foreach(array[A]) {
...
foreach(array[A][B]) {...}
}
expecting the inner foreach loop to only iterate over [B] while the outer foreach loop iterates over [A]. The correct and legal way of writing this is
foreach(array[A]) {
...
foreach(array[,B]) {...}
}
and the correct and legal way of writing your constraint is
//int i,j,a,b; no need to. declare here as they are implicitly declared by foreach
constraint unique_elements {foreach (array[i,j]) {
foreach (array[a,b]){
(!(a==i && b==j)) -> array[a][b] != array [i][j];
}
}}
In reply to dave_59:
Thank you, I understood the mistake.
It works as I intended now!
In reply to sfenil1804:
Could you please explain whats happening in the two foreach loops ? why do we need the condition !(a==i && b==j) ? is the first foreach loop creating a randomized matrix and the second matrix trying to make the elements unique by iterating the first one ?
constraint unique_elements {foreach (array[i][j]) {
foreach (array[a][b]){
(!(a==i && b==j)) -> array[a][b] != array [i][j];
}
}}
In reply to diptishe:
The two for each loops are both iterating over the same array so that every element gets compared with every other element. The !(a==i && b==j) implication prevents elements from being compared with themselves