IEEE 1800-2012 标准的 7.12.3 阵列缩减方法部分指出
[array] 缩减方法可以应用于任何未打包的整数值数组,以将数组缩减为
单值。
虽然允许MAT[0].sum() 或MAT[1].sum()(分别在MAT 的第0 行和第1 行应用总和),但MAT.sum() 不允许。 MAT 中的一行是 bit 的数组,bit 是整数类型,但 MAT 是 bit 的解压缩数组数组,它不是整数类型。
此外,无法从数组中选择单个列。您只能按行切片。这实现起来有点棘手,但可行。
让我们看看每个约束。首先,使用 sum() 函数可以轻松地限制每一行的总和:
constraint sum_on_row {
foreach (MAT[i])
MAT[i].sum() with (32'(item)) inside { 0, 1, 2, 4 };
}
要限制列上的总和,您需要转置数组(行变为列,列变为行)并对其进行约束。首先我们定义MAT的转置:
rand bit MAT_transp[8][8];
constraint construct_MAT_transp {
foreach (MAT[i,j])
MAT_transp[j][i] == MAT[i][j];
}
我们分配另一个数组并使其内容与MAT 的内容保持同步。对MAT_transp 的任何约束都会间接影响MAT。和之前一样,我们可以约束MAT_transp的行,这将有效地约束MAT的列:
constraint sum_on_col {
foreach (MAT_transp[i])
MAT_transp[i].sum() with (32'(item)) == 1;
}
最后,您希望数组中所有元素的总和为 8。这是最棘手的问题。虽然我们不能直接约束数组总和,但我们可以将问题分成两部分。首先,我们可以计算MAT 中每一行的总和并将它们全部存储在一个数组中:
rand int unsigned row_sums[8];
constraint compute_row_sums {
foreach (row_sums[i])
row_sums[i] == MAT[i].sum() with (32'(item));
}
现在我们有了每一行的总和,很容易通过约束所有行和的总和来约束整个数组的总和:
constraint sum_of_matrix {
row_sums.sum() == 8;
}
很酷的是,对于这个问题,我们已经涵盖了很多我们可以在约束数组时应用的常见“技巧”。您可以在old post I wrote 中找到更多数组约束习语。