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'。默认情况下,随机化仅生成 0
和 1
已知值。但是也可以使用现有的随机变量来生成 x
/z
值。
这是一个虚拟示例,说明我们可以在 pre_randomize
和 post_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
如何在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'。默认情况下,随机化仅生成 0
和 1
已知值。但是也可以使用现有的随机变量来生成 x
/z
值。
这是一个虚拟示例,说明我们可以在 pre_randomize
和 post_randomize
函数中做什么。这里,依赖non_rand_var
,我们可以enable/disable约束模式,设置任意变量的rand模式。在post_randomize 函数,可以通过 'x' 或 'z'.
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