pre_randomize() 和 post_randomize() 在 systemverilog 中的常见和良好用法是什么?

What are the common and good usage of pre_randomize() and post_randomize() in systemverilog?

如何在pre_randomize()中change/add约束或constraint_mode? 我知道我可以覆盖 post_randomize 中的结果,我可以在 pre_randomize 中打开和关闭 rand_mode,但我正在寻找一些额外的功能,尤其是与约束相关的功能。

pre_randomize一般用于设置对象随机化前的一些前置条件。这里可以打印之前随机化的结果设置一些约束所依赖的变量

正如您提到的,pre_randomize 可用于为任何变量设置 rand_mode(0)。它也可以用来操纵约束。

post_randomize用于操作一些变量如ECC校验,打印随机化结果操作一些基于现有随机化的非随机字段

post_randomize 的另一个用法是在随机化过程 中 生成'x' 或'z'。默认情况下,随机化仅生成 01 已知值。但是也可以使用现有的随机变量来生成 x/z 值。

这是一个虚拟示例,说明我们可以在 pre_randomizepost_randomize 函数中做什么。这里,依赖non_rand_var,我们可以enable/disable约束模式,设置任意变量的rand模式。post_randomize 函数,可以通过 'x' 或 'z'.

覆盖 'my_x' 变量
    class A;

    int non_rand_var;
    rand int rand_var;
    rand int rand_var2;
    rand logic my_x;

    constraint c1{non_rand_var==1 -> rand_var=='h5;}

      function new(int non_rand_var);
        this.non_rand_var = non_rand_var; // set non random variable
      endfunction

      function void pre_randomize();
        if(non_rand_var==5) begin // set randomization mode of rand_var2
          rand_var2.rand_mode(0);
          c1.constraint_mode(0); // disable constraint
        end
        $display("In pre randomize, non_rand_var=0x%0x rand_var=0x%0x",non_rand_var, rand_var);
      endfunction

      function void post_randomize();
        // my_x = $urandom_range(0,1) ? 0 : 'x;
        my_x = (non_rand_var==1) ? 0 : 'x; // Manipulate my_x to generate 'x' values
        $display("In post randomize, rand_var=0x%0x",rand_var);
      endfunction

    endclass

module top();
  A a=new(1);
  initial begin
    a.randomize(); 
    $display("Initial block:\na.my_x = 0x%0x\na.rand_var=0x%0x\na.non_rand_var=0x%0x\na.rand_var2=0x%0x",a.my_x,a.rand_var,a.non_rand_var,a.rand_var2);
  end
endmodule

pre_randomize & post_randomize 函数可以根据应用程序有多种用途。

下面列出了这些函数的一些用法。

  • 这两个函数都可以被覆盖,因此可以通过扩展 class
  • 来修改随机化行为
  • 转on/off几个随机变量
  • 转on/off少约束
  • 分配给随机化所依赖的其他非随机变量
  • 根据特定条件更改随机变量的权重

pre_randomization 函数的典型用法是生成一个唯一值数组。

class helper;
  randc bit [7:0] a;
endclass

class original;
  bit [7:0] unique[64];

  function void pre_randomize();
    helper h = new();
    foreach (unique[i])
    begin
      void'(h.randomize());
      unique[i] = h.a;
    end
  endfunction
endclass