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