Initial commit

* Bare skeleton implementation of everything
* Testbench builds with Verilator
* Test runs
This commit is contained in:
2025-08-23 14:34:23 -07:00
commit 800e9c4008
20 changed files with 1755 additions and 0 deletions

88
tb/axi_agent.sv Normal file
View File

@@ -0,0 +1,88 @@
// ----------------------------------------------------------------------
// Agent to operate AXI transactions
// This agent includes a driver, monitor, and sequencer for AXI transactions
// ----------------------------------------------------------------------
typedef axi_sequencer;
class axi_agent extends uvm_agent;
agent_type_t agent_type;
virtual `AXI_INTF.MANAGER m_if;
virtual `AXI_INTF.SUBORDINATE s_if;
// Declare the sequencer and driver
axi_sequencer sequencer;
axi_driver driver;
axi_monitor monitor;
`uvm_component_utils_begin(axi_agent)
`uvm_field_enum(agent_type_t, agent_type, UVM_DEFAULT)
`uvm_component_utils_end
// --------------------------------------------------
// Constructor
function new(string name = "axi_agent", 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
// --------------------------------------------------
// Build phase
virtual function void build_phase(uvm_phase phase);
sequencer = axi_sequencer::type_id::create("sequencer", this);
driver = axi_driver::type_id::create("driver", this);
monitor = axi_monitor::type_id::create("monitor", this);
// Propagete the agent type to driver and monitor
driver.set_agent_type(agent_type);
monitor.set_agent_type(agent_type);
if (agent_type == MANAGER) begin
if (!uvm_config_db#(virtual `AXI_INTF.MANAGER)::get(this, "", "axi_dvr_vif", m_if)) begin
`uvm_fatal("axi_agent", "AXI agent MANAGER interface not configured")
end
`uvm_info("axi_agent", $sformatf("Using AXI agent MANAGER interface: axi_dvr_vif"), UVM_LOW)
end else begin // if (agent_type == SUBORDINATE) begin
if (!uvm_config_db#(virtual `AXI_INTF.SUBORDINATE)::get(this, "", "axi_dvr_vif", s_if)) begin
`uvm_fatal("axi_agent", "AXI agent SUBORDINATE interface not configured")
end
`uvm_info("axi_agent", $sformatf("Using AXI agent SUBORDINATE interface: axi_dvr_vif"), UVM_LOW)
end
driver.set_virtual_intefaces(m_if, s_if);
monitor.set_virtual_intefaces(m_if, s_if);
endfunction
// --------------------------------------------------
// Connect phase
virtual function void connect_phase(uvm_phase phase);
// Connect the driver to the sequencer
driver.seq_item_port.connect(sequencer.seq_item_export);
driver.rsp_port.connect(sequencer.rsp_export);
// Connect the monitor to the sequencer
// driver.rsp_port.connect(monitor.rsp_export);
endfunction
// --------------------------------------------------
// Run phase
virtual function void run_phase(uvm_phase phase);
`uvm_info("axi_agent", $sformatf("Running AXI agent: %s as %s",
get_full_name(), agent_type.name()), UVM_LOW)
endfunction
endclass : axi_agent
// ----------------------------------------------------------------------
class axi_sequencer extends uvm_sequencer;
`uvm_component_utils(axi_sequencer)
// Constructor
function new(string name, uvm_component parent);
super.new(name, parent);
endfunction
endclass : axi_sequencer

119
tb/axi_driver.sv Normal file
View File

@@ -0,0 +1,119 @@
// ----------------------------------------------------------------------
// 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

117
tb/axi_monitor.sv Normal file
View File

@@ -0,0 +1,117 @@
// ----------------------------------------------------------------------
// Monitor for AXI transactions
// ----------------------------------------------------------------------
class axi_monitor extends uvm_monitor; // #(axi_transaction);
virtual `AXI_INTF.MANAGER m_if;
virtual `AXI_INTF.SUBORDINATE s_if;
agent_type_t agent_type;
// Declare the analysis export
uvm_analysis_port ap;
// Filehandle for transaction tracker file
int trk_file;
`uvm_component_utils(axi_monitor)
// --------------------------------------------------
// Constructor
function new(string name = "axi_monitor", uvm_component parent = null);
super.new(name, parent);
ap = new("analysis_export", this);
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;
endfunction
// --------------------------------------------------
// Run phase
virtual function void run_phase(uvm_phase phase);
// Open transaction log file
trk_file = $fopen($sformatf("axi_transactions.%s.log", agent_type.name()), "w");
if (trk_file == 0) begin
`uvm_error("AXI_MONITOR", "Failed to open transaction log file")
end else begin
`uvm_info("AXI_MONITOR", "Transaction log file opened successfully", UVM_LOW)
end
// Start monitoring
do_monitor();
endfunction
// --------------------------------------------------
// Monitor logic to capture transactions
virtual task do_monitor();
if (agent_type == MANAGER) begin
do_manager_monitor();
end else if (agent_type == SUBORDINATE) begin
do_subordinate_monitor();
end else begin
`uvm_fatal("AXI_MONITOR", "Unknown agent type")
end
endtask
// --------------------------------------------------
// Monitor logic for MANAGER agent
virtual task do_manager_monitor();
// Placeholder for actual monitoring logic
// This would typically involve sampling signals and creating transactions
forever begin
axi_transaction txn;
@(posedge m_if.ACLK);
txn = axi_transaction::type_id::create("txn");
// Capture transaction details here
ap.write(txn);
write_transaction_to_file(txn);
end
endtask
// --------------------------------------------------
// Monitor logic for SUBORDINATE agent
virtual task do_subordinate_monitor();
// Placeholder for actual monitoring logic
// This would typically involve sampling signals and creating transactions
forever begin
axi_transaction txn;
@(posedge s_if.ACLK);
txn = axi_transaction::type_id::create("txn");
// Capture transaction details here
ap.write(txn);
write_transaction_to_file(txn);
end
endtask
// --------------------------------------------------
// Report phase
virtual function void report_phase(uvm_phase phase);
// Report any captured transactions or statistics
`uvm_info("axi_monitor", $sformatf("Reporting on %s",
get_full_name()), UVM_LOW)
endfunction
// --------------------------------------------------
// Function to write captured transaction into a file
function void write_transaction_to_file(axi_transaction txn);
$fwrite(trk_file, "%s\n", txn.sprint());
endfunction
endclass : axi_monitor

43
tb/axi_transaction.sv Normal file
View File

@@ -0,0 +1,43 @@
// ----------------------------------------------------------------------
class axi_transaction extends uvm_sequence_item;
// Declare AXI transaction fields
rand axi_transaction_type_t txn_type; // Transaction type (read/write)
rand bit [31:0] addr; // Address
rand bit [31:0] data; // Data
rand bit [3:0] strb; // Byte enable
`uvm_object_utils_begin(axi_transaction)
`uvm_field_enum(axi_transaction_type_t, txn_type, UVM_DEFAULT)
`uvm_field_int(addr, UVM_DEFAULT)
`uvm_field_int(data, UVM_DEFAULT)
`uvm_field_int(strb, UVM_DEFAULT)
`uvm_object_utils_end
// Constructor
function new(string name = "axi_transaction");
super.new(name);
endfunction
// Copy method for cloning
virtual function uvm_object clone();
axi_transaction copy;
copy = axi_transaction::type_id::create(get_name());
copy.txn_type = this.txn_type;
copy.addr = this.addr;
copy.data = this.data;
copy.strb = this.strb;
return copy;
endfunction
// Comparison method for checking equality
virtual function bit compare(uvm_object rhs);
axi_transaction other;
if (!$cast(other, rhs)) return 0; // Ensure type match
return (this.txn_type == other.txn_type) &&
(this.addr == other.addr) &&
(this.data == other.data) &&
(this.strb == other.strb);
endfunction
endclass : axi_transaction

40
tb/tb_env.sv Normal file
View File

@@ -0,0 +1,40 @@
// Testbench environment for UVM-based verification
class tb_env extends uvm_env;
axi_agent axi_m;
axi_agent axi_s;
`uvm_component_utils(tb_env)
// ------------------------------------------------------------
function new(string name, uvm_component parent);
super.new(name, parent);
endfunction
// ------------------------------------------------------------
virtual function void build_phase(uvm_phase phase);
axi_m = axi_agent::type_id::create("axi_m", this);
axi_s = axi_agent::type_id::create("axi_s", this);
`uvm_info("tb_env", $sformatf("Building testbench environment: %s", get_full_name()), UVM_LOW)
// Set agent types in AXI agents
axi_m.set_agent_type(MANAGER);
axi_s.set_agent_type(SUBORDINATE);
endfunction
// ------------------------------------------------------------
virtual function void connect_phase(uvm_phase phase);
`uvm_info("tb_env", $sformatf("Connecting testbench environment: %s", get_full_name()), UVM_LOW)
endfunction
// ------------------------------------------------------------
virtual function void report_phase(uvm_phase phase);
`uvm_info("tb_env", $sformatf("Reporting for testbench environment: %s", get_full_name()), UVM_LOW)
// Add any specific report phase tasks here
endfunction
// ------------------------------------------------------------
function uvm_sequencer_base get_axi_m_sequencer();
return axi_m.sequencer;
endfunction
endclass : tb_env

26
tb/tb_intf.sv Normal file
View File

@@ -0,0 +1,26 @@
// Testbench interface for UVM-based verification environment
interface testbench_if (
input clk,
virtual axi_intf #(.ADDR_WIDTH(`ADDR_WIDTH),
.CEIL_DATA_WIDTH_DIV_128(`CEIL_DATA_WIDTH_DIV_128),
.CEIL_DATA_WIDTH_DIV_128_TMS_4(`CEIL_DATA_WIDTH_DIV_128_TMS_4),
.CEIL_DATA_WIDTH_DIV_64(`CEIL_DATA_WIDTH_DIV_64),
.DATA_WIDTH(`DATA_WIDTH),
.DATA_WIDTH_DIV_8(`DATA_WIDTH_DIV_8)) m_if,
virtual axi_intf #(.ADDR_WIDTH(`ADDR_WIDTH),
.CEIL_DATA_WIDTH_DIV_128(`CEIL_DATA_WIDTH_DIV_128),
.CEIL_DATA_WIDTH_DIV_128_TMS_4(`CEIL_DATA_WIDTH_DIV_128_TMS_4),
.CEIL_DATA_WIDTH_DIV_64(`CEIL_DATA_WIDTH_DIV_64),
.DATA_WIDTH(`DATA_WIDTH),
.DATA_WIDTH_DIV_8(`DATA_WIDTH_DIV_8)) s_if);
logic rst_n;
initial begin
forever begin
@(clk or rst_n);
$monitor("@%6t: %b %b ", $time,
rst_n, clk);
end
end
endinterface

39
tb/tb_params.sv Normal file
View File

@@ -0,0 +1,39 @@
// ----------------------------------------------------------------------
// Tesbench defines
// ----------------------------------------------------------------------
// List of AXI parameters used in this testbench
`define ADDR_WIDTH 32
// `define ARSNOOP_WIDTH 1
// `define AWCMO_WIDTH 1
// `define AWSNOOP_WIDTH 1
// `define BRESP_WIDTH 1
`define CEIL_DATA_WIDTH_DIV_128 1
`define CEIL_DATA_WIDTH_DIV_128_TMS_4 4
`define CEIL_DATA_WIDTH_DIV_64 1
`define DATA_WIDTH 64
`define DATA_WIDTH_DIV_8 8
// `define ID_R_WIDTH 1
// `define ID_W_WIDTH 1
// `define LOOP_R_WIDTH 1
// `define LOOP_W_WIDTH 1
// `define MECID_WIDTH 1
// `define MPAM_WIDTH 1
// `define RCHUNKNUM_WIDTH 1
// `define RCHUNKSTRB_WIDTH 1
// `define RRESP_WIDTH 1
// `define SECSID_WIDTH 1
// `define SID_WIDTH 1
// `define SSID_WIDTH 1
// `define SUBSYSID_WIDTH 1
// `define SUM_USER_DATA_WIDTH_USER_RESP_WIDTH 1
// `define USER_DATA_WIDTH 1
// `define USER_REQ_WIDTH 1
// `define USER_RESP_WIDTH 1
// Defines
`define AXI_INTF axi_intf #(.ADDR_WIDTH(`ADDR_WIDTH), \
.CEIL_DATA_WIDTH_DIV_128(`CEIL_DATA_WIDTH_DIV_128), \
.CEIL_DATA_WIDTH_DIV_128_TMS_4(`CEIL_DATA_WIDTH_DIV_128_TMS_4), \
.CEIL_DATA_WIDTH_DIV_64(`CEIL_DATA_WIDTH_DIV_64), \
.DATA_WIDTH(`DATA_WIDTH), \
.DATA_WIDTH_DIV_8(`DATA_WIDTH_DIV_8))

25
tb/tb_pkg.sv Normal file
View File

@@ -0,0 +1,25 @@
`include "tb_params.sv"
`include "tb_intf.sv"
package tb_pkg;
import uvm_pkg::*;
import tb_types::*;
`include "uvm_macros.svh"
// Testbench defines
// UVM data items
`include "axi_transaction.sv"
// UVM components
`include "axi_driver.sv"
`include "axi_monitor.sv"
`include "axi_agent.sv"
`include "tb_env.sv"
// UVM sequences
`include "tb_seq_base.sv"
// Tests
`include "test_base.sv"
endpackage
`include "tb_top.sv"

51
tb/tb_seq_base.sv Normal file
View File

@@ -0,0 +1,51 @@
// Base sequence class for testbench sequences
class tb_seq_base extends uvm_sequence;
`uvm_object_utils(tb_seq_base)
// Constructor
function new(string name = "tb_seq_base");
super.new(name);
endfunction
endclass : tb_seq_base
// ----------------------------------------------------------------------
class axi_m_seq_base extends tb_seq_base;
tb_env env;
`uvm_object_utils(axi_m_seq_base)
// Constructor
function new(string name = "axi_m_seq_base");
super.new(name);
endfunction
// Task to start the sequence
virtual task body();
bit ok = uvm_config_db#(tb_env)::get(uvm_root::get(), "*", "env", env);
endtask
endclass : axi_m_seq_base
// ----------------------------------------------------------------------
class axi_simple_seq extends axi_m_seq_base;
`uvm_object_utils(axi_simple_seq)
// Constructor
function new(string name = "axi_simple_seq");
super.new(name);
endfunction
// Task to start the sequence
virtual task body();
axi_transaction txn;
super.body();
`uvm_info("axi_simple_seq", "Starting simple AXI sequence", UVM_LOW)
`uvm_do(txn, env.get_axi_m_sequencer(), -1, {
addr == 32'h0000_0000; // Example address
data == 32'hDEAD_BEEF; // Example data
strb == 'hf; // Example byte enable
});
endtask
endclass : axi_simple_seq

49
tb/tb_top.sv Normal file
View File

@@ -0,0 +1,49 @@
// Testbench top module for UVM-based verification environment
import uvm_pkg::*;
module tb_top (input logic sys_clk);
logic clk;
logic rst_n;
// AXI interface for manager and subordinate
`AXI_INTF a_if (.ACLK(clk), .ARESETn(rst_n));
// // Instantiate the UVM testbench interface
// testbench_if tb_if (
// .clk(clk),
// .m_if(m_if),
// .s_if(s_if)
// );
// assign tb_if.rst_n = rst_n;
// --------------------------------------------------
initial begin
uvm_config_db#(virtual `AXI_INTF.MANAGER)::set(uvm_root::get(), "uvm_test_top.env.axi_m", "axi_dvr_vif", a_if.MANAGER);
uvm_config_db#(virtual `AXI_INTF.SUBORDINATE)::set(uvm_root::get(), "uvm_test_top.env.axi_s", "axi_dvr_vif", a_if.SUBORDINATE);
run_test();
end
// --------------------------------------------------
initial begin
$dumpfile("wave.vcd");
$dumpvars();
end
// --------------------------------------------------
// Clock generation
// TODO: Move to interface. Parameterize frequency
initial begin
clk = 0; // Initialize clock to 0 at time 0
forever begin
#5ns clk = ~clk; // Toggle clock every 5 ns
end
end
// --------------------------------------------------
initial begin
rst_n = 0;
#20ns rst_n = 1; // Release reset after 20 ns
end
endmodule

13
tb/tb_types.sv Normal file
View File

@@ -0,0 +1,13 @@
// Types
package tb_types;
// Agent type
typedef enum {
MANAGER,
SUBORDINATE
} agent_type_t;
typedef enum {
AXI_READ,
AXI_WRITE
} axi_transaction_type_t;
endpackage

129
tb/test_base.sv Normal file
View File

@@ -0,0 +1,129 @@
// Base class for testbench tests
class test_base extends uvm_test;
`uvm_component_utils(test_base)
tb_env env;
uvm_table_printer tb_printer;
// ------------------------------------------------------------
function new(string name, uvm_component parent);
super.new(name, parent);
endfunction
// ------------------------------------------------------------
function void build_phase(uvm_phase phase);
super.build_phase(phase);
env = tb_env::type_id::create("env", this);
tb_printer = new("tb_printer");
uvm_config_db#(tb_env)::set(uvm_root::get(), "*", "env", env);
endfunction
// ------------------------------------------------------------
virtual function void end_of_elaboration_phase(uvm_phase phase);
`uvm_info("end_of_elaboration_phase", $sformatf("Testbench topology:\n%s", this.sprint(tb_printer)), UVM_LOW)
display_uvm_config_db();
display_uvm_config_db("uvm_test_top.env.axi_m");
display_uvm_config_db("uvm_test_top.env.axi_s");
dump_uvm_config_db();
endfunction
// ------------------------------------------------------------
virtual task run_phase(uvm_phase phase);
uvm_objection objection;
objection = phase.get_objection();
`uvm_info("run_phase", $sformatf("Raising objection"), UVM_LOW)
phase.raise_objection(this);
run_reset_phase(phase);
run_test_phase(phase);
run_flush_phase(phase);
objection.set_drain_time(this, 20);
`uvm_info("run_phase", $sformatf("Dropping objection"), UVM_LOW)
phase.drop_objection(this);
endtask
// ------------------------------------------------------------
virtual task run_reset_phase(uvm_phase phase);
`uvm_info("run_reset_phase", $sformatf("Starting reset"), UVM_LOW)
`uvm_info("run_reset_phase", $sformatf("Finishing reset"), UVM_LOW)
endtask
// ------------------------------------------------------------
virtual task run_test_phase(uvm_phase phase);
`uvm_warning("run_test_phase", $sformatf("This content is expected to be implemented in specific tests"))
endtask
// ------------------------------------------------------------
virtual task run_flush_phase(uvm_phase phase);
`uvm_info("run_flush_phase", $sformatf("Finishing test"), UVM_LOW)
endtask
// ------------------------------------------------------------
// Function to traverse and display all entries in uvm_config_db
function void display_uvm_config_db(string scope = ".*");
uvm_resource_pool rp = uvm_resource_pool::get();
uvm_resource_types::rsrc_q_t resources;
// Get all resources from the resource pool
resources = rp.lookup_regex(scope, get_full_name());
rp.print_resources(resources, 1);
`uvm_info("CONFIG_DB", "Traversing uvm_config_db contents:", UVM_LOW)
if (resources.size() == 0) begin
`uvm_info("CONFIG_DB", "No entries found in uvm_config_db", UVM_LOW)
return;
end
// Iterate through all resources
do begin
uvm_resource_base r = resources.pop_front();
if (r == null) begin
`uvm_info("CONFIG_DB", "No more resources to process", UVM_LOW)
break;
end
`uvm_info("CONFIG_DB", $sformatf("Resource: %s", r.get_name()), UVM_LOW)
end while (1);
endfunction
// ------------------------------------------------------------
// Function to dump all entries in uvm_config_db
function void dump_uvm_config_db();
uvm_resource_pool rp = uvm_resource_pool::get();
endfunction
endclass
// ----------------------------------------------------------------------
class test_basic extends test_base;
`uvm_component_utils(test_basic)
// ------------------------------------------------------------
function new(string name, uvm_component parent);
super.new(name, parent);
endfunction
// ------------------------------------------------------------
virtual task run_test_phase(uvm_phase phase);
axi_simple_seq seq;
`uvm_info("run_test_phase", $sformatf("Starting stimulus"), UVM_LOW)
#100ns;
seq = axi_simple_seq::type_id::create("seq");
if (seq == null) begin
`uvm_fatal("run_test_phase", "Failed to create sequence instance")
end
seq.start(env.get_axi_m_sequencer());
`uvm_info("run_test_phase", $sformatf("Finishing stimulus"), UVM_LOW)
endtask
endclass