本节主要介绍了SystemVerilog中产生随机数的方法以及约束块的使用
随机变量
任何类中的整形(bit/byte/int)变量、定长数组,动态数组、关联数组和队列都可以声明为rand/randc,可以对动态数组和队列的长度加以约束,非组合型结构体可以声明为rand
只能用类这个“载体”去容纳变量以及它们之间的约束关系
module里面不能用rand
对于rand修饰符,表示在可生成的范围内,每个值得可能性是相同的
对于randc修饰符,它的值将会随机并且遍历其可取值范围,即取出后的数不放回,等全部取出后再在取值范围内重新抽取
产生随机数的方式:
- 通过系统函数
std::randomize(var)
产生随机数并赋予变量 var = $urandom()
//可以产生一个32位的无符号随机数var = $urandom_range(maxval, minval = 0)
// 可以生成在maxval与minval之间的数.randomize()
的数据类型只能是类
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41//类中存放一些随机数
class packet;
rand bit [31:0] src, dst, data[4];
rand bit [7:0] kind;
constraint cstr{
src > 10;
src < 15;
}
function void print();
$display("src is %0d\n dst is %0d\n kind is %0d\n data is &p", src, dst, kind, data);
endfuntion
endclass
module tb;
packet p;
initial begin
p = new();
$display("before randomize");
p.print();
p.randomize(); //使用.randomize()随机化类中的变量
$display("after randomize");
p.print();
end
endmodule
//结构体中存放一些随机数
typedef struct{
rand bit [31:0] src;
rand bit [31:0] dst;
rand bit [31:0] data[4];
rand bit [7:0] kind;
} packet_t;
module tb2;
packet_t pkt;
initial begin
$display("before randomized packet struct:: src %0d\n kind is %0d\n kind is %0d\n data is %p", pkt.src, pkt.dst, pkt.kind, pkt.data);
std::randomize(pkt) with {src > 10; src < 15} //in-line constraint 内联约束
$display("before randomized packet struct:: src %0d\n kind is %0d\n kind is %0d\n data is %p", pkt.src, pkt.dst, pkt.kind, pkt.data);
end
endmodule- 通过系统函数
约束块
约束块支持整形通过
constraint
操作符来设置它们的可取值范围1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22class set_rand;
rand integer x, y, z;
constraint c1 {x inside {3, 5, [9:15], [24:32], [y:2*y], z};}
rand integer a, b, c;
constraint c2 {a inside {b, c};}
integer fives[4] = '{5, 10, 15, 20};
rand integer v;
constraint c3 {v inside {fives};}
//unique可以用来约束一组变量,使得其在随机后变量之间不会有相同的数值
rand byte a[5];
rand byte b;
rand byte excluded;
constraint u {unique {b, a[2:3], exclude};}//这里a[2]、a[3]、b和excluded在随机之后将包含不相同的数值
constraint exclusion {excluded == 5;}
//使用->操作符来表示条件约束
bit [3:0] a, b;
constraint c {(a == 0) -> (b < 10)} //表示如果a等于0,那么b就随机取小于10的数
endclass权重分布:
对于
:=
操作符,它们表示每一个值的权重是相同的对于
:/
操作符,它们表示权重会平均分配到每一个值1
2x dist {[100:102] := 1, 200 := 2, 300 := 5} //x在100,101,102,200和300的权重是1-1-1-2-5
x dist {[100:102] :/1, 200 := 2, 300 := 5} //x在100,101,102,200和300的权重是1/3-1/3-1/3-2-5
- 软约束:
- 在没有soft描述约束时,称为硬约束,带有
soft
描述的约束是软约束 - 硬约束的父类子类,若对同一变量:约束同名则覆盖,若不同名则取交集;此外,硬约束可以覆盖软约束
- 若都是软约束,则遵循最近的软约束
- 在没有soft描述约束时,称为硬约束,带有
随机控制与约束控制
1.随机控制
rand_mode()
可以用来使能(1)或禁止(0)随机变量1
2
3
4
5
6
7
8
9
10class packet;
rand bit [31:0] src, dst, data[4];
rand bit [7:0] kind;
...
endclass
Packet packet_a = new();
packet_a.rand_mode(0); //禁止类中所有随机变量
packet_a.src.rand_mode(1);//使能某个随机变量
2.约束控制
- 类似的,约束中使用
constraint_mode()
来使能或禁止约束块