目录
新增内容:
对于类中的属性变量,有的添加了 rand 或者 randc, 有的没有添加,在进行类的randomize() 随机化时,
- 当 randomize() 没有参数时, 只会对 带有rand 和 randc 的变量进行随机。
- 当 randomize(参数)添加参数时,参数可以是任何一个变量,即使那个变量没有 rand 关键字,这个带参数的随机函数只会对参数中的变量进行随机
例:
类中的随机化变量尽量不要使用 带有符号的类型, 会产生随机错误。
例如
把 byte 改成 bit 就不会产生负数了。但是又会产生和多出一位,被舍弃的情况。
我们采取 如下:
在 mcdf 这个项目中 chnl_transaction 中的变量有没有出现这样的问题呢?
可以看到 data 使用了 bit 无符号类型。
其他的属性使用了 int 有符号类型, 但是在约束中都把它们限制到了大于0的 地方。
使用立即断言 来判断 随机化的结果,并给出随机化失败后的 $fatal() 消息打印,还有其他类型的, $info $warning $error $fatal 。
内容:
可以约束动态数组的长度和内容
数组的属性约束:
在多数情况下,数组的大小应该给定范围,防止生成过大体积的数组或者空数组。在约束随机标量的同时,可以对随机化数组进行约束。
例:
class dyn_size;
rand logic [31:0] d[];
constraint d_size {d.size() inside {[1:10]}; }
endclass
可以在约束中结合数组的其他方法sum(), product(), and(), or() 和 xor()。
约束数组的元素:
SV可以利用foreach对数组的每一个元素进行约束,和直接写出固定大小数组的每一个元素的约束相比,foreach要更简洁。针对动态数组,foreach 更适合于对非固定大小数组中每个元素的约束。
例:
class good_sum5;
rand uint len[];
constraint c_len {
foreach (len[i]) len[i] inside {[1:255]};
len.sum() < 1024;
len.size() inside {[1:8]};}
endclass
随机的输出结果是:
sum = 1011, val = 83 249 197 187 152 95 40 8
sum = 1012, val = 213 252 213 44 196 20 54
sum = 370, val = 118 76 176
sum = 976, val = 233 187 44 157 201 81 73
sum = 412, val = 172 167 73
产生唯一元素值的数组:
使用rand:
class UniqueSlow;
rand bit [7:0] ua[64];
constraint c {
foreach (ua[i]) //对数组中的每一个元素操作
foreach(ua[j])
if(i!=j) // 除了元素自己
ua[i] ! = ua[j]; // 和其他元素比较,让值不相等
}
endclass
使用randc:
class randc8;
randc bit [7:0] val;
endclass
class LittleUniqueArray;
bit [7:0] ua[64];
function void pre_randomize();
randc8 rc8 = new();
foreach (ua[i]) begin
assert(rc8.randomize());
ua[i] = rc8.val;
end
endfunction
endclass
(注意:randc 是周期性的产生随机值,例如 randc bit [1:0] a; a的取值范围就是0-3,故每一轮的随机取值可能为 0-1-3-2 ——> 下一轮可能是 2-0-1-3 再下一个周期是 1-3-0-2,每一个周期内的值是唯一的。)
使用unique:
表示限定一个数组,让这个数组里的值在独一无二的范围里
数据约束:
例如下面的代码会报错:
class packet;
rand bit[3:0] da[];
constraint da {
da.size() inside {[3:5]};
foreach (da[i]) da[i] <= da[i+1];
}
endclass
packet p;
initial begin
p = new();
p.randomize() with {da.size() inside {3,5}; };
end
原因:
下面的随机约束da的长度在3或者5,假如是5的话, i=0,1,2,3,4,那么 da[4] <= da[5], da[5]超出了数组的范围, 所以foreach中 i 的取值范围应该是0-3,否则会报错,
应该改为 :
foreach(da[i]) begin
if(i < = da.size() - 2)
da[i] <= da[i+1];
end
随机化句柄数组:
1. 这个数组( array[] )中的每个元素都是个句柄
2. 对这个数组所在类 (RandArray) 进行随机化,ra.randomize()
3. 要求这个数组中的每个句柄在随机化之前,必须实例化,不能悬空,也就是都指向对象
表示为下面的function new(); 函数中
4. 必须对这个句柄数组前加上 rand
5.对这个句柄数组随机化,也就是对这个数组中的每个句柄所指向的对象 随机化
6.因为句柄所指向的对象所在类 RandStuff 中的变量 value 并没有添加 rand,故其值是固定不变的
7.结果显示为:ra.array[i].value = 1;
8.如果bit [1:0] value 前加上rand, 那么结果可能是 ra.array[i].value = 0:3 (0到3之间任意)