mappingconstraintssystem-verilog

SystemVerilog constraint for mapping between two 2D arrays


There are two MxN 2D arrays:

rand bit [M-1:0] src [N-1:0]; 
rand bit [M-1:0] dst [N-1:0];

Both of them will be randomized separately so that they both have P number of 1'b1 in them and rest are 1'b0.

A third MxN array of integers named 'map' establishes a one to one mapping between the two arrays 'src' and 'dst'.

rand int [M-1:0] map [N-1:0]; 

Need a constraint for 'map' such that after randomization, for each element of src[i][j] where src[i][j] == 1'b1, map[i][j] == M*k+l when dst[k][l] == 1. The k and l must be unique for each non-zero element of map.

To give an example: Let M = 3 and N = 2.

Let src be

[1   0   1
 0   1   0]

Let dst be

[0   1   1
 1   0   0]

Then one possible randomization of 'map' will be:

[3   0   1
 0   2   0]

In the above map:


Solution

  • This is very difficult to express as a SystemVerilog constraint because

    1. there is no way to conditionally select elements of an array to be unique
    2. You cannot have random variables as part of index expression to an array element.

    Since you are randomizing src and dst separately, it might be easier to compute the pointers and then randomly choose the pointers to fill in the map.

      module top;
       parameter M=3,N=4,P=4;
       bit  [M-1:0] src [N];
       bit  [M-1:0] dst [N];
       int  map [N][M]; 
       int  pointers[$];
    
       initial begin
          assert( randomize(src) with {src.sum() with ($countones(item)) == P;} );
          assert( randomize(dst) with {dst.sum() with ($countones(item)) == P;} );
          foreach(dst[K,L]) if (dst[K][L]) pointers.push_back(K*M+L);
          pointers.shuffle();
          foreach(map[I,J]) map[I][J] = pointers.pop_back();
          $displayb("%p\n%p",src,dst);
          $display("%p",map);
       end
    endmodule