2
\$\begingroup\$

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 os 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 -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 QuestaSim 10.4c simulation tool.

\$\endgroup\$
2
\$\begingroup\$

The problem is in the foreach syntax, it should be:

foreach PhyRB[,i] PhyRB[0][i] < ResBlks;
| improve this answer | |
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.