// ---------------------------------------------------------------------- // 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