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?

1 Like

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

Link:

@MichaelP 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
5 Likes

Thanks for the wonderful solution.

is the extendable to 10x10 2D array ?

X a1 X
a3 a a2
X a4 X

X → dont care
a != a1 != a2 != a3 != a4

This matrix needs to be applicable throughout the matrix of MxN 2D matrix

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