Synopsys AXI VIP为master和slave agent中的monitor提供了名为item_started_port和item_observed_port的analysis port,前者仅在总线事务传输开始时发送,后者则在总线事务传输完成后发送完整svt_axi_master_transaction和svt_axi_slave_transaction对象到item_observed_port端口,并且在vip agent为passive和active模式下都有效。可以将该端口连接至现有scoreboard用以分析总线事务信号,方法如下:
- 首先需要在scoreboard中声明export(或import)端口
/** Macro that define two analysis ports with unique suffixes */
`uvm_analysis_imp_decl(_initiated)
`uvm_analysis_imp_decl(_response)
/** Analysis port conneted to the AXI Slave Agent */
uvm_analysis_imp_response#(svt_axi_transaction, axi_uvm_scoreboard) item_observed_response_export;
- 在scoreboard::build_phase()中创建export对象
function void build_phase(uvm_phase phase);
super.build_phase();
/** Construct the analysis ports */
item_observed_initiated_export = new("item_observed_initiated_export", this);
item_observed_response_export = new("item_observed_response_export", this);
endfunction
- 添加write_xxx函数以从analysis port中获取transaction
/* This method is called by item_observed_response_export */
virtual function void write_response(input svt_axi_transaction xact);
svt_axi_transaction resp_xact;
if (!$cast(resp_xact, xact.clone())) begin
`uvm_fatal("write_response", "Unable to $cast the received transaction to svt_axi_transaction");
end
`uvm_info("write_response", $sformatf("xact:\n%s", resp_xact.sprint()), UVM_FULL)
endfunction
- 在base_test的connect_phase()中连接slave agent的analysis port和scoreboard
function void connect_phase(uvm_phase phase);
/* Connect the master and slave agent's analysis ports with
* item_observed_port and import of the scoreboard. */
axi_system_env.slave[0].monitor.item_observed_port.connect(axi_scoreboard.item_observed_response_export);
endfunction
注意,vip monitor中某些信号的监测需要在port_configuration中配置使能开启,如arqos和awqos信号:
this.slave_cfg[0].arqos_enable = 1;
this.slave_cfg[0].awqos_enable = 1;
如果要在VIP环境中添加自定义TLM analysis port,需采用callback方法。SVT AXI VIP提供了很多callback方法,以下举例说明如何在AXI port monitor中添加自定义端口svt_axi_port_monitor_callback::read_address_phase_ended。
- 首先创建自定义callback类,并在read_address_phase_ended方法中添加自定义端口item_observed_port_addr
class axiMasterMonitorCallbacks extends svt_axi_port_monitor_callback;
int master_num=0;
svt_axi_system_configuration vip_cfg;
//user-defined analysis ports
uvm_analysis_port #(svt_axi_transaction) item_observed_port_addr;
function new(int master_num=0,svt_axi_system_configuration vip_cfg,uvm_component parent=null);
this.master_num=master_num;
this.vip_cfg=vip_cfg;
item_observed_port_addr=new("",parent);
endfunction
//for initiating masters
extern virtual function void read_address_phase_ended(
svt_axi_port_monitor axi_monitor,
svt_axi_transaction item);
endclass
function void axiMasterMonitorCallbacks::read_address_phase_ended(
svt_axi_port_monitor axi_monitor,
svt_axi_transaction item);
svt_axi_transaction item_copy;
//user-defined analysis port
$cast(item_copy,item.clone());
item_copy.port_id=master_num;
item_observed_port_addr.write(item_copy);
endfunction
-
在scoreboard中创建export端口和write()方法,这一步同上步骤1、2、3,故代码略去
-
在env中连接TLM端口,需要在uvm_env::build_phase()中创建callback,在connect_phase()中连接端口,并在start_of_simulation_phase() 中注册callback
virtual function void build_phase(uvm_phase phase);
super.build_phase(phase);
axi_system_env = svt_axi_system_env::type_id::create("axi_system_env", this);
uvm_config_db#(svt_axi_system_configuration)::set(this, "axi_system_env", "cfg", cfg);
axi_sb = axiSB::type_id::create("axi_sb", this);
master_monitor_cb=new[cfg.num_masters];
foreach(cfg.master_cfg[i]) begin
master_monitor_cb[i]=new(i,cfg,this);
end
endfunction
function void connect_phase(uvm_phase phase);
master_monitor_cb[0].item_observed_port_addr.connect(axi_sb.master_cb_addr_export[0]);
master_monitor_cb[1].item_observed_port_addr.connect(axi_sb.master_cb_addr_export[1]);
master_monitor_cb[2].item_observed_port_addr.connect(axi_sb.master_cb_addr_export[2]);
master_monitor_cb[3].item_observed_port_addr.connect(axi_sb.master_cb_addr_export[3]);
endfunction
virtual function void start_of_simulation_phase(uvm_phase phase);
super.start_of_simulation_phase(phase);
//Master Monitor callbacks
foreach(cfg.master_cfg[i]) begin
uvm_callbacks#(svt_axi_port_monitor)::add(axi_system_env.master[i].monitor,master_monitor_cb[i]);
end
endfunction
参考资料:VC Verification IP AMBA AXI UVM User Guide R-2020.09