How to constrain the 2nd dimension of a 2D array in systemverilog

Hi,

I have a 2x16 2d matrix like this:
[ 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0
0 0 0 1 0 0 0 1 0 0 0 0 0 0 0 0]
I have row constraint that ensures that there aren’t more than 2 1s in the same row.
I want to write a column constraint such that the there is never 2 1s in the same column.
I tried this :

module t;
  
class A ;
  

  rand bit[1:0] mem[2][16];

  
  constraint C1{foreach(mem[i,j]) mem[i][j] inside {[0:1]};}

  constraint C2{foreach(mem[i,j]) mem[i].sum() with (int'(item)) == 2 ;}
  
  constraint C3{ foreach(mem[i,j]) mem[j].sum() inside {[0:1]} ;}


endclass

initial begin
  
  A a;
  a = new();
  
  a.randomize();
  $display("mem is %p", a.mem);
  


end

endmodule

Constraint C3 doesnt work. How should this be written?

In reply to nikhilac@nvidia.com:


class A ;

  rand bit[1:0] mem[2][4];
  rand bit[1:0] mem_hlpr[4][2];

  constraint C1 {foreach(mem[i,j]) mem[i][j] inside {0,1};}
  constraint C1_1 {foreach(mem_hlpr[i,j]) mem_hlpr[i][j] inside {0,1};}
  constraint C2{foreach(mem[i,j]) mem[i].sum() with (int'(item)) == 2 ;}
  constraint C3{foreach(mem_hlpr[i,j]) mem_hlpr[i].sum() with (int'(item)) != 2 ;}
  constraint C4{foreach(mem[i,j]) mem[i][j] == mem_hlpr[j][i];}

endclass

In reply to nikhilac@nvidia.com:
Please use code tags making your code easier to read. I have added them for you.

class A ;
  rand bit[1:0] mem[2][16];
  constraint C1{foreach(mem[i,j]) mem[i][j] inside {0,1};}
  constraint C2{foreach(mem[i]) mem[i].sum() with (int'(item)) <= 2 ;} // you said "no more than 2"
  constraint C3{foreach(mem[,j]) mem.sum() with (int'(mem[item.index][j])) != 2 ;}
endclass

module t();
  A a_h = new();
  initial repeat(5) begin
      a_h.randomize();
      $display("value is %p", a_h.mem); 
   end 
endmodule

Notice the different foreach iterators

In reply to dave_59:

Hi Dave, please explain C3, is it mem.sum() ? or mem[j].sum() ??


constraint C3{foreach(mem[,j]) mem.sum() with (int'(mem[item.index][j])) != 2 ;}

In reply to ssureshg_:

It’s mem.sum(), which iterates over one dimension of an unpacked arrays. This would be mem[0] + mem[1]. However, these are both arrays of 16 elements. The with clause selects the second dimension. If we unroll the foreach loop, the constraint becomes

 mem.sum() with (int'(mem[item.index][0])) != 2 ;
 mem.sum() with (int'(mem[item.index][1])) != 2 ;
...
 mem.sum() with (int'(mem[item.index][15])) != 2 ;

Then expand the sum methods

int'(mem[0][0]) + int'(mem[1][0]) !=2;
int'(mem[0][1]) + int'(mem[1][1]) !=2;
...
int'(mem[0][15]) + int'(mem[1][15]) !=2;

In reply to dave_59:

Thnx Dave

In reply to dave_59:

Hi Dave,

What if we want to add similar constraints diagonally also?
I mean how to get constraint like this?
int’(mem[0][0]) + int’(mem[1][1]) !=2;
int’(mem[0][1]) + int’(mem[1][2]) !=2;
int’(mem[0][2]) + int’(mem[1][3]) !=2;

Is there an easier way to do this?

Hi Dave,

Though I have restricted

constraint C3{foreach(mem[,j]) mem.sum() with (int'(mem[item.index][j])) != 4 ;}//column

The output is
value is ‘{’{'h1, 'h1, 'h1, 'h3, 'h3}, '{'h3, 'h1, 'h1, 'h1, 'h1}}
sum of 1st column is 4

Please let me know if thIs it toll issue /code issue

Thanks,

In reply to UVM_geek:

https://verificationacademy.com/forums/systemverilog/2d-array-constraint-randomization#reply-111221

In reply to dave_59:

class A ;
  rand bit[1:0] mem[2][16];
  constraint C1{
                // all cases kept in single constraint
                foreach(mem[i,j]) mem[i][j] inside {0,1};
                foreach(mem[i]) mem[i].sum() with (int'(item)) <= 2 ;
                foreach(mem[,j]) mem.sum() with (int'(mem[item.index][j])) != 2 ;
               }
 
endclass
 
module t();
  A a_h = new();
  initial repeat(1) begin
      a_h.randomize();
    foreach(a_h.mem[i,])
      $display("%p", a_h.mem[i]); 
   end 
endmodule

if i ran the simulation , did see 1’s in same column… can you help here to understand this?
Compiler version S-2021.09; Runtime version S-2021.09; May 22 09:22 2023
'{'h0, 'h0, 'h0, 'h0, 'h0, 'h0, 'h1, 'h0, 'h0, 'h0, 'h0, 'h0, 'h0, 'h1, 'h0, 'h0}
'{'h0, 'h0, 'h0, 'h0, 'h0, 'h1, 'h0, 'h0, 'h0, 'h0, 'h0, 'h0, 'h0, 'h1, 'h0, 'h0}
link : Edit code - EDA Playground
Thanks in advance

In reply to ndesam:

https://verificationacademy.com/forums/systemverilog/2d-array-constraint-randomization#reply-111221