SystemVerilog中randomize() with{}注意事項

SystemVerilog中randomize() with{}注意事項

原文链接:https://blog.csdn.net/gsjthxy/article/details/87872574

尊重别人的知识产权就是尊重自己的人格!

本文要求你对SV的约束要有一些了解,文中的知识点是跳跃模式的,所以理解起来很能会有些费力!但是,不可否认,这篇文章还是很有价值一读!

1、双等号左右两边的变量名不能相同。如果相同,求解器会认为两边是一样的,导致约束不生效,例如:

一定要避免这样的错误!!!

class dma_seq extends uvm_sequence #(dma_trans);
 
  bit [39:0]          addr;
 
  `uvm_do_with(req, {
    
    req.addr == addr;})
 
endclass : dma_seq

2、假如要约束addr为0x0000_000C,下面的写法是不行的:

  addr == 1'hC;

  这种情况下addr永远是0,只定义了最低的1位bit。

  你应该这样写:
rand_states = (glb_cfg.randomize() with {
    
    
 
  glb_cfg == 'hC;
})

不要写明它的位宽,让编译器去猜。

3、SystemVerilog中constraint指定不等于。

class user_mem_mam_policy extends uvm_mem_mam_policy;
  bit [31:0]    offset;
  
  constraint policy_offset_cons{
    
    
    start_offset % 8 != 0;
 
  }
 
endclass : uvm_mem_mam_policy

对8取模的结果不能是0!

4、SystemVerilog中约束数组。注意,在SystemVerilog中,16位数字的和还是用16位数字表示的,所以这样写会导致数组溢出。如果有sum的约束,需要增大所声明的数组的位宽。

//约束数组
bit [15:0]    dma_rd_len[];
constraint c_dma_rd_len{
    
    
  foreach(dma_rd_len[i]){
    
    
    dma_rd_len[i] dist {
    
    128:=20, 256:=20, [0:127]:/20, [129:255]:/20};
  }
 
}
 
constraint c_dma_rd_len_sum_con{
    
    
  dma_rd_len.size() == 655350;
 
}

(实际上,这样文章的内容上有很多知识点!但是都默认你是会的情况下)

5、在task中产生一个随机数,可以做如下约束:

function void pre_randomize();
  std::randomize(sub_payload_num) with {
    
    sub_payload_num inside {
    
    [1:255]};};
endfunction : pre_randomize
      注意:在class A中使用pre_randomize产生的数据,如果在class B中执行力下面所示的程序,那么class A用pre_randomize产生的数据会被覆盖。如果不希望该数据会被覆盖掉,就要将这个randomize放在post_randomize()中。

A = new(); 
 
assert(A.randomize) else `uvm_error(get_full_name(), "A randomize error")

6、如果两个变量存在依赖关系,在randomize中可以这样写:

下面例子中的->相当于if语句,左边的表达式成立之后,才做约束。

constraint cst_cm_type {
    
    
  cm_type dist {
    
    WRITE:=10, READ:=10};
  cm_type == WRITE -> cm_count dist {
    
    [1:63]};
  cm_type == READ  -> cm_count dist {
    
    [1:42]};
}

7、在pre_randomize()中可以拿到plusargs的值,从而決定randomize的策略。如下面的例子:

class  irq_test_vseq extends l0_base_vseq;
  bit [1:0]                        slow_mode;
 
 
  function new(string name = "irq_test_vseq");
    super.new();
  endfunction
  function pre_randomize();
    super.pre_randomize();
    $value$plusargs("RETRIGGER=%0d", slow_mode);
  endfunction
 
endclass

8、在randomize with{}语句中,可以使用if-else,但是if-else语句要用大括号包起来,不能使用begin-end

class uvm_axi_cfg extends svt_axi_system_configuration;
 
  `uvm_object_utils(uvm_axi_cfg)
 
  bit [0:0]                    slow_mode;
 
  function new(string name = "uvm_axi_cfg");
    super.new();
    $value$plusargs("SLOW_MOD=%0d", slow_mode);
 
    slavecfg[0].randomize() with {
    
    
      axi_interface_type == AXI3;
      data_width         == 32;
      id_width           == 4;
      addr_width         == 32;
    }
 
    if(slow_mode == 'h1) {
    
    
      default_arready == 1'b0;
      default_awready == 1'b0;
      default_wready  == 1'b0;
    }
    else if(slow_mode == 'h0) {
    
    
      default_arready == 1'b1;
      default_awready == 1'b1;
      default_wready  == 1'b1;
    }
  endfunction
 
endclass

版权声明:本文为CSDN博主「gsithxy」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/gsjthxy/article/details/87872574

猜你喜欢

转载自blog.csdn.net/weixin_46259642/article/details/115276672