In the following code, I attempt to randomize the transaction which contains a dynamic array 'PhyRB', with the constraint that each element in the array is less than 'ResBlks' value. Please note that both 'PhyRB' array and 'ResBlks' are of unsigned (bit [6:0]
) type:
module tb;
typedef enum logic {Type2=0, Sorted=1} PhyRBAlloc_t; // RBs allocation type
class Txn;
rand bit [6:0] ResBlks; // Number of resource blocks (NRB)
rand PhyRBAlloc_t PhyRBAllocType; // Physical RB allocation type
rand bit [6:0] PhyRB[2][]; // Physical RB mapping
// Array of unique values
constraint ArrSize {
PhyRB[0].size() > 0;
PhyRB[0].size() <= ResBlks;
PhyRB[1].size() == PhyRB[0].size();
}
constraint vals {
foreach(PhyRB[0][i]) PhyRB[0][i] < ResBlks;
if(PhyRBAllocType == Type2) {
foreach(PhyRB[1][i]) PhyRB[1][i] < ResBlks;
}
unique { PhyRB[0] };
unique { PhyRB[1] } ;
}
constraint ResBlksConstraint {
ResBlks inside {6,15,25,50,75,100};
}
function void post_randomize;
if(PhyRBAllocType == Sorted) begin
PhyRB[0].sort();
PhyRB[1] = PhyRB[0];
end
endfunction
endclass
initial begin
Txn txn;
txn = new;
txn.ResBlks = 50;
txn.ResBlks.rand_mode(0);
if(!txn.randomize())
$error("txn rand failed");
if(!txn.randomize(PhyRBAllocType))
$error("PhyRBAllocType rand failed");
if(!txn.randomize(PhyRB))
$error("PhyRB rand failed");
$info($sformatf("UsedRBNum: %0d", txn.PhyRB[0].size()));
$info($sformatf("RB allocation: %s", txn.PhyRBAllocType.name()));
$info($sformatf("PhyRB[0]: %0p", txn.PhyRB[0]));
$info($sformatf("PhyRB[1]: %0p", txn.PhyRB[1]));
end
endmodule
The randomization reports to be successful, yet the values of 'PhyRB' elements do not meet the constraint. Although 'ResBlks' value is 50, yet some elements have values greater than 50:
# ** Info: PhyRB[0]: 3 4 8 9 12 17 19 21 22 25 29 36 38 45 46 47 48 61
68 71 76 81 86 91 97 99 101 104 115 124 126
# ** Info: PhyRB[1]: 3 4 8 9 12 17 19 21 22 25 29 36 38 45 46 47 48 61
68 71 76 81 86 91 97 99 101 104 115 124 126
I tried to run QuestaSim with the -solvedebug
option, so it reports the following:
# Start class::randomize#1 @ 0ns: t2.sv(44)
# -> type=Txn, randstate=MSd1ef12ef321778f006bc6d297504e6e2
#
# Begin RandSet 1
# Random Variables:
# bit signed [31:0] PhyRB[1].size
# bit signed [31:0] PhyRB[0].size
# Constraints:
# t2.sv(12): ArrSize { (PhyRB[0].size > 0); }
# t2.sv(13): ArrSize { (PhyRB[0].size <= ResBlks); }
# t2.sv(14): ArrSize { (PhyRB[1].size == PhyRB[0].size); }
# t2.sv(8): (PhyRB[1].size >= 0);
# t2.sv(8): (PhyRB[0].size >= 0);
# * Solving RandSet 1 with ACT engine
# Solved: PhyRB[0].size = 29
# Solved: PhyRB[1].size = 29
# End RandSet 1
#
# Begin RandSet 2
# Random Variables:
# bit [6:0] PhyRB[0][0]
# bit [6:0] PhyRB[0][1]
# bit [6:0] PhyRB[0][2]
# bit [6:0] PhyRB[0][3]
# bit [6:0] PhyRB[0][4]
# bit [6:0] PhyRB[0][5]
# bit [6:0] PhyRB[0][6]
# bit [6:0] PhyRB[0][7]
# bit [6:0] PhyRB[0][8]
# bit [6:0] PhyRB[0][9]
# bit [6:0] PhyRB[0][10]
# bit [6:0] PhyRB[0][11]
# bit [6:0] PhyRB[0][12]
# bit [6:0] PhyRB[0][13]
# bit [6:0] PhyRB[0][14]
# bit [6:0] PhyRB[0][15]
# bit [6:0] PhyRB[0][16]
# bit [6:0] PhyRB[0][17]
# bit [6:0] PhyRB[0][18]
# bit [6:0] PhyRB[0][19]
# bit [6:0] PhyRB[0][20]
# bit [6:0] PhyRB[0][21]
# bit [6:0] PhyRB[0][22]
# bit [6:0] PhyRB[0][23]
# bit [6:0] PhyRB[0][24]
# bit [6:0] PhyRB[0][25]
# bit [6:0] PhyRB[0][26]
# bit [6:0] PhyRB[0][28]
# bit [6:0] PhyRB[0][27]
# Constraints:
# t2.sv(21): vals { unique {PhyRB[0]}; }
# t2.sv(17): vals { (PhyRB[0][0] < ResBlks); }
# t2.sv(17): vals { (PhyRB[0][1] < ResBlks); }
# t2.sv(17): vals { (PhyRB[0][2] < ResBlks); }
# t2.sv(17): vals { (PhyRB[0][3] < ResBlks); }
# t2.sv(17): vals { (PhyRB[0][4] < ResBlks); }
# t2.sv(17): vals { (PhyRB[0][5] < ResBlks); }
# t2.sv(17): vals { (PhyRB[0][6] < ResBlks); }
# * Solving RandSet 2 with ACT engine
# Solved: PhyRB[0][11] = 7'h21
# Solved: PhyRB[0][15] = 7'h64
# Solved: PhyRB[0][1] = 7'h1d
# Solved: PhyRB[0][28] = 7'h26
# Solved: PhyRB[0][22] = 7'h48
# Solved: PhyRB[0][26] = 7'h66
# Solved: PhyRB[0][17] = 7'h3a
# Solved: PhyRB[0][9] = 7'h41
# Solved: PhyRB[0][14] = 7'h54
# Solved: PhyRB[0][27] = 7'h28
# Solved: PhyRB[0][16] = 7'h35
# Solved: PhyRB[0][5] = 7'h2b
# Solved: PhyRB[0][18] = 7'h27
# Solved: PhyRB[0][24] = 7'h42
# Solved: PhyRB[0][20] = 7'h00
# Solved: PhyRB[0][0] = 7'h24
# Solved: PhyRB[0][4] = 7'h2c
# Solved: PhyRB[0][19] = 7'h56
# Solved: PhyRB[0][8] = 7'h70
# Solved: PhyRB[0][6] = 7'h12
# Solved: PhyRB[0][21] = 7'h0c
# Solved: PhyRB[0][23] = 7'h7c
# Solved: PhyRB[0][25] = 7'h71
# Solved: PhyRB[0][10] = 7'h6e
# Solved: PhyRB[0][7] = 7'h3e
# Solved: PhyRB[0][3] = 7'h1f
# Solved: PhyRB[0][12] = 7'h11
# Solved: PhyRB[0][13] = 7'h03
# Solved: PhyRB[0][2] = 7'h09
# End RandSet 2
#
# Begin RandSet 3
# Random Variables:
# bit [6:0] PhyRB[1][6]
# reg [0:0] PhyRBAllocType
# bit [6:0] PhyRB[1][5]
# bit [6:0] PhyRB[1][4]
# bit [6:0] PhyRB[1][3]
# bit [6:0] PhyRB[1][2]
# bit [6:0] PhyRB[1][1]
# bit [6:0] PhyRB[1][0]
# bit [6:0] PhyRB[1][7]
# bit [6:0] PhyRB[1][8]
# bit [6:0] PhyRB[1][9]
# bit [6:0] PhyRB[1][10]
# bit [6:0] PhyRB[1][11]
# bit [6:0] PhyRB[1][12]
# bit [6:0] PhyRB[1][13]
# bit [6:0] PhyRB[1][14]
# bit [6:0] PhyRB[1][15]
# bit [6:0] PhyRB[1][16]
# bit [6:0] PhyRB[1][17]
# bit [6:0] PhyRB[1][18]
# bit [6:0] PhyRB[1][19]
# bit [6:0] PhyRB[1][20]
# bit [6:0] PhyRB[1][21]
# bit [6:0] PhyRB[1][22]
# bit [6:0] PhyRB[1][23]
# bit [6:0] PhyRB[1][24]
# bit [6:0] PhyRB[1][25]
# bit [6:0] PhyRB[1][26]
# bit [6:0] PhyRB[1][28]
# bit [6:0] PhyRB[1][27]
# Constraints:
# t2.sv(22): vals { unique {PhyRB[1]}; }
# t2.sv(7): (PhyRBAllocType inside { [Type2:Sorted] });
# t2.sv(19): vals { if ((~PhyRBAllocType)) {(PhyRB[1][6] < ResBlks);} }
# t2.sv(19): vals { if ((~PhyRBAllocType)) {(PhyRB[1][5] < ResBlks);} }
# t2.sv(19): vals { if ((~PhyRBAllocType)) {(PhyRB[1][4] < ResBlks);} }
# t2.sv(19): vals { if ((~PhyRBAllocType)) {(PhyRB[1][3] < ResBlks);} }
# t2.sv(19): vals { if ((~PhyRBAllocType)) {(PhyRB[1][2] < ResBlks);} }
# t2.sv(19): vals { if ((~PhyRBAllocType)) {(PhyRB[1][1] < ResBlks);} }
# t2.sv(19): vals { if ((~PhyRBAllocType)) {(PhyRB[1][0] < ResBlks);} }
# * Solving RandSet 3 with ACT engine
# Solved: PhyRBAllocType = Sorted
# Solved: PhyRB[1][12] = 7'h66
# Solved: PhyRB[1][15] = 7'h2b
# Solved: PhyRB[1][19] = 7'h19
# Solved: PhyRB[1][3] = 7'h11
# Solved: PhyRB[1][13] = 7'h75
# Solved: PhyRB[1][27] = 7'h4f
# Solved: PhyRB[1][0] = 7'h3e
# Solved: PhyRB[1][21] = 7'h48
# Solved: PhyRB[1][9] = 7'h46
# Solved: PhyRB[1][10] = 7'h2c
# Solved: PhyRB[1][11] = 7'h29
# Solved: PhyRB[1][24] = 7'h45
# Solved: PhyRB[1][7] = 7'h72
# Solved: PhyRB[1][8] = 7'h4e
# Solved: PhyRB[1][26] = 7'h60
# Solved: PhyRB[1][2] = 7'h43
# Solved: PhyRB[1][14] = 7'h09
# Solved: PhyRB[1][20] = 7'h0d
# Solved: PhyRB[1][4] = 7'h5d
# Solved: PhyRB[1][28] = 7'h69
# Solved: PhyRB[1][5] = 7'h6a
# Solved: PhyRB[1][6] = 7'h39
# Solved: PhyRB[1][1] = 7'h28
# Solved: PhyRB[1][18] = 7'h12
# Solved: PhyRB[1][17] = 7'h79
# Solved: PhyRB[1][25] = 7'h15
# Solved: PhyRB[1][23] = 7'h7c
# Solved: PhyRB[1][22] = 7'h44
# Solved: PhyRB[1][16] = 7'h6e
# End RandSet 3
#
# v-- executing $rand.post_randomize() [type=Txn: t2.sv(29)]
# --^ $rand.post_randomize() done
#
# End class::randomize#1 @ 0ns: t2.sv(44)
# -> result=1
#
# Start class::randomize#2 @ 0ns: t2.sv(47)
# -> type=Txn, randstate=MS321778f0420665ba7797d1d1e04a9cc9
#
# Executing function:
# t2.sv(14): function()
#
# Executing function:
# t2.sv(14): function()
#
# Executing function:
# t2.sv(13): function()
#
# Executing function:
# t2.sv(12): function()
#
# Begin RandSet 4
# Random Variables:
# reg [0:0] PhyRBAllocType
# Constraints:
# t2.sv(7): (PhyRBAllocType inside { [Type2:Sorted] });
# * Solving RandSet 4 with Limit engine
# Solved: PhyRBAllocType = Sorted
# End RandSet 4
#
# v-- executing $rand.post_randomize() [type=Txn: t2.sv(29)]
# --^ $rand.post_randomize() done
#
# End class::randomize#2 @ 0ns: t2.sv(47)
# -> result=1
#
# Start class::randomize#3 @ 0ns: t2.sv(49)
# -> type=Txn, randstate=MS420665ba7797d1d19a9755ad98e48700
#
# Begin RandSet 5
# Random Variables:
# bit signed [31:0] PhyRB[1].size
# bit signed [31:0] PhyRB[0].size
# Constraints:
# t2.sv(12): ArrSize { (PhyRB[0].size > 0); }
# t2.sv(13): ArrSize { (PhyRB[0].size <= ResBlks); }
# t2.sv(14): ArrSize { (PhyRB[1].size == PhyRB[0].size); }
# t2.sv(8): (PhyRB[1].size >= 0);
# t2.sv(8): (PhyRB[0].size >= 0);
# * Solving RandSet 5 with ACT engine
# Solved: PhyRB[0].size = 31
# Solved: PhyRB[1].size = 31
# End RandSet 5
#
# Begin RandSet 6
# Random Variables:
# bit [6:0] PhyRB[0][0]
# bit [6:0] PhyRB[0][1]
# bit [6:0] PhyRB[0][2]
# bit [6:0] PhyRB[0][3]
# bit [6:0] PhyRB[0][4]
# bit [6:0] PhyRB[0][5]
# bit [6:0] PhyRB[0][6]
# bit [6:0] PhyRB[0][7]
# bit [6:0] PhyRB[0][8]
# bit [6:0] PhyRB[0][9]
# bit [6:0] PhyRB[0][10]
# bit [6:0] PhyRB[0][11]
# bit [6:0] PhyRB[0][12]
# bit [6:0] PhyRB[0][13]
# bit [6:0] PhyRB[0][14]
# bit [6:0] PhyRB[0][15]
# bit [6:0] PhyRB[0][16]
# bit [6:0] PhyRB[0][17]
# bit [6:0] PhyRB[0][18]
# bit [6:0] PhyRB[0][19]
# bit [6:0] PhyRB[0][20]
# bit [6:0] PhyRB[0][21]
# bit [6:0] PhyRB[0][22]
# bit [6:0] PhyRB[0][23]
# bit [6:0] PhyRB[0][24]
# bit [6:0] PhyRB[0][25]
# bit [6:0] PhyRB[0][26]
# bit [6:0] PhyRB[0][27]
# bit [6:0] PhyRB[0][28]
# bit [6:0] PhyRB[0][30]
# bit [6:0] PhyRB[0][29]
# Constraints:
# t2.sv(21): vals { unique {PhyRB[0]}; }
# t2.sv(17): vals { (PhyRB[0][0] < ResBlks); }
# t2.sv(17): vals { (PhyRB[0][1] < ResBlks); }
# t2.sv(17): vals { (PhyRB[0][2] < ResBlks); }
# t2.sv(17): vals { (PhyRB[0][3] < ResBlks); }
# t2.sv(17): vals { (PhyRB[0][4] < ResBlks); }
# t2.sv(17): vals { (PhyRB[0][5] < ResBlks); }
# t2.sv(17): vals { (PhyRB[0][6] < ResBlks); }
# * Solving RandSet 6 with ACT engine
# Solved: PhyRB[0][20] = 7'h47
# Solved: PhyRB[0][18] = 7'h24
# Solved: PhyRB[0][12] = 7'h44
# Solved: PhyRB[0][1] = 7'h2e
# Solved: PhyRB[0][17] = 7'h65
# Solved: PhyRB[0][3] = 7'h16
# Solved: PhyRB[0][27] = 7'h2f
# Solved: PhyRB[0][14] = 7'h1d
# Solved: PhyRB[0][15] = 7'h4c
# Solved: PhyRB[0][30] = 7'h08
# Solved: PhyRB[0][22] = 7'h15
# Solved: PhyRB[0][9] = 7'h04
# Solved: PhyRB[0][21] = 7'h61
# Solved: PhyRB[0][23] = 7'h09
# Solved: PhyRB[0][26] = 7'h56
# Solved: PhyRB[0][25] = 7'h5b
# Solved: PhyRB[0][28] = 7'h7e
# Solved: PhyRB[0][2] = 7'h19
# Solved: PhyRB[0][7] = 7'h63
# Solved: PhyRB[0][13] = 7'h73
# Solved: PhyRB[0][16] = 7'h13
# Solved: PhyRB[0][6] = 7'h2d
# Solved: PhyRB[0][8] = 7'h3d
# Solved: PhyRB[0][24] = 7'h7c
# Solved: PhyRB[0][11] = 7'h51
# Solved: PhyRB[0][4] = 7'h03
# Solved: PhyRB[0][29] = 7'h26
# Solved: PhyRB[0][10] = 7'h30
# Solved: PhyRB[0][0] = 7'h0c
# Solved: PhyRB[0][19] = 7'h68
# Solved: PhyRB[0][5] = 7'h11
# End RandSet 6
#
# Begin RandSet 7
# Random Variables:
# bit [6:0] PhyRB[1][0]
# bit [6:0] PhyRB[1][1]
# bit [6:0] PhyRB[1][2]
# bit [6:0] PhyRB[1][3]
# bit [6:0] PhyRB[1][4]
# bit [6:0] PhyRB[1][5]
# bit [6:0] PhyRB[1][6]
# bit [6:0] PhyRB[1][7]
# bit [6:0] PhyRB[1][8]
# bit [6:0] PhyRB[1][9]
# bit [6:0] PhyRB[1][10]
# bit [6:0] PhyRB[1][11]
# bit [6:0] PhyRB[1][12]
# bit [6:0] PhyRB[1][13]
# bit [6:0] PhyRB[1][14]
# bit [6:0] PhyRB[1][15]
# bit [6:0] PhyRB[1][16]
# bit [6:0] PhyRB[1][17]
# bit [6:0] PhyRB[1][18]
# bit [6:0] PhyRB[1][19]
# bit [6:0] PhyRB[1][20]
# bit [6:0] PhyRB[1][21]
# bit [6:0] PhyRB[1][22]
# bit [6:0] PhyRB[1][23]
# bit [6:0] PhyRB[1][24]
# bit [6:0] PhyRB[1][25]
# bit [6:0] PhyRB[1][26]
# bit [6:0] PhyRB[1][27]
# bit [6:0] PhyRB[1][28]
# bit [6:0] PhyRB[1][30]
# bit [6:0] PhyRB[1][29]
# Constraints:
# t2.sv(22): vals { unique {PhyRB[1]}; }
# * Solving RandSet 7 with ACT engine
# Solved: PhyRB[1][9] = 7'h12
# Solved: PhyRB[1][28] = 7'h59
# Solved: PhyRB[1][14] = 7'h2d
# Solved: PhyRB[1][3] = 7'h27
# Solved: PhyRB[1][11] = 7'h2b
# Solved: PhyRB[1][29] = 7'h17
# Solved: PhyRB[1][18] = 7'h45
# Solved: PhyRB[1][26] = 7'h0a
# Solved: PhyRB[1][27] = 7'h76
# Solved: PhyRB[1][20] = 7'h5c
# Solved: PhyRB[1][10] = 7'h28
# Solved: PhyRB[1][12] = 7'h4f
# Solved: PhyRB[1][6] = 7'h13
# Solved: PhyRB[1][8] = 7'h66
# Solved: PhyRB[1][4] = 7'h18
# Solved: PhyRB[1][7] = 7'h1e
# Solved: PhyRB[1][30] = 7'h14
# Solved: PhyRB[1][23] = 7'h44
# Solved: PhyRB[1][0] = 7'h47
# Solved: PhyRB[1][13] = 7'h50
# Solved: PhyRB[1][22] = 7'h3c
# Solved: PhyRB[1][25] = 7'h16
# Solved: PhyRB[1][24] = 7'h5a
# Solved: PhyRB[1][21] = 7'h24
# Solved: PhyRB[1][16] = 7'h33
# Solved: PhyRB[1][5] = 7'h46
# Solved: PhyRB[1][19] = 7'h56
# Solved: PhyRB[1][2] = 7'h4c
# Solved: PhyRB[1][17] = 7'h0c
# Solved: PhyRB[1][15] = 7'h5d
# Solved: PhyRB[1][1] = 7'h08
# End RandSet 7
#
# Unconstrained Random Variables:
# Solved: PhyRB[0][?] = 7'h75
# Solved: PhyRB[0][?] = 7'h39
# Solved: PhyRB[0][?] = 7'h30
# Solved: PhyRB[0][?] = 7'h6c
# Solved: PhyRB[0][?] = 7'h74
# Solved: PhyRB[0][?] = 7'h09
# Solved: PhyRB[0][?] = 7'h1a
# Solved: PhyRB[0][?] = 7'h3d
# Solved: PhyRB[0][?] = 7'h3c
# Solved: PhyRB[0][?] = 7'h71
# Solved: PhyRB[0][?] = 7'h43
# Solved: PhyRB[0][?] = 7'h01
# Solved: PhyRB[0][?] = 7'h34
# Solved: PhyRB[0][?] = 7'h76
# Solved: PhyRB[0][?] = 7'h68
# Solved: PhyRB[0][?] = 7'h6a
# Solved: PhyRB[0][?] = 7'h74
# Solved: PhyRB[0][?] = 7'h5c
# Solved: PhyRB[0][?] = 7'h17
# Solved: PhyRB[0][?] = 7'h12
# Solved: PhyRB[0][?] = 7'h03
# Solved: PhyRB[0][?] = 7'h05
# Solved: PhyRB[0][?] = 7'h2b
# Solved: PhyRB[0][?] = 7'h44
# Solved: PhyRB[0][?] = 7'h78
# Solved: PhyRB[0][?] = 7'h1f
# Solved: PhyRB[0][?] = 7'h15
# Solved: PhyRB[0][?] = 7'h2d
# Solved: PhyRB[0][?] = 7'h22
# Solved: PhyRB[1][?] = 7'h4c
# Solved: PhyRB[1][?] = 7'h33
# Solved: PhyRB[1][?] = 7'h37
# Solved: PhyRB[1][?] = 7'h11
# Solved: PhyRB[1][?] = 7'h2e
# Solved: PhyRB[1][?] = 7'h72
# Solved: PhyRB[1][?] = 7'h06
# Solved: PhyRB[1][?] = 7'h22
# Solved: PhyRB[1][?] = 7'h53
# Solved: PhyRB[1][?] = 7'h5b
# Solved: PhyRB[1][?] = 7'h66
# Solved: PhyRB[1][?] = 7'h33
# Solved: PhyRB[1][?] = 7'h77
# Solved: PhyRB[1][?] = 7'h26
# Solved: PhyRB[1][?] = 7'h00
# Solved: PhyRB[1][?] = 7'h0f
# Solved: PhyRB[1][?] = 7'h7e
# Solved: PhyRB[1][?] = 7'h65
# Solved: PhyRB[1][?] = 7'h57
# Solved: PhyRB[1][?] = 7'h26
# Solved: PhyRB[1][?] = 7'h3b
# Solved: PhyRB[1][?] = 7'h36
# Solved: PhyRB[1][?] = 7'h74
# Solved: PhyRB[1][?] = 7'h57
# Solved: PhyRB[1][?] = 7'h67
# Solved: PhyRB[1][?] = 7'h35
# Solved: PhyRB[1][?] = 7'h7a
# Solved: PhyRB[1][?] = 7'h31
# Solved: PhyRB[1][?] = 7'h00
#
# v-- executing $rand.post_randomize() [type=Txn: t2.sv(29)]
# --^ $rand.post_randomize() done
#
# End class::randomize#3 @ 0ns: t2.sv(49)
# -> result=1
I am running the QuestaSim 10.4c simulation tool.