|
|
@@ -0,0 +1,121 @@ |
|
|
|
// Brief description: |
|
|
|
// This is the axi master monitor, where in the information from the |
|
|
|
// virtual interface is caputured and translate into transaction level data |
|
|
|
// |
|
|
|
// Known exceptions to rules: |
|
|
|
// |
|
|
|
//============================================================================ |
|
|
|
// Author : Venkatesh |
|
|
|
// Created on : 30/05/2025 |
|
|
|
// File Id : |
|
|
|
//============================================================================ |
|
|
|
|
|
|
|
`ifndef AXI_MASTER_MONITOR_SV |
|
|
|
`define AXI_MASTER_MONITOR_SV |
|
|
|
|
|
|
|
class axi_master_monitor#(parameter int DATA_WIDTH_MAS = 32,parameter int ADDR_WIDTH_MAS = 32) extends uvm_monitor; |
|
|
|
`uvm_component_utils(axi_master_monitor) |
|
|
|
uvm_analysis_port#(axi_tx) ap_sb; |
|
|
|
uvm_analysis_port#(axi_tx) ap_fc; |
|
|
|
//virtual axi_intf vif; |
|
|
|
virtual axi_interface#(.DATA_WIDTH(DATA_WIDTH_MAS),.ADDR_WIDTH(ADDR_WIDTH_MAS)) vif; |
|
|
|
|
|
|
|
axi_m_agent_config m_cfg; |
|
|
|
|
|
|
|
int addr [int]; |
|
|
|
int data[*]; |
|
|
|
int resp[int]; |
|
|
|
axi_tx w_tx,r_tx; |
|
|
|
|
|
|
|
extern function new(string name="",uvm_component parent=null); |
|
|
|
extern function void build_phase(uvm_phase phase); |
|
|
|
extern task run_phase(uvm_phase phase); |
|
|
|
endclass |
|
|
|
|
|
|
|
//add a variable for configration of port |
|
|
|
function axi_master_monitor :: new(string name="",uvm_component parent=null); |
|
|
|
super.new(name,parent); |
|
|
|
//ap_port = new("ap_port",this); |
|
|
|
endfunction |
|
|
|
function axi_master_monitor :: void build_phase(uvm_phase phase); |
|
|
|
super.build_phase(phase); |
|
|
|
if(!uvm_config_db#(virtual axi_interface)::get(this,"","vif",vif))begin |
|
|
|
`uvm_error("[MONITOR]","VIF NOT RECEIVED FROM TOP") |
|
|
|
end |
|
|
|
if(!uvm_config_db #(axi_m_agent_config)::get(this,"","axi_m_agent_config",m_cfg)) begin |
|
|
|
`uvm_error("CONFIG","Getting failed in mst_monitor") |
|
|
|
end |
|
|
|
if(m_cfg.has_sb) |
|
|
|
ap_sb = new("ap_sb",this); |
|
|
|
if(m_cfg.has_fc) |
|
|
|
ap_fc = new("ap_fc",this); |
|
|
|
endfunction |
|
|
|
task axi_master_monitor :: run_phase(uvm_phase phase); |
|
|
|
forever begin |
|
|
|
@(vif.mon_cb); |
|
|
|
//write address channel |
|
|
|
if(vif.mon_cb.awvalid==1 && vif.mon_cb.awready==1) |
|
|
|
begin |
|
|
|
`uvm_info("[AWCHECK]",$psprintf("%t write addr %h",$time,vif.mon_cb.awaddr),UVM_LOW) |
|
|
|
w_tx = axi_tx::type_id::create("w_tx"); |
|
|
|
w_tx.wr_rd = WRITE; |
|
|
|
w_tx.awid = vif.mon_cb.awid; |
|
|
|
w_tx.awaddr = vif.mon_cb.awaddr; |
|
|
|
w_tx.awlen = vif.mon_cb.awlen; |
|
|
|
w_tx.awsize = vif.mon_cb.awsize; |
|
|
|
w_tx.awburst = vif.mon_cb.awburst; |
|
|
|
w_tx.awcache = vif.mon_cb.awcache; |
|
|
|
w_tx.awprot = vif.mon_cb.awprot; |
|
|
|
w_tx.awlock = vif.mon_cb.awlock; |
|
|
|
addr[vif.mon_cb.awid]=w_tx; |
|
|
|
|
|
|
|
end |
|
|
|
// write data channel |
|
|
|
if(vif.mon_cb.wvalid==1 && vif.mon_cb.wready==1) |
|
|
|
begin |
|
|
|
`uvm_info("[WCHECK]",$psprintf("%t write data %h",$time,vif.mon_cb.wdata),UVM_LOW) |
|
|
|
w_tx.wdata.push_back(vif.mon_cb.wdata); |
|
|
|
w_tx.wstrb.push_back(vif.mon_cb.wstrb); |
|
|
|
w_tx.wlast=vif.mon_cb.wlast; |
|
|
|
data[]=w_tx; |
|
|
|
end |
|
|
|
//write response channel |
|
|
|
if(vif.mon_cb.bvalid==1 && vif.mon_cb.bready==1) |
|
|
|
begin |
|
|
|
w_tx.bid = vif.mon_cb.bid; |
|
|
|
`uvm_info("[BCHECK]",$psprintf("%t write RESP %h",$time,vif.mon_cb.bresp),UVM_LOW) |
|
|
|
w_tx.bresp = vif.mon_cb.bresp; |
|
|
|
resp[vif.mon_cb.bid]=w_tx; |
|
|
|
ap_port.write(w_tx); |
|
|
|
end |
|
|
|
//read address channel |
|
|
|
if(vif.mon_cb.arvalid==1 && vif.mon_cb.arready==1) |
|
|
|
begin |
|
|
|
`uvm_info("[ARCHECK]",$psprintf("%t read addr %h",$time,vif.mon_cb.araddr),UVM_LOW) |
|
|
|
r_tx = axi_tx::type_id::create("r_tx"); |
|
|
|
w_tx.wr_rd = READ; |
|
|
|
r_tx.arid = vif.mon_cb.arid; |
|
|
|
r_tx.araddr = vif.mon_cb.araddr; |
|
|
|
r_tx.arlen = vif.mon_cb.arlen; |
|
|
|
r_tx.arsize = vif.mon_cb.arsize; |
|
|
|
r_tx.arburst = vif.mon_cb.arburst; |
|
|
|
r_tx.arcache = vif.mon_cb.arcache; |
|
|
|
r_tx.arprot = vif.mon_cb.arprot; |
|
|
|
r_tx.arlock = vif.mon_cb.arlock; |
|
|
|
end |
|
|
|
//read data channel |
|
|
|
if(vif.mon_cb.rvalid==1 && vif.mon_cb.rready==1) |
|
|
|
begin |
|
|
|
`uvm_info("[RCHECK]",$psprintf("%t write data %h",$time,vif.mon_cb.rdata),UVM_LOW) |
|
|
|
r_tx.rid = vif.mon_cb.rid; |
|
|
|
r_tx.rdata.push_back(vif.mon_cb.rdata); |
|
|
|
r_tx.rresp = vif.mon_cb.rresp; |
|
|
|
r_tx.rlast = vif.mon_cb.rlast; |
|
|
|
ap_port.write(r_tx); |
|
|
|
end |
|
|
|
end |
|
|
|
endtask |
|
|
|
`endif |
|
|
|
|
|
|
|
|
|
|
|
|