Files
axipg/tb/axi_driver.sv
Mahesh Asolkar 800e9c4008 Initial commit
* Bare skeleton implementation of everything
* Testbench builds with Verilator
* Test runs
2025-08-23 14:34:23 -07:00

120 lines
4.5 KiB
Systemverilog

// ----------------------------------------------------------------------
// Driver for AXI transactions
// ----------------------------------------------------------------------
class axi_driver extends uvm_driver; // #(axi_transaction);
virtual `AXI_INTF.MANAGER m_if;
virtual `AXI_INTF.SUBORDINATE s_if;
agent_type_t agent_type;
`uvm_component_utils(axi_driver)
// --------------------------------------------------
// Constructor
function new(string name = "axi_driver", uvm_component parent = null);
super.new(name, parent);
endfunction
// --------------------------------------------------
// Set agent type
function void set_agent_type(agent_type_t atype);
agent_type = atype;
`uvm_info("set_agent_type", $sformatf("Agent type set to %s", agent_type.name()), UVM_LOW)
endfunction
// --------------------------------------------------
// Set virtual interfaces
function void set_virtual_intefaces(virtual `AXI_INTF.MANAGER m_if_p,
virtual `AXI_INTF.SUBORDINATE s_if_p);
`uvm_info("set_virtual_intefaces", $sformatf("Setting virtual interfaces"), UVM_LOW)
m_if = m_if_p;
s_if = s_if_p;
// if (m_if == null && s_if == null) begin
// `uvm_fatal("AXI_DRIVER", "Both MANAGER and SUBORDINATE interfaces are null")
// end else if ((agent_type == MANAGER) && (m_if == null)) begin
// `uvm_error("AXI_DRIVER", $sformatf("MANAGER interface is null"))
// end else if ((agent_type == SUBORDINATE) && (s_if == null)) begin
// `uvm_error("AXI_DRIVER", $sformatf("SUBORDINATE interface is null"))
// end
endfunction
// --------------------------------------------------
// Run phase
virtual task run_phase(uvm_phase phase);
`uvm_info("axi_driver", $sformatf("Running AXI driver: %s as %s",
get_full_name(), agent_type.name()), UVM_LOW)
if (agent_type == MANAGER) begin
`uvm_info("axi_driver", $sformatf("Manager agent detected, driving transactions"), UVM_LOW)
drive_transactions();
end else if (agent_type == SUBORDINATE) begin
`uvm_info("axi_driver", $sformatf("Subordinate agent detected, responding to transactions"), UVM_LOW)
respond_to_transactions();
end else begin
`uvm_fatal("AXI_DRIVER", "Unknown agent type")
end
endtask
// ------------------------------------------------------------
task drive_transactions();
if (m_if == null) begin
`uvm_error("AXI_DRIVER", "MANAGER interface is null, cannot drive transactions")
end
forever begin
`uvm_info("axi_driver", $sformatf("Starting to drive transactions for %s (rst_n = %0b)",
get_full_name(), m_if.ARESETn), UVM_LOW)
if (m_if.ARESETn == 0) begin
`uvm_info("axi_driver", $sformatf("Waiting for reset to be released (rst_n = %0b)",
m_if.ARESETn), UVM_LOW)
@(posedge m_if.ARESETn);
end
`uvm_info("axi_driver", $sformatf("Starting to drive transactions for %s (rst_n = %0b)",
get_full_name(), m_if.ARESETn), UVM_LOW)
while (m_if.ARESETn != 0) begin
uvm_sequence_item txn;
`uvm_info("axi_driver", $sformatf("Waiting for next transaction"), UVM_LOW)
seq_item_port.get_next_item(txn);
drive_item(txn);
seq_item_port.item_done();
end
end
endtask
// ------------------------------------------------------------
task drive_item(uvm_sequence_item txn);
axi_transaction req;
if (!$cast(req, txn)) begin
`uvm_fatal("AXI_DRIVER", "Invalid transaction type")
end
`uvm_info("drive_item", $sformatf("Driving AXI transaction:\n%s", req.sprint()), UVM_LOW)
@(posedge m_if.ACLK);
m_if.AWVALID = 1;
m_if.AWADDR = req.addr;
@(posedge m_if.ACLK);
m_if.WDATA = req.data;
m_if.WSTRB = req.strb;
`uvm_info("drive_item", $sformatf("Driving AXI transaction done."), UVM_LOW)
endtask
// ------------------------------------------------------------
task respond_to_transactions();
forever begin
@(posedge s_if.ARESETn);
while (s_if.ARESETn != 0) begin
@(posedge s_if.ACLK);
@(negedge s_if.ACLK);
end
end
endtask
endclass : axi_driver