基于寄存器模型的32位寄存器Byte访问测试指南
笔者对该测试项测试时候没有注意到集成在环境里的寄存器模型可以实现Byte访问测试的功能。所以我是直接通过总线发送sequence进行测试,当地址不连续,期望读取数据复杂的时候,扫描所有寄存器加大了工作量,重复性的工作非常浪费时间。所以给出一下代码,希望对大家有帮助提高大家的工作效率
在UVM和SystemVerilog中,可以通过以下步骤来实现对32位寄存器的按byte写入和分段读取,并对读取回来的数据和期望数据进行对比,并在出现错误时进行报错。给出一段展示用代码
步骤 1:定义寄存器模型
首先,定义一个寄存器模型类,继承自 uvm_reg
。
class my_reg extends uvm_reg;
`uvm_object_utils(my_reg)
uvm_reg_field field;
function new(string name = "my_reg");
super.new(name, 32, UVM_NO_COVERAGE);
endfunction
virtual function void build();
field = uvm_reg_field::type_id::create("field");
field.configure(this, 32, 0, "RW", 1, 32'hFFFF_FFFF, 1, 0, 0);
endfunction
endclass
步骤 2:定义寄存器块和环境
定义寄存器块和环境
class my_reg_block extends uvm_reg_block;
`uvm_object_utils(my_reg_block)
my_reg reg0;
function new(string name = "my_reg_block");
super.new(name, UVM_NO_COVERAGE);
endfunction
virtual function void build();
reg0 = my_reg::type_id::create("reg0");
reg0.configure(this);
reg0.build();
this.default_map.add_reg(reg0, 'h0000, "RW");
endfunction
endclass
class my_env extends uvm_env;
`uvm_component_utils(my_env)
my_reg_block reg_block;
function new(string name, uvm_component parent);
super.new(name, parent);
endfunction
virtual function void build_phase(uvm_phase phase);
super.build_phase(phase);
reg_block = my_reg_block::type_id::create("reg_block", this);
reg_block.build();
endfunction
endclass
步骤 3:在测试用例中进行按byte写和读操作
在测试用例中进行寄存器的写入和分段读取操作,并对读取回来的数据和期望数据进行对比
class my_test extends uvm_test;
`uvm_component_utils(my_test)
my_env m_env;
function new(string name, uvm_component parent);
super.new(name, parent);
endfunction
virtual function void build_phase(uvm_phase phase);
super.build_phase(phase);
m_env = my_env::type_id::create("m_env", this);
endfunction
virtual task run_phase(uvm_phase phase);
uvm_status_e status;
uvm_reg_data_t read_data, expected_data;
uvm_reg_map map;
uvm_reg_addr_t addr;
// 写入32位寄存器
m_env.reg_block.reg0.write(status, 'hFFFF, UVM_FRONTDOOR, .parent(this));
map = m_env.reg_block.default_map;
addr = 'h0000;
// 分段读取第1, 2, 4, 8字节
foreach ({1, 2, 4, 8} i) begin
map.read(status, read_data, addr, i, UVM_FRONTDOOR, .parent(this));
case (i)
1: expected_data = 'hFF;
2: expected_data = 'hFFFF;
4: expected_data = 'hFFFF_FFFF;
8: expected_data = 'hFFFF_FFFF_FFFF_FFFF; // Adjust based on your actual test
default: expected_data = 'h0;
endcase
if (read_data !== expected_data) begin
`uvm_error("DATA_MISMATCH", $sformatf("Read data %h does not match expected data %h", read_data, expected_data))
end else begin
`uvm_info("DATA_MATCH", $sformatf("Read data %h matches expected data %h", read_data, expected_data), UVM_LOW)
end
end
endtask
endclass
步骤 4:在测试台中运行测试
在测试台中实例化环境并运行测试。
module tb; import uvm_pkg::*; `include "uvm_macros.svh" initial begin run_test("my_test"); end endmodule
通过以上步骤,您可以实现对32位寄存器的写入和分段读取,并对读取回来的数据和期望数据进行对比,在出现错误时进行报错。这样,您可以确保数据的一致性和正确性。
作者:Fish6657