Question on Array.Sum() Method , generate a n*n matrix such that there is only one 1's in a coloumn

]I was looking to generate a Matrix Where at any given point there is only one 1's in a coloumn
 1  0  0  0
 0  1  0  0
 0  0  1  0
 0  0  0  1

etc.... the goal is just to have one 1 in any given col 

Based on previous forum questions I used the sum method and was able to generate one 1's per col , and it worked on Mentor simulator and not on synopsys vcs(on VCS I got all 0's)
I understand that sum method unrolls as ( int'(arr[0]) +  ... + int'(arr[4]) ) ==j; where j is my sum
I wanted to know if what I wrote is correct , if there is a better way to achieve can you please let me know 


class my_array;
  rand bit[4:0] array[4][4];
  int i,j;
  rand int n;

//This is first constraint limiting value of each item
constraint array_item_val   {     
  foreach  (array[i]) {       // for each row
    foreach (array[,j]) {     // for each column in array
      array[i][j] inside {[0:1]};  // each element is either 0/1
        }
      }
  } 
      
constraint array_col_sum  {     
  foreach  (array[j]) {       
    array.sum with (int'(array[item.index][j])) == 1; // col max sum is 1
 	 }
  }

  function void display();
    foreach (array[i]) begin
      foreach (array[i][j]) begin
        $write("  %d  ",array[i][j]);
      end
      $display("\n");
    end
  endfunction
 
endclass
 
module my_array_randomization;
  my_array ma;
 
  initial begin
    ma = new();
    ma.randomize();
    ma.display();   
  end
 
endmodule 
[/systemverilog

In reply to CPU_Verif:

just point out a typo

constraint array_col_sum {
foreach (array[,j]) {    // you probably want to traverse column since you require column max = 1
array.sum with (int'(array[item.index][j])) == 1; // col max sum is 1
}
}

In reply to Jianfeng_0:

Agree, But on EDA playground both(The col wise iteration u mentioned and the one I wrote ) produced same result with Mentor Questa and both gave 0’s with synopsys VCS.

In reply to CPU_Verif:

that’s because your row and column count are the same.

have a try with
rand bit[4:0] array[4][10];

the solution fails when number of rows = 2;


class my_array;
  rand bit[4:0] array[4][4];
  int i,j;
  rand int n;
 
//This is first constraint limiting value of each item
constraint array_item_val   {     
  foreach  (array[i]) {       // for each row
    foreach (array[,j]) {     // for each column in array
      array[i][j] inside {[0:1]};  // each element is either 0/1
        }
      }
  }

      
constraint array_col_sum  {     
  foreach  (array[i,j]) {       
    array.sum() with (item.index(2) == j ? int'(item) : 0) == 1; // col max sum is 1
 	 }
  }
    
    
    function void display();
    foreach (array[i]) begin
      foreach (array[i][j]) begin
        $write("  %d  ",array[i][j]);
      end
      $display("\n");
    end
  endfunction
 
endclass
 
module my_array_randomization;
  my_array ma;
 
  initial begin
    ma = new();
    ma.randomize();
    ma.display();   
  end
 
endmodule 

this should generate sum of elements in column to 1.

In reply to sohels:
Not really Can you check once


class my_array;
  rand bit[4:0] array[2][10];
int i,j;
rand int n;

//This is first constraint limiting value of each item
constraint array_item_val {
foreach (array[i]) { // for each row
foreach (array[,j]) { // for each column in array
array[i][j] inside {[0:1]}; // each element is either 0/1
}
}
}

constraint array_col_sum {
  foreach (array[,j]) {
array.sum with (int'(array[item.index][j])) == 1; // col max sum is 1
}
}

function void display();
foreach (array[i]) begin
foreach (array[i][j]) begin
$write(" %d ",array[i][j]);
end
$display("\n");
end
endfunction

endclass

module my_array_randomization;
my_array ma;

initial begin
ma = new();
ma.randomize();
ma.display();
end
endmodule

vsim -voptargs=+acc=npr

run -all

0 0 0 0 0 1 0 1 0 0

1 1 1 1 1 0 1 0 1 1

is the output seen 1 1’s in a col

In reply to CPU_Verif:
A couple of problems with the use of the foreach statement. You do not declare the iterator variables separately like you would in a for loop. They are implicitly declared and iterate over each array dimension. That creates problems with this illegal code that is accepted by some tools, especially when you have declared “i” as a separate variable

foreach (array[i]) begin
  foreach (array[i][j]) begin
    ...

More than one set of brackets is not allowed in a foreach loop declaration. It’s not clear if you are trying to declare an new implicit iterator “i” or use a previously declared variable.

The code below works for me on 2 simulators on EDAPlayground. The other two have bugs dealing with the sum method operating on 2-D arrays. You can work around that by using another foreach loop and creating a helper array that accumulates the sum from previous elements lie a fibonacci series.

class my_array;
  rand bit[4:0] array[4][5];
 
//This is first constraint limiting value of each item
constraint array_item_val {
  foreach (array[i,j]) { // for each row,column in array
    array[i][j] inside {[0:1]}; // each element is either 0/1
  }
}
 
constraint array_col_sum {
  foreach (array[,j]) {
    array.sum() with (int'(item[j])) == 1; // col max sum is 1
  }
}
 
function void display();
  foreach (array[i]) begin
    foreach (array[,j]) begin // correct way of nesting two loops
      $write(" %d ",array[i][j]);
    end
    $display("\n");
  end
endfunction
 
endclass
 
module my_array_randomization;
my_array ma;
 
initial begin
  ma = new();
  assert(ma.randomize());
  ma.display();
end
endmodule

In reply to dave_59:

Thanks Dave I did not know that the iterator var are created implicitly && also was not aware of the fact that we can have only 1 set of in a for loop. Thanks for taking time to look at the code and correcting the mistakes.