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:
This is very difficult to express as a SystemVerilog constraint because
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