I have a 2D array:: bit[31:0] reg_a [24], I want to randomise reg_a in a way that all reg_a[i] is mutually exclusive. none of the bits of any two reg_a[i] should be overlapping.
rand bit [31:0] reg_a [24];
if the array was just 2 deep this would be the solution.
foreach(reg_a[i]) begin
std::randomize (reg_a[i]) with {
foreach(reg_a[i][j]){
if(i!=0){
reg_a[i][j] != reg_a[i-1][j];
}
}
};
if we could somehow also add another constraint which is on a counter, which counts $countones(reg_a[i]). like valid = valid+$countones[i] and on this valid if we put a constraint like, valid <32, will it work?
Any other solution is also welcome. Thanks.
So the iterator is here for packed dimension? So effectively this rolls up into
(int'(reg_a[0][j])+int'(reg_a[1][j])...int'(reg_a[23][j])) ==1
Also how is this different from the below constraint?
foreach(reg_a[j]) reg_a.sum() with (int'(item[j])) == 1;
That would not work because the 1st dimension only iterates from 0…23. The 2nd dimention iterates from 0…31. It would leave the packed dimension bits 24…31 unconstrained. However it would work only for the cases where the 2 dimension ranges were the same.
foreach(reg_a[,j]) reg_a.sum() with (int'(item[j])) == 1;
In this case, when you do reg_a.sum() with (int’(item[j])) == 1, you mean the value of the packed dimension to be unique or in other words it should not be same as any other element in the array correct?
No, it means at most one bit can be set in the particular [j] index of the packed dimension for all unpacked elements. Unique would only work if there were 2 unpacked elements.
Hi dave,
I tried the code that u suggested, I get an error msg suggesting ‘item’ has not been declared yet.
“Error-[IND] Identifier not declared
randomise.sv, 13
Identifier ‘item’ has not been declared yet.”
class my_trans;
bit[31:0] reg_a [24];
constraint non_overlapping {
foreach(reg_a[,j]) reg_a.sum() with (int'(item[j])) == 1;
};
endclass
module ab;
my_trans trans_h= new ;
initial
begin
trans_h.randomize();
end
endmodule
it is not picking up the coloumn, when I only put item there it does expand, but putting item[j] causes a compilation error.
I believe you have run into a tool bug. The following code works on 4 SystemVerilog simulation tools on www.edaplayground.com.
class my_trans;
rand bit[31:0] reg_a [24];
function void post_randomize;
foreach(reg_a[,j]) $display(reg_a.sum() with (int'(item[j])));
endfunction
endclass
module ab;
my_trans trans_h= new ;
initial assert(trans_h.randomize());
endmodule
This Mentor/Siemens EDA sponsored public forum is not for discussing tool specific usage or issues. Please contact your tool vendor directly for support.
In reply to 100rabhh:
I believe you have run into a tool bug. The following code works on 4 SystemVerilog simulation tools on www.edaplayground.com.
class my_trans;
rand bit[31:0] reg_a [24];
function void post_randomize;
foreach(reg_a[,j]) $display(reg_a.sum() with (int'(item[j])));
endfunction
endclass
module ab;
my_trans trans_h= new ;
initial assert(trans_h.randomize());
endmodule
This Mentor/Siemens EDA sponsored public forum is not for discussing tool specific usage or issues. Please contact your tool vendor directly for support.
Hi Dave,
2 follow-up questions:
Why are you doing it in post_randomize()? why not as a constraint by itself?
I do see your code to also have overlapping bits set. Pasted the snapshot running your code. Added display statement in addition.
class my_trans;
rand bit[31:0] reg_a [24];
/*
constraint c_no_overlap {
foreach(reg_a[,j]) {
reg_a.sum() with (int'(item[j]));
}
}*/
function void post_randomize;
foreach(reg_a[,j]) $display(reg_a.sum() with (int'(item[j])));
endfunction
endclass
module ab;
my_trans trans_h= new ;
initial begin
assert(trans_h.randomize());
foreach(trans_h.reg_a[i])
$display("%b",trans_h.reg_a[i]);
end
endmodule