为什么要随机化?
随着设计复杂度的增加,验证的难度也会增加。这体现在激励的角度上,就是需要尽可能多样的激励进行验证。如果人为的去增加各种激励,显然工作量非常大,所以要采用随机化的方法。用受约束随机的手段,尽可能多地覆盖各种激励。
需要随机化的方面有器件配置;环境配置;原始输入数据;封装后的输入数据;协议异常;延时;事务状态;错误和违规。
如何随机化?
建立具有随机变量及其约束的类,然后利用随机函数对其赋值。
class rnd;/*一个带有随机变量的类*/
rand bit [31:0] data0;
randc bit [7:0] data1; /*randc类型会在所有可能值出现后才有重复值*/
/*变量的约束*/
constraint c {data0 > 20; /*约束中一个关系式只有一个关系操作符;表达式并行*/
data0 < 50;}
endclass
rnd r1;
initial begin
r1 = new();
r1.randomize(); /*随机化这个对象*/
end
约束的多样性
可以利用dist操作符对随机值施加权重。权重之和不一定是100。如下列代码,data为25的概率是40/140;31~35每个值的概率是20/140。
constraint c {
data dist {25:=40; [31:35]:/100}; /*:= 指权重均为某值;:/指权重为某值的平均数*/
}
可以用inside运算符指定随机值的集合。
int low = 20,high = 50;
constraint c {
data inside {[low:high],[10:40]};/*也可以用$符号指定最大最小值*/
}
constraint copp {
!(data inside {[low:high],[10:40]});/*可以取反*/
}
可以用if-else语句及->操作符进行条件约束。
class BusOp;
constraint c_len_rw {
if (op==READ)
len inside{[BYTE:LWRD]};
else
len == LWRD;
}
endclass
class BusOp;
constraint c_io {
(io_space_mode) ->
addr[31] = 1'b1;
}
endclass
可以用内建的constraint_mode()控制约束的生效与否。
BusOp.constraint_mode(0);/*约束全部禁止*/
BusOp.c_io.constraint_mode(1);/*开启约束*/
BusOp.op.rand_mode(0);/*设置参数为非随机数*/
BusOp.randomize(op);/*只随机化op*/
可以在randomize()语句后用wit{}语句添加内嵌约束。
assert(BusOp.randomize() with {len > 10;});
可以用pre_randomize()及post_randmize()进行随机化前后处理。
对于数组的约束,可以利用foreach进行单个元素约束,也可以用操作数组的函数进行整体约束,比如sum。
constraint c_len {
foreach (len[i])
len[i] inside {[1:255]};
len.sum < 1024;
len.size() inside {[1:8]};
}