随机约束和分布
- 随机化就是为了能更好的测试,找到连自己都没想到的缺陷
- 随机化是为了产生更多可能的驱动,在 Class 中使用
- 在类中使用rand/randc表明随机属性,constraint约束一起声明,后期对象调用使用randomize
- 约束表达式由约束求解器完成,不同仿真器对于同一个约束和种子值求解出来的数值可能是不相同的
- SV只能随机化2值数据类型,位可以是2位/4位,无法随机出X/Z以及字符串
- 随机化采用受约束的随机测试法:CRT,自动产生测试机,定向测试集只需施加激励,而后人工检查输出结果
- 对象执行randomize()前会先执行pre_randomize()以及post_randomize()
- $random()平均分布,返回32位有符号随机数
- $urandom()平均分布,返回32位无符号随机数
- $urandom_range()在指定范围内的平均分布
class Pakcet; //类中声明rand变量与约束
rand bit[31 : 0] src, dst, date[8];
randc bit[7 : 0] kind;
constraint c {src > 10 ; src < 15;}
end class
Packet p;
initial begin
p = new(); //创建类对象
assert(p.randomize()) else //对象调用随机方法 遇到约束方面问题返回0
$fatal(0, "Pakcet::randomize failed");
transmit(p);
end
其中,rand与randc区别:
rand 每次随机数可能相同,randc 不存在随机数相同情况
class date;
rand bit[2 : 0] month;
rand bit[4 : 0] day;
rand int year;
constraint c_data{
month inside{[1 : 12]};
day inside {[1 : 31]};
year inside {[2010 : 2030]};
end class
无法生成 month = 10,因为month为3位,最多到7
rand int src, dst;
constraint c_dist{
src dist {0:40,[1:3]:=60};
// src = 0, weight = 40/220;
// src = 1, weight = 60/220;
// src = 2, weight = 60/220;
// src = 3, weight = 60/220;
dst dist {0:/40,[1:3]:/60}; //:/表示这区间的总权重
// dst = 0, weight = 40/100;
// dst = 1, weight = 20/100;
// dst = 2, weight = 20/100;
// dst = 3, weight = 20/100;
}
:= X 表示区间内的每个元素都是等于权重X
:/ X 表示区间内的每个元素总和等于权重X
rand logic[15 : 0] r, s, t;
constraint c_bidir{
r < t;
s == r;
t < 30;
s > 25;
}
- 约束块是并行的
- 约束是双向的,会同时计算所有的随机变量的约束
class Packet;
rand int length;
constraint c_short {length inside {[1 : 32]}; }
constraint c_long {length inside {[1000 : 1023]};}
end class
Pakcet p;
initial begin
p = new();
p.c_short.constraint_mode(0); //打开c_short约束
assert(p.randomize());
transmit(p);
p.constrain_mode(0);
p.c_short.constraint_mode(1);//关闭c_short约束
assert(p.randomize());
transmit(p);
end
可以使用constraint_mode来打开或者关闭约束
class Transaction;
rand bit[31 : 0] addr, data;
constraint c1{
soft addr inside {[0 : 100], [1000 : 2000];
}
end class
Transaction t;
initial begin
t = new ();
assert(t.randomize() with {addr >= 50; addr <= 1500; data < 10;});
driveBus(t);
assert(t.randomize() with {addr == 2000; data > 10;});
driveBus(t);
end
randomize( ) with 称为:外部约束,内部约束和外部约束之间是协调的
soft 称为:软约束,当软约束与其他约束相背时,软约束失效
class Rising;
byte low;
rand byte med, hi;
constraint up {low < med; med < hi;}
end class
initial begin
Rising r;
r = new();
r.randomize();
r.randomize(med);//只随机化med, 其他为0
r.randomize(low);//同理
end
所有被指定或者没有被指定rand的变量都可以做randomize()的参数被随机化
若一个随机化失败,该随机化过程失败
parameter MAX_SIZE = 10;
class RandStuff;
bit[1 : 0] value = 1;
end class
class RandArray;
rand RandStuff array[];
constraint c{array.size() inside {[1 : MAX_SIZE]};}
function new();
array = new[MAX_SIZE];
foreach(array[i])
array[i] = new();
endfunction;
end class
RandArray ra;
initial begin
ra = new();
assert(ra.randomize());
foreach(ra.array[i])
$display(ra.array[i].value);
end
调用随机函数前要保证句柄数组的每一个句柄元素都是非悬空的
对于多个随机对象,需要在随机化之前分配所有的元素,动态句柄数组的大小可以保持不变或者减小,不能增加