class bathtub;
int value;
int width=50, depth=4, seed=1;
function void pre_randomize();
value=$dist_exponential(seed,depth);
if(value>width) value=width;
if($urandom_range(1)) value=width-value;
endfunction
endclass
随机数函数
$random()——平均分布,返回32位有符号随机数
$urandom()——同上,无符号
$urandom_range(a,b)——在指定范围内同上,上下限位置不限,只有一个表示0-a/b
$dist_exponential()——指数衰落
d
i
s
t
n
o
r
m
a
l
(
)
——钟型分布,还有
dist_normal()——钟型分布,还有
distnormal()——钟型分布,还有dist_poisson()
class uniqueslow
rand bit [7:0] ua[64];
constraint c {
foreach (ua[i])
foreach (ua[j])
if (i!=j) ua[i]!=ua[j];
}
endclass
随机化句柄数组
功能:产生多个随机对象
随机句柄数组一定要加上rand,在调用前保证每一个句柄元素都是非悬空的
在随机化前分配所有的元素,随机化不会创建对象,动态句柄数组的大小只会不变或减小,不会增加
parameter max_size=10;
class randstuff;
bit [1:0] value=1;//不论随机化出多少个句柄。value只有1。如果加上rand,那就可以是其他值
endclass
class randarray;
rand randstuff array[];//存放句柄的动态数组
constraint c{
array.size() inside {[1:max_size];}//约束在1-10个
}
function new();//如果没有这个函数,就报错:句柄不能悬空,在随机化前必须指向对象
array=new[max_size];//给数组分配最大的容量
foreach (array[i])
array[i]=new();//开辟10个句柄空间,句柄指向10个对象
endfunction
endclass
randarray ra;
initial begin
ra=new();//创建10个对象
assert(ra.randomize());//随机化数组的元素,不一定是10个,
foreach (ra.array[i])
$display(ra.array[i].value);
end
随机序列
用randsequence产生原子测试序列
类比case语句,多了权重
initial begin
for (int i=0; i<15; i++) begin
randsequence(stream)//stream序列有三个入口
stream : cfg_read :=1 |
io_read :=2 |
mem_read :=5;
cfg_read :{cfg_read_task;} |
{cfg_read_task;} cfg_read;//用或表示可能执行两种结果,task或者task之后继续这个通道
mem_read :{mem_read_task;} |
{mem_read_task;} mem_read;
io_read :{io_read_task;} |
{io_read_task;} io_read;
endsequence
end
randcase建立随机决策树
缺点:没有变量可供追踪调试
randcase权重在前,冒号后表范围
initial begin
int len;
randcase
1: len=$urandom_range(0,2);//10%的概率是0-2
8: len=$urandom_range(3,5);
1: len=$urandom_range(6,7);
endcase
$display("len=%0d", len);
end