systemverilog 随机化操作
在进行验证已编写过的模块时,我们往往需要一些随机的测试方法来检测隐藏的漏洞。
sv相比于verilog而言,在随机化上则是非常有力,有许多关于随机化的操作。
===================================================
一 随机数据:
一般而言随机化的操作都是需要封装成为类的。
class Bus; rand bit[15:0] addr; rand bit[31:0] data; constraint word_align {addr[1:0] == 2’b0;} endclass
这是个简单的例子,只要在类的数据类型前加上了rand或者randc,那么只要对这个类的实例化
对象调用randomize()方法,这些带有rand与randc的数据类型则是会被随机化。
但往往随机化并非完全的随机化,很多时候需要有一定的限制,所以还需要使用constraint语句
构造约束条件。
其中约束有很多种:
(1)表达式约束:
constraint word_align {addr[1:0] == 2’b0; data < 32 }
(2)条件约束:
class MyBus extends Bus; rand AddrType atype; constraint addr_range { (atype == low ) -> addr inside { [0 : 15] }; (atype == mid ) -> addr inside { [16 : 127]}; (atype == high) -> addr inside {[128 : 255]}; // ( 先前的条件 )-> (相应的约束) } endclass
条件约束可以使用->的方式也可以使用if-else的方式。只有当先前的条件满足时才可以进行后面的约束。
(3)嵌套约束:
task exercise_bus (MyBus bus); int res; // EXAMPLE 1: restrict to low addresses res = bus.randomize() with {atype == low;}; // EXAMPLE 2: restrict to address between 10 and 20 res = bus.randomize() with {10 <= addr && addr <= 20;}; // EXAMPLE 3: restrict data values to powers-of-two res = bus.randomize() with {data & (data - 1) == 0;}; endtask
在randomize()方法后使用with { } 加入约束的条件。
(4)权重约束:
x dist { [100:102] := 1, 200 := 2, 300 := 5} // 其中在:=前的每个元素的权重值都为:=后的值 x dist { [100:102] :/ 1, 200 :/ 2, 300 :/ 5} // 其中在:/前的每个元素平分:/后的权重值
二 随机序列:
randsequence ( main ) main : first second done ; // 从main处顺序执行 first second done first : add | dec ; // 执行add 或者 dec second : pop | push ; done : { $display("done"); } ; add : { $display("add"); } ; dec : { $display("dec"); } ; pop : { $display("pop"); } ; push : { $display("push"); } ; endsequence
三 决策树:
randcase 3 : x = 1; // :前的值为相应的权重 1 : x = 2; 4 : x = 3; 6 : randcase 4 : x = 4 ; 5 : x = 5 ; endcase endcase
CONTRAINT 约束
本篇主要介绍一些 systemverilog 中的 constraint。
我们可以用> < >= <=
等符号来对变量进行简单的约束, 注意的是当要把某个变量设为定值时, 需要使用==
符号。
比如下面的例子:
1
|
class myClass;
|
那么运行的结果就是:
1
|
source ../edaTools/cadence/INCISIV131/tools/inca/files/ncsimrc
|
2. inside 表达式
(1) 也可以使用inside
关键字申明变量的范围或者申明变量只能取某些特定的值, 比如:
1
|
constraint my_range { typ > 32;
|
(2) 如果加上符号!
表示变量不在某个范围内
1
|
rand bit [2:0] typ;
|
3. 权重分布
当在随机化变量的时候, 需要某些值出现的更加频繁一些。 就可以用关键字dist
进行权重的约束。
:=
表示的是, 对于指定范围的值, 权重都一样, 比如 [1:5]:=50;表示的是 [1:5] 范围的任何一个值, 其权重都是 50;
:/
表示的是, 对于指定范围的值, 权重均分, 比如 [1:5]:=50;表示的是 [1:5] 范围的任何一个值, 其权重都是 10;
1
|
rand bit [2:0] typ;
|
上面约束表示的含义是: 0 的权重是 20, 6 是 40, 7 是 10, 1:5 中的每个数都是 50. 总共 320, 那么选择 0 的概率就是 20/320
1
|
rand bit [2:0] typ;
|
这个约束表示的含义就不同了, 选中 0 的概率就是 20/100
4. 多重约束
多重约束存在时, 取的是交集:
1
|
class myClass;
|
比如上面的例子, val 的值被约束在了 [10, 12)
5. implication 约束
implication 约束使用的符号是->
, 代表的是某两个或者多个变量之间的关系。 有些类似于if - else
申明。
1
|
class ABC;
|
上面例子的运行结果为:
1
|
ncsim> run
|