Constraint Question : Write a constraint for 2D Array where value of an element should be different from its neighbor

class packet;
  rand bit [3:0] array[4][4];
  int i,j,a,b;

  constraint unique_elements {foreach (array[i,j]) {
    foreach (array[a,b]){
      (a==i+1 && b==j && a<4) -> array[a][b]!=array[i][j]; // One Row below, Same Column
      (a==i-1 && b==j && a>=0) -> array[a][b]!=array[i][j];// One Row above, Same Column
      
      (a==i && b==j+1 && b<4) -> array[a][b]!=array[i][j];// Same Row, Column to the right
      (a==i && b==j-1 && b>=0) -> array[a][b]!=array[i][j];// Same Row, Column to the left
    }
  }}
                
  function void print();
    for (int i = 0; i < 4; i++) begin
      $display("\n");
      for (int j = 0; j < 4; j++) begin
        $write("[%0d]\t",array[i][j]); 
      end 
    end
  endfunction 
endclass



module test;
  packet p;
  
  initial begin
    p=new();
      p.randomize;
      p.print();
  end
endmodule

Is my solution correct for this problem?

Did you try to use the unique constraint construct?
For example:
constraint array_unique_elements_c {unique {array};}

Link:

@Michael54 Using unique would make the array elements too different.
OP only wants neighboring elements to be unique, not all array elements to be unique.

@totochan1985 Have you tried to run the code on https://www.edaplayground.com/ ?

Yes, it seems to work fine but just wanted opinion of experts here to check if my approach is correct.

You have many reduncies in your constraints. You just need a single foreach loop scan to check adjacent elements. Also, you should not be declaring the foreach loop iterator variables separately.

class packet;
  rand bit [3:0] array[4][4];
  constraint unique_elements {foreach (array[i,j]) {
    i < 3 -> array[i+1][j] != array[i][j];   // One Row below, Same Column
    j < 3 -> array[i][j]  !=   array[i][j+1]; // Same Row, Column to the right
    }
  }          
  function void print();
    for (int i = 0; i < 4; i++) begin
      $display("\n");
      for (int j = 0; j < 4; j++) begin
        $write("[%0d]\t",array[i][j]); 
      end 
    end
    $display;                     
  endfunction 
endclass

module test;
  packet p = new;
  initial repeat(5) begin
      p.randomize;
      p.print();
  end
endmodule
4 Likes

Thanks for the wonderful solution.