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

本文探讨了SystemVerilog中randomize()函数的使用注意事项,包括变量命名冲突、数值约束、数组约束、依赖变量处理、预随机化策略、条件约束等关键概念。深入解析了如何避免常见错误,实现更高效、准确的随机化测试。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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

 

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,只去了最低位的1bit。

      推薦的寫法是不指定位寬,直接這樣寫:

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

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

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

元直数字电路验证

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值