1.随机属性关键字
- 随机属性的关键字是
rand
,通常用于修饰class中的成员变量。此外还有randc
表示周期随机性,所有可能值都出现过后才可能重复。 - 通过使用
std::randomize()
函数才能对声明了rand
的变量进行随机化。
assert (xx.randomize()) else $fatal(0, "xx::randomize failed");
- sv只能随机化二值数据类型,无法随机化出x值和z值。
2.随机约束和分布
-
不同仿真器对于同一个约束类和种子值求解出的数值可能是不相同的。
-
关键词
dist
可以在约束中产生随机数值的权重分布。使用:=
表示每一个值的权重是相同的,:/
表示权重平分到每一个值。 -
inside
是常用的约束运算符。使用$
可以指定最大值和最小值。 -
->
或者if-else
可以让约束表达式在特定时刻有效。
class xx;
rand bit [2:0] example;
constraint ex{
//example inside {[1:3]};
//example dist{0:=40, [1:3]:=60};
(mode) -> example='d1;
}
endclass
※约束块不像自上向下的程序性代码,是并行同时有效的,需要得到同时满足约束的结果。
3.约束块控制
- 一个class中可以包含多个约束块,一般情况下各个约束块之间的约束内容是相互协调的。对于其它情况可以通过
constraint_mode()
函数1
打开或0
关闭约束。 - sv可以通过使用
randomize() with
来增加约束。
assert (x.randomize() with {xx>=100; xx<=200;});
- 当内部约束和外部约束相互冲突时,有
soft
修饰的优先级低。
4.随机函数
pre_randomize()
和post_randiomize()
函数是sv预定义的两个void类型函数,对象在执行randomize()
之前或者之后会分别执行这两个函数。- 其它系统随机函数:
$random()
、$urandom()
、$urandom_range()
均返回平均分布。 - 通过
random(xx)
可以对个别变量(无论是否指定rand
)进行随机化。
5.数组约束
- 随机动态数组–> 数组的长度和内容均可对其进行
random
。此时无需对动态数组进行new()
。
class darray_ex;
rand int len[];
constraint c_len{
foreach(len[i]) len[i] inside {[1:255]};
len.sum() < 1024;
len.size() inside {[1:8]};
}
endclass
- 随机句柄数组。在调用其所在类的随机函数时,随机函数会随机化数组中的每一个句柄所指向的对象。所以需要保证句柄数组声明添加
rand
保证其随机化属性,同时在调用随机函数前要保证句柄数组中的每一个句柄元素都是非悬空的。
class randarray;
rand xx array[];
constraint c{
array.size() inside {[1: MAX_SIZE]};
}
function new();
array = new[MAX_SIZE];
foreach(array[i])
array[i] = new();
endfunction;
endclass
※随机化后,数组array
会进行随机,相应的句柄也会进行随机,如果class中的成员变量被rand
进行修饰了则相应的成员变量也会进行随机化。
6.随机控制
randsequence
和randcase
针对轻量级随机控制的应用。