Constraint elements in a 2D array to a particular number a particular number of times

I have a 2d array, I want to constraint the elements in a way that the total no of times an element appears can be constrained to a particular value.
For eg: if we have a variable like rand bit [5:0] temp_id [4][4], out of the 16 elements in this 2d array I want an element =8 to appear 4 times, the element can appear 4 times in a row or 4 times in a column, it can appear diagonally, or in any random order.

class problem7;
  rand bit [5:0] temp_id [][];

 constraint size {
  temp_id.size() ==4;
 foreach(temp_id[i]) temp_id[i].size() == 4;
}
// constraint for 8 to appear 4 times in this 2d array.
endclass
module check;
 problem7 p7;
  initial 
  begin
  p7 = new();
  p7.randomize();
 foreach(p7.temp_id[i]) $display("%0p", temp_id[i]);
 end
endmodule.

Try this along with some corrections to your existing code:

class problem7;
  rand bit [5:0] temp_id [][];
 constraint size {
  temp_id.size() ==4;
   foreach(temp_id[i]) temp_id[i].size() == 4;
}
// constraint for 8 to appear 4 times in this 2d array.
  constraint element_count {
    temp_id.sum(D1) with (D1.sum(D2) with (int'(D2 == 8) ) ) == 4;
}
endclass
module check;
  problem7 p7 = new();;
  initial 
  begin
    assert(p7.randomize());
    foreach(p7.temp_id[i]) $display("%0p", p7.temp_id[i]);
 end
endmodule

Thanks Dave, this worked. Can you tell us where can we find details about sum() operators for cases like these? Or something that we can go over, which would be helpful. I went through Chris spears and some part of LRM, could not find something like what we have in the above example. Do u have any blog/link which elaborates use of sum() for different cases.

https://verificationacademy.com/forums/search?q=sum%20constraint%202d

Hi @dave_59
I tried the above problem as shown below. However, .shuffle() does not seem to work. Can you please tell how to shuffle() works in case of 2D array?

class abc;
  rand bit[7:0] arr[4][4];
  
  constraint arr_c{
    foreach(arr[i,j]){
      arr[i][j] inside {[0:10]};
      arr[i].sum() with (int'(item == 8)) == 2;
    
    }
     // arr.sum() with 
  
  }
      function void post_randomize();
    arr.shuffle();
        foreach(arr[i,j]) 
          $display("value of array[%p][%p] = %p",i,j,arr[i][j]);
    endfunction   
  
endclass



  module tb;
   abc abc_inst;
  initial begin 
    abc_inst = new();
    //repeat(10)
    abc_inst.randomize();

  end
endmodule



This question should have been asked as new topic. That way it helps other people with the same question search for an answer.

The shuffle() method works on a single dimension of an array. For a 2D array, you can shuffle individual rows and columns, but to shuffle the entire array, you would need to cast it to an intermediate 1D array, then shuffle it, then cast it back to a 2D array,

I created a mew topic as asked.

Can you please tell how to cast a 2D array to 1D array? We can take a 3X3 2D array.

Hi, Dave, I am amazed by your code

temp_id.sum(D1) with (D1.sum(D2) with (int'(D2 == 8) ) ) == 4;

How do D1, D2 work here?

With all the array manipulation methods array.method(ID), ID is the name of the iterator variable for each element of a single array dimension. If you don’t specify an explicit ID, then item is the implicit iterator variable name. When nesting reduction methods, using explicit iterator names makes it clearer what is being iterated. Each iteration of the first dimension of temp _id is a single dimensional dynamic array of 6 bits. Each iteration of D2 is a 6-bit packed integral value.

1 Like