Compare commits
2 Commits
4efbada1d8
...
728d2a0f6d
Author | SHA1 | Date | |
---|---|---|---|
728d2a0f6d
|
|||
1e484bc2c6
|
3
Makefile
3
Makefile
@@ -3,7 +3,8 @@ LOG_REDIR = >&
|
||||
TIME=/usr/bin/time --format "Elapsed: %E, Memory: %M KB [Swaps %W]"
|
||||
|
||||
# Makefile variables
|
||||
NUM_PROCS=$(shell nproc --all)
|
||||
# NUM_PROCS=$(shell nproc --all)
|
||||
NUM_PROCS=6
|
||||
PROJ_BASE=$(shell pwd)
|
||||
|
||||
# Make and run project
|
||||
|
@@ -10,10 +10,12 @@ class axi_agent extends uvm_agent;
|
||||
virtual `AXI_INTF.SUBORDINATE s_if;
|
||||
virtual `AXI_INTF mon_if;
|
||||
|
||||
// Configuration object
|
||||
rand axi_agent_config cfg;
|
||||
// Declare the sequencer and driver
|
||||
axi_sequencer sequencer;
|
||||
axi_driver driver;
|
||||
axi_monitor monitor;
|
||||
axi_sequencer sequencer;
|
||||
axi_driver driver;
|
||||
axi_monitor monitor;
|
||||
|
||||
`uvm_component_utils_begin(axi_agent)
|
||||
`uvm_field_enum(axi_agent_type_t, agent_type, UVM_DEFAULT)
|
||||
@@ -32,9 +34,21 @@ class axi_agent extends uvm_agent;
|
||||
`uvm_info("set_agent_type", $sformatf("Agent type set to %s", agent_type.name()), UVM_LOW)
|
||||
endfunction
|
||||
|
||||
// --------------------------------------------------
|
||||
function axi_agent_config get_cfg();
|
||||
return cfg;
|
||||
endfunction
|
||||
|
||||
// --------------------------------------------------
|
||||
// Build phase
|
||||
virtual function void build_phase(uvm_phase phase);
|
||||
cfg = axi_agent_config::type_id::create("cfg");
|
||||
if (!cfg.randomize()) begin
|
||||
`uvm_fatal("build_phase", "Randomization of cfg failed")
|
||||
end else begin
|
||||
`uvm_info("build_phase", $sformatf("%s randomized:\n%s", cfg.get_full_name(), cfg.sprint()), UVM_LOW)
|
||||
end
|
||||
|
||||
sequencer = axi_sequencer::type_id::create("sequencer", this);
|
||||
if (agent_type == MANAGER) begin
|
||||
// TODO: Additional variable md should not be needed. We should
|
||||
|
67
src/axi/axi_agent_config.sv
Normal file
67
src/axi/axi_agent_config.sv
Normal file
@@ -0,0 +1,67 @@
|
||||
// Configuration class to hold options used in the agent. This contains
|
||||
// options for anything in side the agent
|
||||
class axi_agent_config extends uvm_object;
|
||||
|
||||
/// Minimum value of pre_transaction_delay
|
||||
int pre_transaction_delay_min = 0;
|
||||
/// Maximum value of pre_transaction_delay
|
||||
int pre_transaction_delay_max = 20;
|
||||
|
||||
/// Minimum value of pre_response_delay
|
||||
int pre_response_delay_min = 1;
|
||||
/// Maximum value of pre_response_delay
|
||||
int pre_response_delay_max = 20;
|
||||
|
||||
`uvm_object_utils_begin(axi_agent_config)
|
||||
`uvm_field_int(pre_transaction_delay_min, UVM_DEFAULT)
|
||||
`uvm_field_int(pre_transaction_delay_max, UVM_DEFAULT)
|
||||
`uvm_field_int(pre_response_delay_min, UVM_DEFAULT)
|
||||
`uvm_field_int(pre_response_delay_max, UVM_DEFAULT)
|
||||
`uvm_object_utils_end
|
||||
|
||||
// --------------------------------------------------
|
||||
function new(string name = "axi_agent_config");
|
||||
super.new(name);
|
||||
endfunction
|
||||
|
||||
// --------------------------------------------------
|
||||
function post_randomize();
|
||||
`uvm_info("post_randomzie", $sformatf("AXI Agent Config:\n%s", this.sprint()), UVM_LOW)
|
||||
endfunction
|
||||
|
||||
// TODO: Using $urandom_range() since Verilator does not have support for
|
||||
// std::randomize() with {}
|
||||
// --------------------------------------------------
|
||||
function int get_pre_transaction_delay();
|
||||
int dly = 0;
|
||||
// if (!std::randomzie(dly) with {
|
||||
// dly dist {
|
||||
// pre_transaction_delay_min :/ 4,
|
||||
// pre_transaction_delay_max :/ 4,
|
||||
// [pre_transaction_delay_min
|
||||
// :pre_transaction_delay_max] :/ 2
|
||||
// };
|
||||
// }) begin
|
||||
// `uvm_error("get_pre_transaction_delay", "Randomization failed")
|
||||
// end
|
||||
dly = $urandom_range(pre_transaction_delay_max, pre_transaction_delay_min);
|
||||
return dly;
|
||||
endfunction
|
||||
|
||||
// --------------------------------------------------
|
||||
function int get_pre_response_delay();
|
||||
int dly = 0;
|
||||
// if (!std::randomzie(dly) with {
|
||||
// dly dist {
|
||||
// pre_response_delay_min :/ 4,
|
||||
// pre_response_delay_max :/ 4,
|
||||
// [pre_response_delay_min
|
||||
// :pre_response_delay_max] :/ 2
|
||||
// };
|
||||
// }) begin
|
||||
// `uvm_error("get_pre_response_delay", "Randomization failed")
|
||||
// end
|
||||
dly = $urandom_range(pre_response_delay_max, pre_response_delay_min);
|
||||
return dly;
|
||||
endfunction
|
||||
endclass
|
@@ -1,10 +1,13 @@
|
||||
// ----------------------------------------------------------------------
|
||||
// Driver for AXI transactions
|
||||
// ----------------------------------------------------------------------
|
||||
typedef axi_agent;
|
||||
|
||||
class axi_driver extends uvm_driver; // #(axi_transaction);
|
||||
virtual `AXI_INTF.MANAGER m_if;
|
||||
virtual `AXI_INTF.SUBORDINATE s_if;
|
||||
axi_agent_type_t agent_type;
|
||||
axi_agent_config cfg;
|
||||
|
||||
`uvm_component_utils(axi_driver)
|
||||
|
||||
@@ -24,9 +27,18 @@ class axi_driver extends uvm_driver; // #(axi_transaction);
|
||||
// --------------------------------------------------
|
||||
// Set virtual interfaces
|
||||
function void set_virtual_interfaces(virtual `AXI_INTF.MANAGER m_if_p,
|
||||
virtual `AXI_INTF.SUBORDINATE s_if_p);
|
||||
virtual `AXI_INTF.SUBORDINATE s_if_p);
|
||||
`uvm_info("set_virtual_interfaces", $sformatf("Setting virtual interfaces"), UVM_LOW)
|
||||
m_if = m_if_p;
|
||||
s_if = s_if_p;
|
||||
endfunction
|
||||
|
||||
// --------------------------------------------------
|
||||
virtual function void end_of_elaboration_phase(uvm_phase phase);
|
||||
axi_agent agt;
|
||||
|
||||
if ($cast(agt, get_parent())) begin
|
||||
cfg = agt.get_cfg();
|
||||
end
|
||||
endfunction
|
||||
endclass : axi_driver
|
||||
|
@@ -53,8 +53,14 @@ class axi_manager_driver extends axi_driver;
|
||||
|
||||
// ------------------------------------------------------------
|
||||
task drive_txn(axi_transaction req);
|
||||
|
||||
int dly = cfg.get_pre_transaction_delay();
|
||||
`uvm_info("drive_txn", $sformatf("Driving AXI transaction:\n%s", req.sprint()), UVM_LOW)
|
||||
|
||||
// Pre transaction delay
|
||||
`uvm_info("drive_txn", $sformatf("Waiting pre_transaction_delay = %0d cycles",
|
||||
dly), UVM_LOW)
|
||||
repeat(dly) @(posedge m_if.ACLK);
|
||||
|
||||
if (req.txn_type == AXI_WRITE) begin
|
||||
drive_write_txn(req);
|
||||
end else if (req.txn_type == AXI_READ) begin
|
||||
|
@@ -5,6 +5,7 @@ package axi_pkg;
|
||||
`include "uvm_macros.svh"
|
||||
|
||||
// UVM data items
|
||||
`include "axi_agent_config.sv"
|
||||
`include "axi_transaction.sv"
|
||||
|
||||
// UVM components
|
||||
|
@@ -41,6 +41,7 @@ class axi_subordinate_driver extends axi_driver;
|
||||
// ------------------------------------------------------------
|
||||
task respond_to_write_txn();
|
||||
axi_transaction req;
|
||||
int dly = cfg.get_pre_response_delay();
|
||||
|
||||
req = axi_transaction::type_id::create("req");
|
||||
req.txn_type = AXI_WRITE;
|
||||
@@ -48,25 +49,36 @@ class axi_subordinate_driver extends axi_driver;
|
||||
req.data = s_if.WDATA;
|
||||
req.strb = s_if.WSTRB;
|
||||
|
||||
@(posedge s_if.ACLK);
|
||||
// Pre response delay
|
||||
`uvm_info("drive_txn", $sformatf("Waiting pre_response_delay = %0d cycles",
|
||||
dly), UVM_LOW)
|
||||
repeat(dly) @(posedge s_if.ACLK);
|
||||
|
||||
`uvm_info("respond_to_write_txn", $sformatf("Responding to AXI write transaction:\n%s", req.sprint()), UVM_LOW)
|
||||
|
||||
s_if.AWREADY = 1'b1;
|
||||
@(posedge s_if.ACLK);
|
||||
s_if.AWREADY = 1'b0;
|
||||
endtask
|
||||
|
||||
// ------------------------------------------------------------
|
||||
task respond_to_read_txn();
|
||||
axi_transaction req;
|
||||
int dly = cfg.get_pre_response_delay();
|
||||
|
||||
req = axi_transaction::type_id::create("req");
|
||||
req.txn_type = AXI_READ;
|
||||
req.addr = s_if.ARADDR;
|
||||
|
||||
@(posedge s_if.ACLK);
|
||||
// Pre response delay
|
||||
`uvm_info("respond_to_write_txn", $sformatf("Waiting pre_response_delay = %0d cycles",
|
||||
dly), UVM_LOW)
|
||||
repeat(dly) @(posedge s_if.ACLK);
|
||||
|
||||
`uvm_info("respond_to_write_txn", $sformatf("Responding to AXI write transaction:\n%s", req.sprint()), UVM_LOW)
|
||||
|
||||
s_if.ARREADY = 1'b1;
|
||||
@(posedge s_if.ACLK);
|
||||
s_if.ARREADY = 1'b0;
|
||||
endtask
|
||||
endclass : axi_subordinate_driver
|
||||
|
Reference in New Issue
Block a user