1. 如何简单产生一个随机常数
1.1 $randomize
1.2 $urandom
$urandom(),可以生成一个32位的无符号随机数。
$urandom_range(maxval, minval=0),可以生成间与maxval与minval之间的数。
val = $urandom_range(7,0); //结果是[0,7]
val = $urandom_range(0,7); //如果mixval比minval小,参数列表会自动反向
val = $urandom_range(7); //如果minval没有指定,默认为0
2. 系统而有机地组织随机变量
2.1 约束
以上独立地生成一些随机数,在面向DUT的随机激励发生过程中,为了符合协议、满足测试需求,还需要添加一些”约束”。这些”约束”会使得变量朝着希望他们变化的方向去随机。不但如此,这些约束也会对变量与变量之间的关系生效。
2.2 约束的载体
因此,我们需要一个”载体”去容纳这些变量以及它们之间的约束。这个”载体”即是类,而类的成员变量均可声明为”随机”属性,用rand或者randc来表示。
2.3 随机变量
任何类中的整形(bit/byte/int)变量都可以声明为rand/randc。
定长数组、动态数组、关联数组和队列都可以声明为rand/randc,可以对动态数组和队列的长度加以约束。
指向对象的句柄成员,也可以声明为rand(不能被声明为randc) ,随机时该句柄指向对象中的随机变量也会一并被随机。
2.4 实例
2.5 约束块
有用的激励不仅仅是随机值,变量之间也有着相互关系。没有约束的随机变量会包含许多无效的和非法的值,这会使得有效激励的产生
2.5.1 设置取值范围
约束块支持整形通过set操作符来设置它们的可取值范围。
2.5.2 权重
除了成员集合设置,约束块也支持设置可取值的同时也为其设置随机时的权重。
:= 操作符:表示每一个值的权重是相同的。
:/ 操作符:表示权重会平均分配到每一个值。
2.5.3 唯一标识
unique可以用来约束一组变量,使得其在随机后变量之间不会有相同的数值。
2.5.4 条件约束
使用if-else或者->操作符来表示条件约束。
2.5.5 迭代约束
foreach可以用来迭代约束数组中的元素,这些数组可以是定长数组、动态数组、关联数组或者队列。
也可以使用数组的缩减方法做迭代约束。
2.5.6 函数调用
2.5.7 软约束
在没有soft描述时的约束,我们称之为硬约束,而带有soft描述的则是软约束。软约束用来指定变量的默认值和权重。如果用户在使用时,指定了外部约束对同一个变量做二次约束,或者用户定义了子类,也对同一个变量做二次约束时,那么硬约束可以”覆盖”软约束,并且不会导致随机数产生的失败。
2.5.8 实例
2.5.9 内嵌约束(指向模糊)
此处x是加给f的约束,就近句柄f指向类c1,优先找这个类里面有无x
若要指向task参数中的x,使用 local::x
2.5.10 内嵌约束(指向明确)
2.5.11 local域指向
之前在使用内嵌约束随机时,对于同名的变量处在不同的域中,可能会出现指向模糊的情况,之前我们已经给出了一种方法。接下来我们可以通过local:: 的域索引方式来明确随机变量的指向,即 local:: 指向的变量会在包含randomize()方法的对象中。
2.5.12 随机控制
rand_mode可以用来使能或者禁止随机变量。
当随机数被禁止时,它会同为声明为随机变量的普通变量一样,不会参与到随机化过程当中。
从以下两个函数声明可以看到,可以就单个随机变量调用其rand_mode,或者对整个对象调用rand_mode来控制其中所有的随机变量。
2.5.13 约束控制
类似于随机控制,一些约束块或者某个类的约束块集合都可以单个控制或者集体控制。
task object[.constraint_identifier] : :constraint_mode (bit on_off );funetion int object.constraint_identifier : : constraint_mode() ;
可以通过约束控制函数来使能或者关闭某些约束块。
2.5.14 内嵌变量控制
在使用类的随机化函数randomize()时,如果伴有参数,那么只会随机化这些变量,而其余变量无论是否之前被声明为rand/randc,都将不会参与到随机化当中。
3. 问答题
1.随机测试相比于定向测试,就你目前的认识,你认为有哪些优缺点?
答:当一个项目的功能成倍增加时,编写足够多的定向测试几乎不可能。而且,定向测试很难满足检查功能完整性的要求,随机测试能够产生更加完整复杂的激励场景,去对设计进行测试。缺点:随机测试会使验证环境的复杂度提高,从环境组件上考虑不再只需要发送激励的组件,而且还包括监测器、比较
器等。
2.产生一个随机数有哪些方法呢?请提交代码文本和仿真打印结果。
使用randomize
module randnum;
bit [3:0] a;
bit [3:0] b;
initial begin
$display("before randomized a = %0d b = %0d",a,b);
std::randomize (a,b);
$display("after randomized a = %0d b = %0d",a,b);
end
endmodule
仿真结果:
before randomized a =0 b=0
after randomized a= 4 b = 14
使用系统函数$urandom
module randnum;
bit [3:0] a;
bit [3:0] b;
initial begin
$display("before randomized a = %0d b = %0d",a,b);
b = $urandom();
a = $urandom_range(0,10);
$display("after randomized a = %0d b = %0d",a,b);
end
endmodule
仿真结果
before randomized a = 0 b = 0
after randomized a = 6 b = 6
3.如何用rand bit [15:0]向量产生一个随机实数?请提交代码文本和仿真打印结果。
4.如何用rand bit[7:0] arr[8]通过约束块(不用unique来约束)产生一个元素各不相同的数组?请提交代码文本和仿真打印结果。
5.请仿真以下代码并且解释仿真结果。
module tb;
class randnum;
rand bit[3:0] x, y;
endclass
initial begin
randnum rn = new();
int x = 5, y=7;
for(int loop = 0; loop < 10; loop++) begin
rn.randomize() with {x < y;};
$display("LOOP-%0d:: CONSTRAINT{x
分析:
y——指向rand bit[3:0] y中的y(就近原则,rn指向randnum这个类,此处y指向randnum这个要被随机化的类里面的y),所以每次随机后的x小于每次随机后的y即可。
this.y——同上
local::y——指向y=7(local::指向的变量y会在包含randomize()方法的对象rn中),所以每次随机后x小于7即可。
仿真结果
LOOP-0:: CONSTRAINT{x<y;}
rn.x = 4, rn.y = 6
LOOP-0: CONSTRAINT {x<this.y;}
rn.x = 5, rn.y = 15
LOOP-0:: CONSTRAINT{x<local::y;}
rn.x = 5, rn.y = 1LOOP-1:: CONSTRAINT{x<y;}
rn.x = 2, rn.y = 11
LOOP-1: CONSTRAINT {x<this.y;}
rn.x = 0, rn.y = 4
LOOP-1:: CONSTRAINT{x<local::y;}
rn.x = 4, rn.y = 7LOOP-2:: CONSTRAINT{x<y;}
rn.x = 8, rn.y = 13
LOOP-2: CONSTRAINT {x<this.y;}
rn.x = 7, rn.y = 8
LOOP-2:: CONSTRAINT{x<local::y;}
rn.x = 6, rn.y = 13LOOP-3:: CONSTRAINT{x<y;}
rn.x = 2, rn.y = 15
LOOP-3: CONSTRAINT {x<this.y;}
rn.x = 4, rn.y = 6
LOOP-3:: CONSTRAINT{x<local::y;}
rn.x = 0, rn.y = 15LOOP-4:: CONSTRAINT{x<y;}
rn.x = 11, rn.y = 15
LOOP-4: CONSTRAINT {x<this.y;}
rn.x = 2, rn.y = 5
LOOP-4:: CONSTRAINT{x<local::y;}
rn.x = 4, rn.y = 10LOOP-5:: CONSTRAINT{x<y;}
rn.x = 6, rn.y = 10
LOOP-5: CONSTRAINT {x<this.y;}
rn.x = 7, rn.y = 10
LOOP-5:: CONSTRAINT{x<local::y;}
rn.x = 3, rn.y = 3LOOP-6:: CONSTRAINT{x<y;}
rn.x = 0, rn.y = 12
LOOP-6: CONSTRAINT {x<this.y;}
rn.x = 9, rn.y = 13
LOOP-6:: CONSTRAINT{x<local::y;}
rn.x = 3, rn.y = 0LOOP-7:: CONSTRAINT{x<y;}
rn.x = 0, rn.y = 1
LOOP-7: CONSTRAINT {x<this.y;}
rn.x = 4, rn.y = 6
LOOP-7:: CONSTRAINT{x<local::y;}
rn.x = 5, rn.y = 13LOOP-8:: CONSTRAINT{x<y;}
rn.x = 0, rn.y = 12
LOOP-8: CONSTRAINT {x<this.y;}
rn.x = 11, rn.y = 14
LOOP-8:: CONSTRAINT{x<local::y;}
rn.x = 0, rn.y = 15LOOP-9:: CONSTRAINT{x<y;}
rn.x = 3, rn.y = 15
LOOP-9: CONSTRAINT {x<this.y;}
rn.x = 1, rn.y = 14
LOOP-9:: CONSTRAINT{x<local::y;}
rn.x = 0, rn.y = 8