Repeated randomization of dynamic array fails after a few iterations

Folks,

I have been beating my head over this for over a day now and am just exhausted looking at this code. What I basically want to do is to split a number into 1:63 chunks. This is what I am doing.

int unsigned pld_size;

  // var: sample_size
  rand int unsigned sample_size[];
  constraint pc_rgx_stim_flow_base_sample_size_cnstr {
    sample_size.size() >= 1;
    sample_size.size() <= 63;
    sample_size.sum() == pld_size;
    foreach (sample_size[i]) {
      sample_size[i] >= 1;
      sample_size[i] <= pld_size;
    }
  }

  function gen_payload_val();
    for (int i=0;i<20;i++) begin
     pld_size = $urandom_range(10,100);
     randomize(sample_size);
    end
  endfunction

I ensured that
(1) Everything is unsigned and no negative numbers screw up the math
(2) I also made sure that none of the individual elements of the array end up being negative numbers
(3) To bound the sum(), I made sure that the sum does not exceed the pld_size too

Here is what I observe - For the first 5 or 6 iterations(sometimes it fails after the 8th iteration), things are fine. But after a few iterations, the randomization fails and I get the following :

ncsim: *W,SVRNDF (base.sv,156|12): The randomize method call failed. The unique id of the failed randomize call is 4569.
Observed simulation time : 403501 PS + 16
ncsim: *W,RNDOCS: These constraints contribute to the set of conflicting constraints:

sample_size.sum() == pld_size; (base.sv,217)

ncsim: *W,RNDOCS: These variables contribute to the set of conflicting constraints:

state variables:
sample_size[1] (1) base.sv, 369] rand_mode(0)
pld_size (10) [base.sv, 365]

I don’t understand why there is a rand_mode(0) on the sample_size. I am not turning off any constraints anywhere. So what is wrong with my constraints.

In reply to DVJoe:

If an array is constrained by both size constraints and iterative constraints, the size constraints are solved first and the iterative constraints next. As a result of this implicit ordering between size constraints and iterative constraints, the size method shall be treated as a state variable within the foreach block of the corresponding array. This implicit ordering can cause the solver to fail in some situations.

Your constraint is failing because pld_size is a state variable and sample_size.size() is picked before any other constraints get considered. If the size() is smaller than pld_size, the sum() constraint cannot be met. So make pld_size an random variable

class C;
   rand int pld_size;
 
  // var: sample_size
   rand int unsigned sample_size[];
   constraint pc {pld_size inside {[10:100]};}

In reply to dave_59:

Thanks Dave. I have a follow up question with making pld_size a rand variable. Currently I am computing pld_size based on the size of a queue. So to prevent pld_size from becoming a state variable, I need to do the following correct ?

randomize(pld_size) with {pld_size == pld_q.size();};

and NOT do this

pld_size = pld_q.size();

Is my understanding correct

In reply to DVJoe:

You need to call randomize() with no arguments so that all the class variables are randomized together, not one at a time.

In reply to dave_59:

Thanks Dave. That was basically the bane of my issues.