第六章:随机化

Posted xuqing125

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了第六章:随机化相关的知识,希望对你有一定的参考价值。

随着设计变得越来越复杂,要想产生一个完整的激励集来测试设计的功能也变得越来越困难。采用受约束的随机测试法(CRT)自动产生测试集是目前的一种主要的方法。CRT由两部分组成:使用随机的数据流为DUT产生输入的测试代码,以及伪随机数发生器的种子。

6.1 什么需要随机化

在产生随机化的激励时,我们最容易想到的就是使用$random函数。但是这种方法找bug的能力是十分有限的,它只能找到数据路径的问题,或者是bit级别的错误。从某种意义上讲,这种方法还是基于定向测试。那些具有挑战性的bug大都在控制路径里面。因此,必须对DUT里所有关键点都采用随机化技术。随机化使控制路径里每一个分支都可能被测试。你需要考虑设计输入下列的各个方面。

  • 器件配置
  • 环境配置
  • 原始输入数据
  • 封装后的输入数据
  • 协议异常
  • 延时
  • 事务状态
  • 错误和违规

    6.2 SystemVerilog中的随机化

    基于OOP使用SystemVerilog中的随机激励产生是最有效的。首先,建立一个具有一组相关的随机变量的类,然后用随机函数为这些变量赋随机值,你可以用约束来限制这些随机值的范围,使他们是有效的值,也可以某些专用的功能。
    技术分享图片
  • rand:每次随机化这个类,这些变量都会赋一个值。就好像掷骰子,每掷一次就产生一个新的数字。
  • randc:表示周期性随机。就好像从一副牌里一张一张地、随机抽出所有的牌,洗牌后再按另一个顺序随机地抽出牌。
  • constraint:约束的条件放在{}里面,而不是begin---end里面。
  • randomize():函数遇到约束方面的问题时,返回0.如果随机化成功则返回1.
  • assert:判断随机化有没有成功。
  • $fatal:用来结束仿真。
    注意:
    1、不能在类的构造函数里随机化对象。
    2、constraint中受到约束的变量必须是声明成rand或者randc类型。

    6.2.1 简单的表达式

    在一个表达式中最多只能使用一个关系操作符。

        class order;
               rand bit[7:0] lo,med,hi;
               constraint bad {lo<med<hi;}
        endclass

    lo<med<hi会被划分成(lo<med)<hi,(lo<med)会得到一个布尔函数值0或1,然后与hi相比较。显然结果并不是我们想要的。正确的写法如下:

       class order;
               rand bit[7:0] lo,med,hi;
               constraint good {lo<med;
                                med<hi;}
      endclass
    6.2.2 权重分布
    dist操作符允许产生权重分布,这样的话某些值得选取机会就会比其他值大一些。
  • :=表示值范围内的每一个值得权重是相同的。
  • :/表示权重要均分到值范围内的每一个值。
  • 值可以是一个值,也可以是一个范围,例如[lo:hi]

       class test;
          rand int src,dst;
          constraint c {
                         src dist {0:=40,[1:3]:=60;}
                         dst dist {0:/40,[1,3]:/60;}
                              }
        endclass

    src=0 40/220
    src=1 60/220
    src=2 60/220
    src=3 60/220
    dst=0 40/100
    dst=1 20/100
    dst=2 20/100
    dst=3 20/100

    6.2.3 集合成员和inside运算符

    可以用inside运算符产生一个值的集合。

       class test;
          rand int src;
          constraint c {
                         src inside {[0:3]};
                              }
       endclass
  • inside {lo:hi};lo<hi,否则的话为空集;
  • $,可以代表取值范围的最大值和最小值;
  • !取反操作符可以选取集合范围之外的数据;

    6.2.4 在集合里使用数组
    技术分享图片
    技术分享图片
  • 对数组里面的每一个值的取值的概率都相等。

    6.2.5 条件约束

    通常约束块里所有的约束表达式都是有效的,但怎样才能只让一个表达式在某些情况下有效呢?SystemVerilog支持两种关系操作符:->和if-else。

      class BusOp;
             ......
      constraint c {(io_space_mode) ->
                   addr[31]==1‘b1;
                  }

    if-else并不是包含在begin-end块中,而是放在constraint的{}中。

    6.2.6双向约束

    约束块并不想自上而下执行的程序性代码,它们是声明性代码,是并行的,所有的约束表达式同时有效。
    就算是在条件约束中,if-else语句中,并不是if中的语句成立才执行才执行下一条语句,而是所有的语句事先都已经知道。

    6.3 解的概率

    提到随机,那么概率必然与之相随。SystemVerilog并不能保证求解器能够给出确定的解,但是我们可以干预解得概率分布。

    6.4 控制多个约束块

    在一个类中可以包含多个约束块。那么我们应该如何去控制这些约束呢?
    在运行期间,可以使用constraint_mode()函数来打开或者关闭约束。

       class Test;
          rand int src;
          constraint c {
                         src inside {[0:3]};
                              }
         constraint c_1 {
                         dst inside {[0:3]};
                              }
        endclass
    
     Test t;
       initial begin
         t=new();
        t.c.constraint_mode(0);//关闭c
        assert(t.randomize());
        t.constraint_mode(0); //关闭所有的限制c和dst
        t.c_1.constraint_mode(1);//打开c_1这个约束
  • t.c.constraint_mode(0);//关闭c
  • t.constraint_mode(0); //关闭所有的限制c和dst
  • t.c_1.constraint_mode(1);//打开c_1这个约束

    6.5 内嵌约束

    SystemVerilog允许使用randomize()with来增加额外的约束,这和在类里增加约束是等效的。

     class Test;
          rand int src;
          constraint c {
                         src inside {[0:3]};
                              }
       endclass
    
    Test t;
     initial begin
        t=new();
     assert(randomize() with {src>2});
    end

    注意:在此处,with{}语句里面类似于作用域,但是使用了变量src而不是t.src.















以上是关于第六章:随机化的主要内容,如果未能解决你的问题,请参考以下文章

第六章:随机化(续1)

第六章 函数和调试

第六章.解决大问题

第六章 自然的数学化和分析化

《JVM系列》 第六章 -- 对象的实例化与内存布局

第六章 函数和宏定义实验