一、定义单个寄存器(uvm_reg)
// 自定义寄存器:32位
class ctrl_reg extends uvm_reg;
`uvm_object_utils(ctrl_reg)
// 1. 声明寄存器字段
rand uvm_reg_field en;
rand uvm_reg_field mode;
// 构造函数:寄存器位宽32
function new(string name="ctrl_reg");
super.new(name, 32, UVM_NO_COVERAGE);
endfunction
virtual function void build();
// 实例化字段
en = uvm_reg_field::type_id::create("en");
mode = uvm_reg_field::type_id::create("mode");
// configure(所属reg,位宽,起始位,权限,volatile,复位值,有复位,可随机,假访问)
en.configure (this, 1, 0, "RW", 0, 1'b0, 1, 1, 0);
mode.configure(this, 2, 1, "RW", 0, 2'b00,1,1,0);
endfunction
endclass
二、建寄存器块 uvm_reg_block
class reg_model extends uvm_reg_block;
`uvm_object_utils(reg_model)
// 声明寄存器
ctrl_reg ctrl_reg;
// 地址映射表
uvm_reg_map reg_map;
function new(string name="reg_model");
super.new(name, UVM_NO_COVERAGE);
endfunction
virtual function void build();
// 1. 创建寄存器
ctrl_reg = ctrl_reg::type_id::create("ctrl_reg");
ctrl_reg.build();
// 2. 创建map:基地址0,地址步长4字节,小端
reg_map = create_map("reg_map", 0, 4, UVM_LITTLE_ENDIAN);
// 3. 寄存器挂到偏移地址 0x00
reg_map.add_reg(ctrl_reg, 32'h00, "RW");
// 4. 锁定ral模型,不能再改
lock_model();
endfunction
endclass
三、在 env 环境里实例化寄存器模型
class my_env extends uvm_env;
`uvm_object_utils(my_env)
reg_model rm; // 寄存器模型
function new(string name="my_env");
super.new(name);
endfunction
virtual function void build_phase(uvm_phase phase);
super.build_phase(phase);
rm = reg_model::type_id::create("rm");
rm.build(); // 必须调用build
rm.reset(); // 复位寄存器默认值
endfunction
endclass
四、test 用例里操作寄存器
class my_test extends uvm_test;
`uvm_object_utils(my_test)
my_env env;
uvm_status_e status;
uvm_reg_data_t rdata;
function new(string name="my_test");
super.new(name);
endfunction
virtual task run_phase(uvm_phase phase);
phase.raise_objection(this);
// 1. 前门写:走总线发写操作
env.rm.ctrl_reg.write(status, 32'h00000005, UVM_FRONTDOOR);
#100ns;
// 2. 前门读
env.rm.ctrl_reg.read(status, rdata, UVM_FRONTDOOR);
`uvm_info("READ",$sformatf("reg read = 0x%0h",rdata),UVM_MEDIUM)
// 3. 只改期望值,不发总线
env.rm.ctrl_reg.set(32'h00000007);
// update:把期望值同步写到硬件
env.rm.ctrl_reg.update(status);
// 4. 后门直接写DUT寄存器(零延时)
env.rm.ctrl_reg.poke(32'h00000009);
// 后门直接读
env.rm.ctrl_reg.peek(rdata);
phase.drop_objection(this);
endtask
endclass
五、顶层 TB 关联寄存器模型(绑定总线 agent)
在 top_tb 里,把reg_model 的 map 和 bus_agent 绑定
env.rm.default_map.set_sequencer(env.bus_agent.sqr);
env.rm.default_map.set_adapter(env.reg_adapter);