在进行验证已编写过的模块时,我们往往需要一些随机的测试方法来检测隐藏的漏洞。

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 donefirst    : add | dec ;           //   执行add  或者 decsecond    : 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 ;        endcaseendcase