欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

SystemVerilog foreach Constraint

程序员文章站 2022-05-07 08:01:54
...

SystemVerilog提供了在约束内使用foreach循环的支持,因此可以约束数组。

foreach构造遍历数组的元素,其参数是表示数组中单个实体的标识符。

下面显示的代码声明了一个名为array的静态数组,其大小为5。此数组可以容纳5个元素,其中每个元素可以使用从0到4的索引进行访问。

该约束使用foreach循环遍历所有元素,并将每个元素的值分配给其索引的值。

class ABC;
  rand bit[3:0] array [5];
 
  // 此约束将遍历数组中的5个元素中的每个元素,并将每个元素设置为其特定索引的值
  constraint c_array { foreach (array[i]) {
              array[i] == i;
              }
                     }
endclass
 
module tb;
 
  initial begin
    ABC abc = new;
    abc.randomize();
    $display ("array = %p", abc.array);
  end
endmodule

Simulation Log
ncsim> run
array = '{'h0, 'h1, 'h2, 'h3, 'h4}
ncsim: *W,RNQUIE: Simulation is complete.

此约束将遍历数组中的5个元素中的每个元素,并将每个元素设置为其特定索引的值

动态数组/队列

动态数组和队列在声明时没有大小,因此无法直接使用foreach循环。 因此,数组的大小必须直接分配或作为约束集的一部分进行约束。

Example
 
class ABC;
  rand bit[3:0] darray [];     // Dynamic array -> size unknown
  rand bit[3:0] queue [$];     // Queue -> size unknown
 
  // Assign size for the queue if not already known
  constraint c_qsize  { queue.size() == 5; }
 
  // Constrain each element of both the arrays
  constraint c_array  { foreach (darray[i])                
                darray[i] == i;              
                        foreach (queue[i]) 
                          queue[i] == i + 1;
                      } 
 
    // 可以像对队列一样使用约束来分配数组的大小,但是让我们在调用随机化之前分配大小
    function new ();
    darray = new[5];   // Assign size of dynamic array
  endfunction
endclass
 
module tb;
 
  initial begin
    ABC abc = new;
    abc.randomize();
    $display ("array = %p
queue = %p", abc.darray, abc.queue);
  end
endmodule
 
Simulation Log
ncsim> run
array = '{'h0, 'h1, 'h2, 'h3, 'h4}
queue = '{'h1, 'h2, 'h3, 'h4, 'h5}
ncsim: *W,RNQUIE: Simulation is complete.

多维数组

SystemVerilog约束功能强大,足以应用于多维数组。在下面的示例中,我们具有带有打包结构的多维静态数组。
SystemVerilog foreach Constraint
在这里,我们尝试将模式0xF0F0F分配给多维数组的每个元素。

class ABC;
  rand bit[4:0][3:0] md_array [2][5];   // Multidimansional Arrays
 
  constraint c_md_array { 
    foreach (md_array[i]) {
      foreach (md_array[i][j]) {
          foreach (md_array[i][j][k]) {
            if (k %2 == 0) 
              md_array[i][j][k] == 'hF;
            else
              md_array[i][j][k] == 0;
        }
      }
    }
  }
 
 
endclass
 
module tb;
 
  initial begin
    ABC abc = new;
    abc.randomize();
    $display ("md_array = %p", abc.md_array);
  end
endmodule
 
Simulation Log
ncsim> run
md_array = '{'{'hf0f0f, 'hf0f0f, 'hf0f0f, 'hf0f0f, 'hf0f0f}, '{'hf0f0f, 'hf0f0f, 'hf0f0f, 'hf0f0f, 'hf0f0f}}
ncsim: *W,RNQUIE: Simulation is complete.

rand bit[4:0][3:0] md_array [2][5]
SystemVerilog foreach Constraint rand bit[4:0][3:0] md_array [2][5]

多维动态数组

约束多维动态数组会有些棘手,并非所有模拟器都支持。在下面显示的示例中,2D数组md_array的X或Y元素的大小未知。

class ABC;
  rand bit[3:0] md_array [][];   // Multidimansional Arrays with unknown size
 
  constraint c_md_array { 
     // First assign the size of the first dimension of md_array
     md_array.size() == 2; 
 
     // Then for each sub-array in the first dimension do the following:
     foreach (md_array[i]) {
 
        // Randomize size of the sub-array to a value within the range
        md_array[i].size() inside {[1:5]};
 
        // Iterate over the second dimension 
        foreach (md_array[i][j]) {
 
           // Assign constraints for values to the second dimension
           md_array[i][j] inside {[1:10]};
         }
      }
   }
 
endclass
 
module tb;
 
  initial begin
    ABC abc = new;
    abc.randomize();
    $display ("md_array = %p", abc.md_array);
  end
endmodule
 
Simulation Log
ncsim> run
md_array = '{'{'h9, 'h6, 'h7, 'h9, 'h1}, '{'h5, 'h9, 'h4, 'h2}}
ncsim: *W,RNQUIE: Simulation is complete.

数组约简迭代约束

这是SystemVerilog中支持的另一个非常有用的结构和技术。数组约简方法可以从未打包的整数值数组中生成单个值。这可以在约束中使用,以允许在随机化期间考虑表达式。例如,考虑N个元素的数组必须是随机的,以便所有元素的和等于某个值。可以将数组约简操作符与with子句一起使用,以便迭代数组的每个元素并将其包含在约束求解器中。

class ABC;
  rand bit[3:0] array [5];
 
  // Intrepreted as int'(array[0]) + int'(array[1]) + .. + int'(array[4]) == 20;
  constraint c_sum { array.sum() with (int'(item)) == 20; }
 
endclass
 
module tb;
  initial begin
    ABC abc = new;
    abc.randomize();
    $display ("array = %p", abc.array);
  end
endmodule
 
Simulation Log
ncsim> run
array = '{'h4, 'h2, 'h2, 'h4, 'h8}
ncsim: *W,RNQUIE: Simulation is complete.

参考文献:
【1】https://www.chipverify.com/systemverilog/systemverilog-foreach-constraint

相关标签: # Constraint