2D array generation with special condtion

Hi,
I am trying to solve below problem.
Need to generate the 2D array with below constraints

  1. each element can take either 0 or 1
  2. there would be N(say=2) elements which are not equivalent to it’s 4 neighbors. (top,bottom,left,right)

I am able to generate the 2D array with above constraints except N elements. Instead, I see the result for all the valid elements.


class test;
 
  rand bit a[5][5]; 
  constraint c1 {
  
    foreach(a[i,j]){
      i>0 -> a[i][j] != a[i-1][j];
      i<3 -> a[i][j] != a[i+1][j];
      j>0 -> a[i][j] != a[i][j-1];
      j<3 -> a[i][j] != a[i][j+1];      
    }      
  }      
endclass

module tb;
  test t_h;
  initial begin
  t_h=new;
     t_h.randomize;
      foreach(t_h.a[i,])
        $display("%p",t_h.a[i]);   
end  
endmodule

current o/p:
'{'h1, 'h0, 'h1, 'h0, 'h1}
'{'h0, 'h1, 'h0, 'h1, 'h0}
'{'h1, 'h0, 'h1, 'h0, 'h1}
'{'h0, 'h1, 'h0, 'h1, 'h0}
'{'h1, 'h0, 'h1, 'h0, 'h1}

expected o/p: where N=2
'{'h1, 'h0, 'h1, 'h0, 'h1}
'{'h0, 'h1, 'h0, 'h0, 'h0}
'{'h1, 'h0, 'h0, 'h0, 'h1}
'{'h0, 'h0, 'h0, 'h1, 'h0}
'{'h1, 'h0, 'h1, 'h0, 'h1}

EDITED:

  1. fixed the expected output.
  2. Rule does not apply for the edges.

In reply to verifeng2:

In your expected output, I see three elements that are not equivalent to its 4 neighbors (the one diagonally in-between the one you marked.

How does your rule apply to the edges?

Hi Dave,
I have fixed the output. The rule is not applicable to edges.
Thanks

In reply to verifeng2:

This worked for me by creating a “helper” array.

class test;
 
  rand bit a[5][5]; 
  rand bit b[1:3][1:3]; //helper array to select N elements
   int N = 6;
   
   constraint c1 {
		  b.sum(D1) with (D1.sum(D2) with (int'(D2)))== N;
		  foreach(b[i,j])
		     if (b[i][j]) {
			a[i][j] != a[i-1][j] &&
			a[i][j] != a[i+1][j] &&
			a[i][j] != a[i][j-1] &&
			a[i][j] != a[i][j+1];
			} else {
			a[i][j] == a[i-1][j] ||
			a[i][j] == a[i+1][j] ||
			a[i][j] == a[i][j-1] ||
			a[i][j] == a[i][j+1];
			}}		     
endclass
 
module tb;
  test t_h;
  initial begin
     t_h=new;
     t_h.randomize;
     foreach(t_h.a[i,])
       $display("%p",t_h.a[i]);   
end  
endmodule 

Produced:

# '{0, 1, 0, 0, 1} # '{1, 0, 0, 0, 1} # '{1, 0, **1**, 0, 0} # '{0, **1**, 0, 1, 1} # '{1, 0, 0, 0, 1}

In reply to dave_59:
Thanks Dave for quick solution.