rand_mode()

this.fcs.rand_mode(0) //关闭rand
通过修改rand_mode()的参数值,可以允许或禁止随机化;默认情况下的参数为1;语法格式如下:
对象名.成员名.rand_mode(0);//关闭成员的随机化
对象名.rand_mode(0);//关闭所有成员的随机化

pack将一个数组转成单bit数据流

类似并串转换,用在类似spi这种协议

约束的修改有sv的方法和uvm的方法

  • uvm就是extends出来新的transaction ,加约束,然后factory覆盖;代码量有点大

    注册时关掉pack(UVM_NOPACK),然后自己写do_pack

    Randomization Methods 随机化方法

    随机化方法randomize( )是一个虚方法,在遵守有效约束的情况下为对象的所有随机化变量产生随机值;如果随机化成功,该方法会返回1,否则返回0;

    其次,每个类都包括内建的pre_randomize()和post_randomize()方法.一旦调用randomize( ),会在随机化的前后分别调用pre_randomize()和post_randomize()方法.用户可以自定义这两个方法以覆盖内建的方法,这两个方法虽然不是虚方法,但是表现和虚方法类似,当你试图在这两个方法前加上virtual关键字时会报错!

    pre_randomize()可以用来在随机化之前设置一些随机化的条件,例如阻止某些随机变量的随机化;pre_randomize()可以用来在随机化之后检查对象随机化之后的后置条件,如打印随机化的值或者覆盖随机化的值等。
    ref:
    SV之随机化和约束

    sequence 中约束

      virtual task body();
        // Write to the Configuration register and enable transmission of frames
        `uvm_do_with(req, { xtxn_n==WRITE; xtxn_addr==8'h00; xtxn_data==32'h1; } );
        // Write to the Interrupt Mark register and enable all the interrupts
        `uvm_do_with(req, { xtxn_n==WRITE; xtxn_addr==8'h10; xtxn_data==32'hFFFF_FFFF; } );
      endtask : body
    

    Constraint Blocks 约束块

    随机变量可以通过随机化获得随机值,通过对随机变量添加约束可以得到特定范围内的随机值 ;约束必须写在约束块中.

    约束块是类的成员,就像成员变量和成员方法一样,类里面的每一个约束块都要有唯一的块名,如:

    constraint  [name_of_constraint] {  [expression 1];
                                          [expression N]; 
    

    constraint_mode( )

    constraint_mode()方法可以用来禁止约束,默认情况下该方法的参数值为1,表示约束有效;参数为0时,表示约束无效.

    Inline Constraints 附加约束

    (1)附加约束

    允许在调用随机函数的时候添加约束,此时要将定义在类中的约束也与添加约束一起考虑 ,添加的约束叫做附加约束.附加的约束不能和原始约束发生冲突,否则随机化会失败!

    class packet; rand bit [3:0] addr; endclass module inline_constr; initial begin packet pkt; pkt = new(); repeat(2) begin pkt.randomize() with { addr == 8;};//在调用randomize方法时添加约束 $display("\taddr = %0d",pkt.addr); endmodule

    (2)附加的约束函数

    class packet;
      rand bit [3:0] start_addr;
      rand bit [3:0] end_addr;
      constraint end_addr_c { end_addr == e_addr(start_addr); }//调用约束函数
      function bit [3:0] e_addr(bit [3:0] s_addr);
        if(s_addr<0)
          e_addr = 0;
            e_addr = s_addr * 2;
      endfunction
    endclass
    module func_constr;
      initial begin
        packet pkt;
        pkt = new();
        repeat(3) begin
          pkt.randomize();
          $display("\tstart_addr = %0d end_addr =",pkt.start_addr,pkt.end_addr);
    endmodule
    

    Soft Constraints 软约束

    举个例子,父类中的约束为constraining a < 10,子类中的约束为 constraining a > 10,这样两个约束会发生互斥而导致随机化的失败.解决这一问题的方法就是使用软约束,格式如下:

    constraint c_name { soft variable { condition }; }
    class packet;
      rand bit [3:0] addr;
      constraint addr_range {soft addr > 6; }
    endclass
    module soft_constr;
      initial begin
        packet pkt;
        pkt = new();
        repeat(2) begin
          pkt.randomize() with { addr < 6;};//内嵌约束与类中的约束矛盾,会导致随机化失败
          $display("\taddr = %0d",pkt.addr);
    

    当正常约束与软约束发生矛盾时,软约束被正常约束抑制 .

  •