I have an index array of bits, and weight array with integer values.
I want to random a variable with constraint to be inside rises bits in the index array with the weight that is in the weight array.
Lets say I have 10 boxes and I want to choose one box from the boxes that ready (to sending). but give a weight to the randomization.
so I have:
bit [9:0] ready_boxes;
int [9:0] weight_box ={10,5,5,7,3,5,5,10,10,50};
rand int chosen_box;
For example:
ready_boxes = 10’b10101;
so the chosen_box should be inside [4,2,0] with dist: 0:=50, 2:=10, 4:=5
mentions using unpacked array elements both as weight as well as values .
Even the code given under " iterative weight-age constraint " doesn’t work ( Seems like the 2 authors didn’t verify the code )
bit [9:0] ready_boxes;
bit [9:0] weight_box[$] ={10,5,5,7,3,5,5,10,10,50};
rand int chosen_box[]; // Changed to Unpacked Array !!
rand int val ;
constraint SIZE { chosen_box.size() == weight_box.size() ; }
constraint DIST { foreach( ready_boxes[i] )
{
if ( ready_boxes[i] == 1 )
{
chosen_box[i] dist { i := weight_box[i] } ;
}
}
}
constraint VALUE { val inside { chosen_box } ; }
Via VALUE constraint would chose any value from chosen_box with equal probability .
Each element of chosen_box would be selected a value with appropriate weight
Not 100% sure if this satisfies the weight distribution too . Please correct me if wrong
You need to divide the problem into two pieces. First constrain the chosen_box to the available ready_boxes. Then you need to apply the entire distribution to chosen_box. The values eliminated by the pick_one constraint will be removed from the distribution calculation.
class A;
rand int chosen_box;
bit [9:0] ready_boxes;
int weight_box[9:0] ={10,5,5,7,3,5,5,10,10,50};
constraint pick_one { (ready_boxes >> choosen_box)%2 == 1'b1; }
constraint pick_dist { chosen_box dist {9:=weight_box[9],
8:=weight_box[8],
7:=weight_box[7],
6:=weight_box[6],
5:=weight_box[5],
4:=weight_box[4],
3:=weight_box[3],
2:=weight_box[2],
1:=weight_box[1],
0:=weight_box[0] }; }
endclass
Thanks for your answer.
The number of boxes is greater than 10, it defined with define and can be more than 100.
Is there a way to write the pick_dist constraint with a loop?
Thanks for your answer.
The number of boxes is greater than 10, it defined with define and can be more than 100.
Is there a way to write the pick_dist constraint with a loop?
It would have helped if you said that up front. dist does not work with a variable number of distribution choices. You can handle the weights manually by selecting a random number in the range of the sum of all the weights.
You can try this, I did not test it.
class A;
rand int chosen_box;
bit [9:0] ready_boxes ='b111;
int weight_box[] ={50,5,5,7,3,5,5,10,10,50};
int bounding_box[];
rand int weight;
function new;
bounding_box = new[weight_box.size()];
foreach(weight_box[i])
if (i==0)
bounding_box[0]=0;
else
bounding_box[i]=bounding_box[i-1]+weight_box[i-1];
endfunction
constraint pick_one { (ready_boxes >> chosen_box)%2 == 1'b1; }
constraint weight_dist {
weight inside {[0:weight_box.sum()]};
solve weight before chosen_box;
foreach(weight_box[i])
weight inside {[bounding_box[i]:bounding_box[i]+weight_box[i]]} -> i == chosen_box;
}
endclass