Constraint: 2d matrix

Hi,

I have the following requirements:

16 dma engines, each one accessing 1 of the 16 segments in memory
each segment of memory is 16 deep and contiguous locations.
memory locations of the segments must not overlap.


class matrix;
  localparam N = 16;
  rand int box[N][N];
  
  constraint box_c
  {
    foreach(box[row,col])
    {
      //This constraint intention was to just generate incremental address for each dma engine[0...15]
      (row > 0) -> box[row][col] == box[row-1][col] + 1;
      //This constraint generates contiguous address within the 16 deep memory segments
      (col > 0) -> box[row][col] == box[row][col-1] + 1;
    }
    
    //This constraint is to make sure the segment address don't overlap
    unique{box};
    
//foreach(box[rowA,colA])
    //  foreach(box[rowB,colB])
    //    if(!(rowA == rowB && colA == colB))
    //      box[rowA][colA] != box[rowB][colB];
  }
  
endclass : matrix

module test_top;
  
  matrix mat;
  
  initial
    begin
      mat = new;
      repeat(1)
        begin
          assert(mat.randomize());
          foreach(mat.box[i])
            $display("%p\n",mat.box[i]);
        end
    end
  
endmodule : test_top

A few issues here:

  1. How do I constraint the first dimension to be 0-15 incrementally, one for each dma engine
  2. How do I make sure segments are unique?

The above unique constraint causes the tools on edaplayground to crash.

In reply to nnd:

The first two rows and columns constraints conflict with being unique. box[0][1] and box[1][0] both have to be one increment above box[0][0]. It might help if you show us one solution you are looking for and then see if it fits into your constraints.

In reply to dave_59:

Hi Dave,
I wanted the values as shown below



1st dimension  2nd dimension values
0              1000, 1001,...,1015
1              2000, 2001,...,2015
2              3000, 3001,...,3015
..             ...
15             15000, 15001,....,15015

I had the unique in there to make sure the 2nd dimension values don't overlap.


In reply to nnd:

You had

(row > 0) -> box[row][col] == box[row-1][col] + 1;

instead of + 1 did you mean + 1000 ?

In reply to dave_59:

No there I thought I was generating the 1st dimension values as I showed.

Your constraints needed a bit of tweaking. This works on edaplayground.


class matrix;
  localparam N = 16;
  rand int unsigned box[N][N];
  
  constraint box_row_c{
    foreach(box[row, col]) {
      row == 0 && col == 0 -> box[row][col] == 0;
      (row > 0) -> box[row][col] == box[row-1][col] + 1;
      (col > 0) -> box[row][col] == box[row][col-1] + 1000;
     }
   }
        
endclass: matrix
        
module test_top;
 
  matrix mat;
 
  initial
    begin
      mat = new;
      repeat(1)
        begin
          assert(mat.randomize());
          foreach(mat.box[i])
            $display("%p\n",mat.box[i]);
        end
    end
 
endmodule : test_top


Output:
'{'h0, 'h3e8, 'h7d0, 'hbb8, 'hfa0, 'h1388, 'h1770, 'h1b58, 'h1f40, 'h2328, 'h2710, 'h2af8, 'h2ee0, 'h32c8, 'h36b0, 'h3a98}

'{'h1, 'h3e9, 'h7d1, 'hbb9, 'hfa1, 'h1389, 'h1771, 'h1b59, 'h1f41, 'h2329, 'h2711, 'h2af9, 'h2ee1, 'h32c9, 'h36b1, 'h3a99}

In reply to Dileep Namboothiri:

That works!

Thanks