How to constrain 2 dynamic arrays to related to each other?

Hi,

Can someone help to constrain 2 dynamic arrays to get even distribution?

  1. C0,C1 evenly distribute
  2. E0,E1,E2,E3 evenly distribute
  3. En in C0 has same distribution as En in C1

One possible solution:
Cs: C0,C0,C1,C1,C0,C1,C1,C0 // num of C0 = num of C1
Es: E0,E1,E1,E0,E2,E3,E2,E3 // number of En is same
// The index of C0 include E0,E1,E2,E3
// The index of C1 include E0,E1,E2,E3

The code below somehow give a solution as below is not intention.

Cs:‘{C1, C0, C0, C0, C1, C0, C1, C1}
Es:’{E1, E3, E1, E3, E2, E2, E0, E0} //against 3 b/c E3,E1,E3,E2 under C0, ideally should be E3,E1,E0,E2


typedef enum bit[0:0] {C0=0, C1} c_typ_e;          //c_typ_e is fixed to C{0,1}
typedef enum bit[1:0] {E0=0, E1, E2, E3} e_typ_e;  //e_typ_e is fixed to E{0,1,2,3}

class A;
   
   rand c_typ_e Cs[];
   rand e_typ_e Es[];
   rand shortint arr_sz;

   //arr_sz mostly are 8*n(n>0), sometimes always could be 2*n(such as 2,4,6)
   constraint arr_sz_cs {
      arr_sz == 8;
   }

   constraint cs_cs {
      Cs.size == arr_sz;
   }

   constraint cs_val {
      if(arr_sz % 2 == 0) {
        Cs.sum with(int'(item==C0)) == arr_sz/2;
        Cs.sum with(int'(item==C1)) == arr_sz/2;
      }
   }
   
   constraint es_cs {
      Es.size == arr_sz;
   }

   constraint es_val {
      if(arr_sz % 4 == 0) {
        Es.sum with(int'(item==E0)) == arr_sz/4;
        Es.sum with(int'(item==E1)) == arr_sz/4;
        Es.sum with(int'(item==E2)) == arr_sz/4;
        Es.sum with(int'(item==E3)) == arr_sz/4;
      }
   }

   function void randomize_it();
      this.randomize();
      $display("Cs:%p",Cs);
      $display("Es:%p",Es);
   endfunction // randomize_it
   
endclass // A


module tb;

   A a;

   initial begin
      a = new();
      a.randomize_it();
   end

endmodule // tb

In reply to mlsxdx:
Some questions:

Are the number of names in c_typ_e and e_typ_e fixed at 2 and 4 respectively?
Is arr_sz constrained to the product of this numbers, 2*4 = 8?

If that’s not the case, then you need to express your #3 requirement better.

In reply to dave_59:

In reply to mlsxdx:
Some questions:
Are the number of names in c_typ_e and e_typ_e fixed at 2 and 4 respectively?
Is arr_sz constrained to the product of this numbers, 2*4 = 8?
If that’s not the case, then you need to express your #3 requirement better.

Not fixed, mostly it will be 8n, but some cases, it could be 2n(n>0)

In reply to dave_59:

Dave, thanks for your reply.
I have updated the code and comments after the variable declaration and constraints.

  1. the number of names in c_typ_e and e_typ_e fixed at 2 and 4 respectively
  2. arr_sz mostly is 8n, also could be 2n (such as 2,4,6), if 2*n, C requires to evenly distributed, E not required.

In reply to mlsxdx:

Still waiting for the response. Can somebody help on this?

In reply to mlsxdx:

your requirement is still not very clear to me.
btw, try this idea

rand c_typ_e Cs;
rand shortint arr_sz;
rand e_typ_e E_set; // e_typ_e distribution set in C0 and C1
e_typ_e Es;

  1. constraint block to solve Cs (size is 8) and E_set (size is 4) first

  2. post_randomize() for final Es (size 8)
    based on Cs and E_set constrainted results

    int C0_idx_q[] = Cs.find_index with (item == C0); int C1_idx_q[] = Cs.find_index with (item == C1);

    e.g. Cs: C0,C0,C1,C1,C0,C1,C1,C0 // num of C0 = num of C1
    C0_idx_q = {0,1,4,7}
    C1_idx_q = {2,3,5,6}
    E_set= {E0, E1, E2, E3}

    foreach (C0_idx_q[i]) Es[C0_idx_q[i]] = E_set[i];
    E_set.shuffle();
    foreacj (C1_idx_q[i]) Es[C1_idx_q[i]] = E_set[i];

I guess nobody understands your 3rd requirement.

In reply to mlsxdx:

In reply to mlsxdx:
Still waiting for the response. Can somebody help on this?