做scoreboard时已经完成了不同位数的对比
-----------------------建立rkv_ahbram_diff_hsize_virt_seq并添加到头文件
目的再smoke_seq基础上添加hsize为8、16、32的随机传输测试
`ifndef RKV_AHBRAM_DIFF_HSIZE_VIRT_SEQ_SV
`define RKV_AHBRAM_DIFF_HSIZE_VIRT_SEQ_SV
class rkv_ahbram_diff_hsize_virt_seq extends rkv_ahbram_base_virtual_sequence;
`uvm_object_utils(rkv_ahbram_diff_hsize_virt_seq)
function new (string name = "rkv_ahbram_diff_hsize_virt_seq");
super.new(name);
endfunction
virtual task body();
bit [31:0] addr, data;
burst_size_enum bsize;//加入bsize
super.body();
`uvm_info("body", "Entered...", UVM_LOW)
for(int i=0; i<100; i++) begin
std::randomize(addr) with {addr[1:0] == 0; addr inside {['h1000:'h1FFF]};};
std::randomize(wr_val) with {wr_val == (i << 8) + i;};
//bsize的随机化限制
std::randomize(bsize) with {bsize inside {BURST_SIZE_8BIT, BURST_SIZE_16BIT, BURST_SIZE_32BIT};};
data = wr_val;
`uvm_do_with(single_write, {addr == local::addr; data == local::data; bsize == local::bsize;})
`uvm_do_with(single_read, {addr == local::addr; bsize == local::bsize;})
rd_val = single_read.data;
case(bsize)//根据bsize位数进行compare_data
BURST_SIZE_8BIT : compare_data(wr_val & 32'hFF , rd_val & 32'hFF);
BURST_SIZE_16BIT : compare_data(wr_val & 32'hFFFF, rd_val & 32'hFFFF);
BURST_SIZE_32BIT : compare_data(wr_val , rd_val );
default : `uvm_error("TYPEERR", "burst size not recognized")
endcase
end
`uvm_info("body", "Exiting...", UVM_LOW)
endtask
endclass
`endif
做完vir_seq后建立diff_hsize_test与smoke_test相似
`ifndef RKV_AHBRAM_DIFF_HSIZE_TEST_SV
`define RKV_AHBRAM_DIFF_HSIZE_TEST_SV
class rkv_ahbram_diff_hsize_test extends rkv_ahbram_base_test;
`uvm_component_utils(rkv_ahbram_diff_hsize_test)
function new (string name = "rkv_ahbram_diff_hsize_test", uvm_component parent);
super.new(name, parent);
endfunction
function void build_phase(uvm_phase phase);
super.build_phase(phase);
endfunction
task run_phase(uvm_phase phase);
rkv_ahbram_diff_hsize_virt_seq seq = rkv_ahbram_diff_hsize_virt_seq::type_id::create("this");
super.run_phase(phase);
phase.raise_objection(this);
seq.start(env.virt_sqr);
phase.drop_objection(this);
endtask
endclass
`endif
------------------diff_haddr_virt_seq:相对于smoke_test把约束地址改为cfg.addr_start : cfg.addr_end
循环次数为 i <(cfg.addr_end>>4)
`ifndef RKV_AHBRAM_DIFF_HADDR_VIRT_SEQ_SV
`define RKV_AHBRAM_DIFF_HADDR_VIRT_SEQ_SV
class rkv_ahbram_diff_haddr_virt_seq extends rkv_ahbram_base_virtual_sequence;
`uvm_object_utils(rkv_ahbram_diff_haddr_virt_seq)
function new (string name = "rkv_ahbram_diff_haddr_virt_seq");
super.new(name);
endfunction
virtual task body();
bit [31:0] addr, data;
super.body();
`uvm_info("body", "Entered...", UVM_LOW)
for(int i=0; i<(cfg.addr_end >>4); i++) begin//base_test中定义cfg.addr_start = 32'h0;cfg.addr_end = 32'h0000_FFFF;
std::randomize(addr) with {addr[1:0] == 0; addr inside {[cfg.addr_start:cfg.addr_end]};};
std::randomize(wr_val) with {wr_val == (i << 8) + i;};
data = wr_val;
`uvm_do_with(single_write, {addr == local::addr; data == local::data;})
`uvm_do_with(single_read, {addr == local::addr;})
rd_val = single_read.data;
compare_data(wr_val, rd_val);
end
`uvm_info("body", "Exiting...", UVM_LOW)
endtask
endclass
`endif
diff_addr_test与smoke_test类似,只是更换了virt_seq;
----------------------------rkv_ahbram_reset_w2r_virt_seq
目的是在smoke正常SINGLE读写检查时,将地址存到队列addr_q[$]中。
然后调用接口的assert_reset函数重置DUT,再将之前存入的地址取出,并进行读操作从DUT读取mem的数据。
`ifndef RKV_AHBRAM_RESET_W2R_VIRT_SEQ_SV
`define RKV_AHBRAM_RESET_W2R_VIRT_SEQ_SV
class rkv_ahbram_reset_w2r_virt_seq extends rkv_ahbram_base_virtual_sequence;
`uvm_object_utils(rkv_ahbram_reset_w2r_virt_seq)
function new (string name = "rkv_ahbram_reset_w2r_virt_seq");
super.new(name);
endfunction
virtual task body();
bit [31:0] addr, data;
bit [31:0] addr_q[$];
super.body();
`uvm_info("body", "Entered...", UVM_LOW)
// normal write -> read check
for(int i=0; i<10; i++) begin
std::randomize(addr) with {addr[1:0] == 0; addr inside {['h1000:'h1FFF]};};
std::randomize(wr_val) with {wr_val == (i << 4) + i;};
addr_q.push_back(addr);
data = wr_val;
`uvm_do_with(single_write, {addr == local::addr; data == local::data;})
//`uvm_do_with(single_write, {addr == local::addr; data == 'hff;})
`uvm_do_with(single_read, {addr == local::addr; })
rd_val = single_read.data;
compare_data(wr_val, rd_val);
end
// trigger reset
vif.assert_reset(10);
// read check after reset
do begin
addr = addr_q.pop_front();
`uvm_do_with(single_read, {addr == local::addr; })
rd_val = single_read.data;
if(cfg.init_logic === 1'b0)//注意是===,对z和x都要比较
compare_data(32'h0, rd_val);
else if(cfg.init_logic === 1'bx)
compare_data(32'hx, rd_val);
else
`uvm_error("TYPEERR", "type is not recognized")
end while(addr_q.size() > 0);
`uvm_info("body", "Exiting...", UVM_LOW)
endtask
endclass
`endif