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

qquod 发布于 2019-10-09 最后更新 2019-10-09 22:59 11 浏览

如何在pre_randomize()中更改/添加约束或constraint_mode? 我知道我可以覆盖post_randomize中的结果,我可以在pre_randomize中打开和关闭rand_mode,但我正在寻找更多的功能,特别是与约束相关的功能。谢谢。

已邀请:

vvelit

赞同来自:

pre_randomize& post_randomize函数可以根据应用程序进行多种使用。 以下是这些功能的少数用法列表。

  • 可以覆盖这两个函数,因此可以使用扩展类修改随机化行为
  • 打开/关闭几个随机变量
  • 打开/关闭一些约束
  • 分配给随机化依赖的其他非随机变量
  • 根据特定条件更改随机变量的权重
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

jfugit

赞同来自:

pre_randomize通常用于在对象随机化之前设置一些前置条件。这里可以打印先前随机化的结果,设置一些约束依赖的变量等。 如您所述,pre_randomize可用于为任何变量设置rand_mode(0)。它也可以用来操纵约束。 post_randomize用于操作一些变量,如ECC检查,打印随机化结果,根据现有随机化操作一些非随机字段等。 post_randomize的另一个用法是在随机化过程中生成“x”或“z”。默认情况下,随机化仅生成01已知值。但是也可以使用现有的随机变量生成x / z值。 以下是我们在pre_randomizepost_randomize函数中可以执行的操作的虚拟示例。这里,根据non_rand_var,我们可以启用/禁用约束模式并设置任何变量的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