I want to write a constraint so that 10 elements of the array arr have the value of 5, if i call randomize() on an object of the class numberGen, can someone help me with the constraint?
I am able to achieve the above by adding code in post_randomize function but have failed to do so with just a constraint.
class numberGen;
int i,j;
rand bit[7:0] arr[100];
function new();
i = 5; j =10;
endfunction
constraint pick_ij { arr.sum(item) with (int'(item == i)) == j;}
endclass : numberGen
Hi Dave,
“with” is getting really confusing without having any descriptions in LRM.
Can you please help me understanding difference between below 2 statements?
constraint pick_ij { arr.sum(item) with (int’(item == i)) == j;}
Output of 1) is → number of i equal to j. This statement has really nothing to do with sum.
constraint pick_ij { arr.sum(item) with (int’(item)) == j;}
Output of 2) is → sum of arr equal to j.
There is vast difference between output of above 2 statements, but it’s really confusing why and how.
I had tried below code and i am getting an error like this:-
xmsim: *W,SVRNDF (./testbench.sv,39|17): The randomize method call failed. The unique id of the failed randomize call is 0.
Observed simulation time : 0 FS + 0
xmsim: *W,RNDOCS: These constraints contribute to the set of conflicting constraints:
constraint number { count_five(a) == five;} (./testbench.sv,9)
xmsim: *W,RNDOCS: These variables contribute to the set of conflicting constraints:
Var_Name Type Status Current_Value Source
--------------------------------------------------------------------------------------------
a (U8) SOLVED EARLY <array> ./testbench.sv ; line 5
count_five( .a( a ) ) (S32) SOLVED EARLY 0 (0x0) ./testbench.sv ; line 9
'{'h0, 'h0, 'h0, 'h0, 'h0, 'h0, 'h0, 'h0, 'h0, 'h0}
xmsim: *W,RNQUIE: Simulation is complete.
xcelium> exit
TOOL: xrun 20.09-s003: Exiting on Mar 07, 2021 at 02:18:36 EST (total: 00:00:01)
class ab;
rand bit [0:7] a[10]; // the array variable to be constrained
parameter five = 5;
constraint number { count_five(a) == five;} // this constraint tells to keep the count of
// element '5' five times
function int count_five(bit [0:7] a[10]);
for(int i = 0;i<=9; i++)
begin
if(a[i] == 5)
begin
count_five = count_five + 1;//when ever a '5' element occur increment count_five
end
$display(count_five,i);
end
endfunction
endclass
module tb;
ab a1;
initial
begin
a1 = new;
a1.randomize();
$display("%p",a1.a);
end
endmodule
why do we always cast the item to be an int when item refers to the actual array element. In the above example discussed in the thread the array element is an 8bit type which is good to hold values from 0-255.
Are we doing this to hold the sum of all the elements which if done may exceed an 8bit value and we are casting an int only to cover all possible scenarios? Even if this is the case I have seen wrong results when we don’t cast to an int type for item even if dealing with a sum < 255.
Please clarify as it has been very hard to find good info on the same. Thanks again as always. Here is another example which fails without a cast to int
class packet;
rand bit[3:0] add[$];
//constraint address_range { foreach(add[i])add[i] inside {[10:20]};}
constraint s {
add.size inside {[6:8]};
//(add.sum() with (int'(item))) ==7;//works
(add.sum() with (item)) ==7;//fails
}
endclass
module constr_inside;
initial begin
packet pkt;
pkt = new();
$display("------------------------------------");
repeat(1) begin
pkt.randomize();
$display("size = %0d",pkt.add.size);
foreach(pkt.add[i])$display("element i value = %0d",pkt.add[i]);
end
$display("------------------------------------");
end
endmodule
This is because the result of the sum method has the same type as the elements of the array, which in your example is only 4 bits. You need 5 bits to hold the sum of two 4-bit numbers, 6 bits to hold the sum of four 4-bit numbers, and so on. When using a with expression, the result is the same type as that expression.
I tried the following code on edaplayground with all simulators .
class uni_con;
rand int arr[5];
rand int ref_arr[5];
constraint c1 {
foreach(arr[i]){
arr[i] > 0;}
arr.sum(item) with (int'(item) == 10) == 5;
}
Got following error:
testbench.sv(34): randomize() failed due to conflicts between the following constraints:
# testbench.sv(12): c1 { (1'((arr[0] == 10) + (arr[1] == 10) + (arr[2] == 10) + (arr[3] == 10) + (arr[4] == 10)) == 5); }
# Given:
# bit signed [31:0] arr[0]
# bit signed [31:0] arr[1]
# bit signed [31:0] arr[2]
# bit signed [31:0] arr[3]
# bit signed [31:0] arr[4]
# ** Note: (vsim-7106) Use vsim option '-solvefailtestcase[=filename]' to generate a simplified testcase that will reproduce the failure.
# ** Warning: (vsim-7084) No solutions exist which satisfy the specified constraints; randomize() failed.
Hi Dave,
i thought of a solution in a slightly different way, i am trying to check if size of queue returned by find_index method with elements having value 5 should equal 5. I get below error,
what is wrong with my approach?
constraint arr_con_1 {(arr.find_index() with (item == 5)).size() == 5;}
VCS:
Error-[SE] Syntax error
Following verilog source has syntax error :
“testbench.sv”, 14: token is ‘.’
constraint arr_con_1 {(arr.find_index() with (item == 5)).size() == 5;}
What if the values of i and j have to be the minimum and maximum element in the array and they have to occur exactly once. How do we go forward with that, i tried using .max and .min functions inside the constraint, but it doesn’t work.