SV--随机

a:系统函数:$random/$urandom/$urandom_range,$dist_uniform/$dist_normal/$dist_exponetial/$dist_possion/$dist_chi_square/$dist_t/$dist_erlang。注意返回值的位宽、范围。

b:randcase、randsquence实现分支选择。

c:基于对象的随机。rand/randc申明、randomize、约束:indise/dist/->/if else/foreach/soft约束。

d:标准随机函数stb::randomize();随时对任意变量进行随机化并添加约束。

 

1:  主要使用$urandom_range/$urandom/$random.

       $urandom_randge(max,min):返回32位无符号数,包括边界。

       $urandom(seed):返回32bit无符号数。

       $random(seed)返回32位有符号数,可正可负。

2:randcase

         3:x = 1;

         1:x = 2;

         2:x = 3;

       endcase  // x的随机权重为3:1:2.

       如果权重为0,则不会随机到此条目。此外,权重还可以是任意表达式。

 

3:每次调用randomize都会重新随机。

       randc的变量,在随机完本轮的所有值后,自动开启新周期的随机。

       dist分布注意:/      =/数组中共享此权重。dist操作不能应用于randc变量。缺省值为:=1。

       约束是双向的,注意概率。

       约束仅支持2态值。4态会报错。

       solve a before b,先解a,再解b。

       子类中的约束与基类相同时,那么他会改写基类的约束。

 

       randomize是虚方法,返回int变量,不可改写。sv中还提供pre_/post_randomize函数,可以改写。randomize……with动态修改约束。

       rand_mode、constraint_mode。0表示关闭,1表示打开。默认打开。rand_mode可以关闭句柄中的所有rand变量,也可以关闭某一个变量。

 

4:randomzie……with。

       soft约束,一般用于正常的约束,在异常包时,以后面约束的为准。

 

由于对象class由数据和操作组成,所以对数据的随机化一般放在一个class内。(对环境或环境的配置也可以反映在配置参数的随机化上)

一个constraint包括两部分:rand/randc变量声明,constraint约束块。其中randc会在重复之前,周期性取值,constraint约束块中的变量至少有一个rand/randc

                                     变量,constraint约束块必须在{}内,用;来表示多个约束。约束块是一种声明性的代码,并行运行。

SV中的randomize函数有两种引用方法:

1)直接用任意一个class类型的对象引用,作用在整个class的rand/randc类型变量上。 this.randomize(var),只随机var,但是pre/post_randomize也会被调用

  obj.randomize(null),此时的randomize只是作为一个checker,检查solver是否成功,不是作为一个generator。现有值符合constraint,success返回1,failed返回0。

2)std::randomize(,,,) with {} ,其中()内的变量便是需要random的variable,with表示一些random constraint

                    success = std::randomize(a,b,c) with{a<b,a+b<length} ,随机化成功,返回success为1.

  with约束中的变量如果与调用randomize的obj相同,需要用local::来为变量定位。

3)直接使用$urandom/$urandom_range()等函数。

constraint的引用:一般在一个initial模块或program中引用,采用assert的形式来:assert( p.randomize() );随机化失败后,返回值为0,assert将会打印log,

                         并退出。还有两个隐性function:pre_randomize(),post_randomize(), 可以加入非randomize变量的初始化,同时留下hook。

 

几种约束方式:

1) constraint  longth { low < mid;

                                 mid < high;}    //关系操作符必须分开来写

2)constraint   length { len == mid - low;}    //约束块内不能有赋值语句,相反应该用关系运算符

3)constraint   c_dist  { src_dist {0:= 40, [1:3]:=60;}     //:=后表示权重---相等

                                  dst_dist {0:/ 40,  [1:3]:/ 60};}  //:/后表示权重---比例

4)constraint   c_rang { c inside {[lo:hi]};                       //inside:low-high

                                  b inside {[10:$]};                      //$可以表示边界

                                  !(c inside {[$:30]}); }               //加()可以加!表示非

5)constraint   c_io { (io_space_mode) -> addr[31]==1'b1;    //--->表示if

                              if (op==READ) len inside {[BYTE:WORD]}; }  //--->if--else

6)constraint   c_xy  {(x==0) -> y==0;      //solve..before可能改变解的概率

                                solve x before y;}

7)assert (t.randmize() with {addr > 50;    //内嵌式的约束,addr的作用域是class这一级的,randomize的效果等价

                                         addr < 150;} )

                                       

 

随机化的开关控制:

rand bit[7:0] length;

p.length.rand_mode(0);    //设置包长为非随机值 

 

约束的开关控制:

              p.c_short.constraint_mode(0);   //句柄+约束块+mode,控制这个约束块mode

              p.constraint_mode(0);                //句柄+mode,控制整个句柄的mode

 

对数组的约束:

1)constraint    d_size   {

          d.size inside {[1:10]} ;

                                    d.sum == 4'h4;   }  //sum的位数与数组中的数的位数相同,所以又是可能达不到想要的范围。

 

在实际应用中,应该多用变量来控制约束。  

posted on 2020-01-19 18:58  superany  阅读(2587)  评论(0编辑  收藏  举报

导航