【问题标题】:Sum 2D array in constraints in system verilog在系统verilog中的约束中求和二维数组
【发布时间】:2017-06-19 11:57:06
【问题描述】:

我正在尝试使用填充 1 和 0 的二维数组创建约束。 我希望每一行的总和为 0、1、2、4,每列的总和为 1。此外,我希望矩阵的总和等于 8(使用 sum 函数)。 我尝试使用函数 .sum() 将每一行和每一列限制为我要求的值,但我不断收到语法错误。我做错了什么?

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};
     }
 }

【问题讨论】:

    标签: multidimensional-array constraints system-verilog verification


    【解决方案1】:

    IEEE 1800-2012 标准的 7.12.3 阵列缩减方法部分指出

    [array] 缩减方法可以应用于任何未打包的整数值数组,以将数组缩减为 单值。

    虽然允许MAT[0].sum()MAT[1].sum()(分别在MAT 的第0 行和第1 行应用总和),但MAT.sum() 不允许。 MAT 中的一行是 bit 的数组,bit 是整数类型,但 MATbit 的解压缩数组数组,它​​不是整数类型。

    此外,无法从数组中选择单个列。您只能按行切片。这实现起来有点棘手,但可行。

    让我们看看每个约束。首先,使用 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 中找到更多数组约束习语。

    【讨论】:

      【解决方案2】:

      实际上,array2d.sum() 与 VCS 配合使用。

      【讨论】:

        【解决方案3】:

        对于第二个索引的总和: 代替 MAT[j][].sum() with (32'(item)) 采用 MAT[j].sum() with (32'(item))

        对于第一个索引的总和: 代替 MAT[][i].sum() with (32'(item)) 采用 MAT.sum() with (32'(item[i]))

        注意:对于沿多维数组的任何索引求和,指定较高维度的索引,然后减少获得的子数组,使用 with 子句用于较低维度的索引。

        例子:

        bit bit_array [n0][n1][n2][n3][n4];
        int sum_0 = bit_array.sum() with (int'(item[i1][i2][i3][i4]));
        int sum_1 = bit_array[i0].sum() with (int'(item[i2][i3][i4]));
        int sum_2 = bit_array[i0][i1].sum() with (int'(item[i3][i4]));
        int sum_3 = bit_array[i0][i1][i2].sum() with (int'(item[i4]));
        int sum_4 = bit_array[i0][i1][i2][i3].sum() with (int'(item));
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-12-04
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多