约束的技巧和技术
常用的随机函数
$random() // 平均分布,反回32位有符号的随机数
$urandom() // 平均分布,返回32位无符号随机数
$urandom_range() // 在指定范围内的平均分布
使用$urandom_range函数
initial begin
bit [31:0] data[3];
data[0] = $urandom_range(0,10); // 0~10
data[1] = $urandom_range(5,0); // 0~5
data[2] = $urandom_range(20); // 0~20
end
变量的约束
约束变量的上下限
class transaction;
rand int data;
constraint c_data {
data inside {[1:100]}; // 1~100
}
endclass
带有权重的约束(dist)
typedef enum {DATA8, DATA16, DATA32, DATA64} data_e;
class transaction;
rand data_e data_kind;
constraint c_data_kind {
data_kind dist {
DATA8 := 2,
DATA16 := 1,
DATA32 := 1,
DATA64 := 1
};
}
endclass
例子说明:上述例子中DATA8 DATA16 DATA32 DATA64出现的比例分别为:40% 20% 20% 20%。
注:在缺省的情况下,每一种出现的概率是相等的,可以通过设置权重为0来禁止某种情况。
rand_mode的使用
如果只有少数几个变量需要修改,可以通过使用rand_mode函数来将这些变量设置为非随机变量。
class transaction;
rand bit[31:0] data;
rand bit[31:0] length;
constraint c_data {
data inside {[1:100]};
}
constraint c_length {
length > 0;
}
endclass
initial begin
transaction tr;
tr = new();
// 随机化transaction class中的data和length
assert(tr.randomize());
$display("The value of data is %0d and length is %0d", tr.data, tr.length);
tr.length.rand_mode(0);
tr.length = 100;
assert(tr.randomize());
$display("The value of data is %0d and length is %0d", tr.data, tr.length);
end
constraint_mode的使用
可以通过constraint_mode来实现约束的打开或者关闭
class transaction;
rand bit[31:0] data;
rand bit[31:0] length
constraint c_data {
data inside {[1:10]};
}
constraint c_length {
length == 10;
}
endclass
initial begin
transaction tr;
tr = new();
// 关闭tr中所有的约束
tr.constraint_mode(0);
assert(tr.randomize());
$display("The value of data is %0d and length is %0d", tr.data, tr.length);
// 仅仅打开tr中length的约束
tr.constraint_mode(0);
tr.c_length.constraint_mode(1);
assert(tr.randomize());
$display("The value of data is %0d and length is %0d", tr.data, tr.length);
end
randomize()with的使用
SystemVerilog中允许使用randomize()with来增加额外的约束,这和在类当中增加约束是等效的。
class transaction;
rand bit[31:0] data;
rand bit[31:0] length;
constraint c_data {
data inside {[1:100]};
}
endclass
initial begin
transaction tr;
tr = new();
assert(tr.randomize() with {data == 99; length inside {[1:10]}; });
$display("The value of data is %0d", tr.data);
$display("The value of length is %0d", tr.length);
end
注:在with{}语句当中,SystemVerilog使用了类的作用域,所以上述例子中data和length变量,不是使用tr.data和tr.length。