寄存器模型集成的写法
第一种写法:
当driver将读取值返回后,寄存器模型会更新寄存器的镜像值和期望值。这个功能被称为寄存器模型的自动预测功能auto_predict;
在建立寄存器模型时,使用如下语句打开此功能:rm.default_map.set_auto_perdict(1)
function void base_test::build_phase(uvm_phase phase);
super.build_phase(phase);
rm = reg_model::type_id::create("rm", this);
rm.configure(null, "");//parent block;后门访问路径
rm.build();//将所有的寄存器实例化
rm.lock_model();//调用此函数后,reg_model中就不能再加入新的寄存器
rm.reset();//不调用此函数,reg_model中所有寄存器的值都是零,调用后,所有寄存器的值为设置后的reset的值;
rm.set_hdl_path_root("top_tb.my_dut");//后门访问路径
//利用后门路径访问寄存器时,需要在reg_block中调用configure函数,设置好第三个路径;
reg_sqr_adapter = new("reg_sqr_adapter");
// Set this bit in extensions of this class if the bus driver provides separate response items.
reg_sqr_adaper.provides_responses = 1;//put response to sequencer
endfunction
function void base_test::connect_phase(uvm_phase phase);
super.connect_phase(phase);
//寄存器模型的前门访问操作最终都是由uvm_reg_map完成,因此在connect_phase中,
//需要将转换器和bus_sequencer通过set_sequencer函数告知reg_model的default_map;
rm.default_map.set_sequencer(env.bus_agt.sqr, reg_sqr_adapter);
rm.default_map.set_auto_predict(1);//将default_map设置为自动预测状态;
endfunction
第二种写法:
monitor从总线上收集到的transaction交给寄存器模型,后者更新相应的寄存器的值;
当总线上只有一个主设备时,两种方法完全一致。如果有多个主设备,则前一种方法会漏掉某些transaction;
此时可以关掉自动预测功能:rm.default_map.set_auto_predict(0);
function void base_test::build_phase(uvm_phase phase);
super.build_phase(phase);
rm = reg_model::type_id::create("rm", this);
rm.configure(null, "");
rm.build();
rm.lock_model();
rm.reset();
reg_sqr_adapter = new("reg_sqr_adapter");
mon_reg_adapter = new("mon_reg_adapter");////
reg_predictor = new("reg_predictor", this);////
endfunction
function void base_test::connect_phase(uvm_phase phase);
super.connect_phase(phase);
rm.default_map.set_sequencer(env.bus_agt.sqr, reg_sqr_adapter);
rm.default_map.set_auto_predict(1);////1
//monitor->predictor->adapter->rm
reg_predictor.map = rm.default_map;////2设置reg_predictor的map
reg_predictor.adapter = mon_reg_adapter;////2设置reg_predictor的adapter
env.bus_agt.ap.connect(reg_predictor.bus_in);////2把reg_predictor和bus_agt的ap口来连接在一起
endfunction
class bus_monitor extends uvm_monitor;
virtual bus_if vif;
uvm_analysis_port #(bus_transaction) ap;
`uvm_component_utils(bus_monitor)
function new(string name = "bus_monitor", uvm_component parent = null);
super.new(name, parent);
endfunction
virtual function void build_phase(uvm_phase phase);
super.build_phase(phase);
if(!uvm_config_db#(virtual bus_if)::get(this, "", "vif", vif))
`uvm_fatal("bus_monitor", "virtual interface must be set for vif!!!")
ap = new("ap", this);
endfunction
extern task main_phase(uvm_phase phase);
extern task collect_one_pkt(bus_transaction tr);
endclass
monitor的写法
task bus_monitor::main_phase(uvm_phase phase);
bus_transaction tr;
while(1) begin
tr = new("tr");
collect_one_pkt(tr);
ap.write(tr);
end
endtask
task bus_monitor::collect_one_pkt(bus_transaction tr);
while(1) begin
@(posedge vif.clk);
if(vif.bus_cmd_valid) break;
end
tr.bus_op = ((vif.bus_op == 0) ? BUS_RD : BUS_WR);
tr.addr = vif.bus_addr;
tr.wr_data = vif.bus_wr_data;
@(posedge vif.clk);
tr.rd_data = vif.bus_rd_data;
`uvm_info("bus_monitor", "end collect one pkt", UVM_LOW);
endtask
浙公网安备 33010602011771号