Sum 2D array in constraints in system verilog
I am trying to create a constraint using a 2d array filled with 1 and 0. I want each row to have a total of 0,1,2,4 and each column to be 1. Moreover, I want the entire sum of the matrix to be 8 (which worked using the sum function). I tried to use the .sum () function to constrain each row and column to the value I required, but I keep getting a syntax error. What am I doing wrong?
rand bit MAT[8][8];
constraint range {
MAT.sum() with (32' (item)) == 8;
foreach (MAT[j]){
foreach(MAT[j][i]){
MAT[j][].sum() with (32' (item)) == 1;
MAT[][i].sum() with (32' (item)) inside {0,1,2,4};
}
}
source to share
Section 7.12.3. The IEEE 1800-2012 Array Reduction Methods state that
[array] reduction methods can be applied to any unpacked array of integral values to reduce the array to a single value.
While permitted MAT[0].sum()
or MAT[1].sum()
(apply the sum on lines 0 and 1, respectively MAT
), MAT.sum()
- no. String in MAT
is an array bit
and bit
is an integral type, but it MAT
is an unpacked array bit
that is not an integral type.
Also, it is not possible to select a single column from an array. You can only cut equally. It's a little more difficult to implement, but doable.
Let's take a look at each limitation. First, limiting the sum of each row is easily accomplished with the sum () function:
constraint sum_on_row {
foreach (MAT[i])
MAT[i].sum() with (32'(item)) inside { 0, 1, 2, 4 };
}
To limit the sum of a column, you will need to transpose the array (rows become columns, columns become rows) and limit that. First, let's define the transposition MAT
:
rand bit MAT_transp[8][8];
constraint construct_MAT_transp {
foreach (MAT[i,j])
MAT_transp[j][i] == MAT[i][j];
}
We allocate another array and store its contents as configured MAT
. Any restrictions on MAT_transp
will indirectly affect MAT
. As before, we can limit rows MAT_transp
that will effectively limit the columns MAT
:
constraint sum_on_col {
foreach (MAT_transp[i])
MAT_transp[i].sum() with (32'(item)) == 1;
}
Finally, you want the sum of all the elements in the array to be 8. This is the hardest thing to do. While we cannot directly limit the sum of the array, we can split the problem into two parts. First, we can calculate the sum for each row in MAT
and store them all in an array:
rand int unsigned row_sums[8];
constraint compute_row_sums {
foreach (row_sums[i])
row_sums[i] == MAT[i].sum() with (32'(item));
}
Now that we have the sum on each row, it is easy to limit the sum of the entire array by holding back the sum of all row sums:
constraint sum_of_matrix {
row_sums.sum() == 8;
}
The most interesting thing is that with this problem we covered a lot of common "tricks" that we can apply when limiting arrays. You can find more named array constraints in an old post I wrote .
source to share