AXI-Lite is a lightweight, powerful subset of the AXI protocol from the ARM AMBA family, used for register access and peripheral communication within an SoC, when burst transfers are inefficient. Today’s most used protocol versions are AXI5-Lite and AXI4-Lite. AXI5-Lite is backwards compatible with AXI4-Lite and offers support for response reordering and throughput flexibility using configurable bus widths.
Despite its extended usage, very few reliable open-source solutions exist. Most of them are neither protocol-compliant, nor easily configurable, nor coverage-complete. To address the verification industry’s needs, a reusable, highly configurable, AXI4-Lite and AXI5-Lite UVC is developed using SystemVerilog (SV 2009) and Universal Verification Methodology (UVM 1.1). The AXI-Lite specification can be found in the official documentation for AMBA AXI Protocol Specification.
UVC Features
The main characteristics of the AXI-Lite UVC are:
- Compatibility with the AXI4-Lite and AXI5-Lite versions of the protocol
- Easy and efficient configuration methods through configuration object fields (check step 4.b) or sequence fields (fields for delay control and number of generated sequence items)
- Configurable toggling/randomization modes for ready signals
- Support for driving and monitoring outstanding transactions and out-of-order transactions
- Precise control over inter-transfer delays
- Static configuration for bus widths or optional signals, according to the protocol specification
- Write request integrity – it guarantees control over pairing a write address and a write data within a request packet
- Built-in ports in monitor and drivers that can be used to connect the UVC to other components in the environment (e.g. scoreboard)
- Coverage model with a large set of measurements, designed to offer a comprehensive view of the deployed scenarios
Structure
The agent follows the standard UVM architecture. It contains all relevant entities: the active parts that handle stimuli driving (drivers, sequencers, sequences), the passive parts that receive them (interface, monitor, coverage collector), and the configuration object that defines the behavior of the agent.
Each agent has its own implementation class: amiq_axi_lite_manager_agent for manager, respectively amiq_axi_lite_subordinate_agent for subordinate. Both inherit the same base class, amiq_axi_lite_agent, that extends the uvm_agent class. Moreover, the agents have different implementations for their drivers and sequence library, each agent being responsible for driving on different channels. The amiq_axi_lite_driver class provides shared functionality between drivers and is extended only to implement the behavior specific to each agent and transaction type.
In contrast, the implementation for monitor (amiq_axi_lite_monitor), coverage collector (amiq_axi_lite_coverage_collector), configuration object (amiq_axi_lite_config_obj), and sequencer (amiq_axi_lite_sequencer) are shared between agents. The structure of the agent is presented in Figure 1.

Integration & Usage
The recommended approach to instantiate and use the UVC in a testbench is described by the following steps:
- in tb_top declare the AXI-Lite interface, then connect it to the DUT
amiq_axi_lite_if axi_lite_if(
.clock (clk),
.reset_n (rst_n)
);
- set the AXI-Lite interface in `uvm_config_db() to be visible in the environment
uvm_config_db#(virtual amiq_axi_lite_if)::set(null, "uvm_test_top.env*", "axi_lite_vif", axi_lite_vif);
- include the amiq_axi_lite_agent_pgk package in the environment package
import amiq_axi_lite_agent_pkg::*;
- in the environment configuration object:
- instantiate the agent configuration object:
- set the fields of the agent configuration object:
axi_config_obj = amiq_axi_lite_config_obj::type_id::create("axi_config_obj");
| Field name | Description |
|---|---|
| agent_type | manager or subordinate |
| version | protocol version: AXI4-Lite or AXI5-Lite |
| bus_config | bus widths and optional signals |
| is_active | agent mode: active or passive |
| has_checks | enabler for checks |
| has_coverage | enabler for coverage collection |
| nof_write_outstanding | maximum number of write outstanding transactions; any non-zero positive integer |
| nof_read_outstanding | maximum number of read outstanding transactions; any non-zero positive integer |
| write_channels_ordering_capability | support for write out-of-order responses, if the UVC is able to generate/receive write out-of-order transactions |
| read_channels_ordering_capability | support for read out-of-order responses, if the UVC is able to generate/receive read out-of-order transactions |
| addr_data_ordering | if the UVC (if manager) is able to generate write address and write data in any order, or just in a precise order |
| ready_config_on_channel | ready signal toggling on each channel: random, ready-on-valid, high-rate, or custom |
- instantiate the agent in the build_phase() of the environment
axi_agent = amiq_axi_lite_manager_agent::type id::create("axi_agent", this);or
axi_agent = amiq_axi_lite_subordinate_agent::type id::create("axi_agent", this);
- set the agent configuration object and the AXI-Lite interface in `uvm_config_db() to be visible in the agent
uvm_config_db#(amiq_axi_lite_config_obj)::set(this, "axi_agent*", "axi_config_obj", axi_config_obj);
uvm_config_db#(virtual amiq_axi lite_if)::set(this, "axi_agent*", "axi_lite_vif", axi_lite_vif);
- declare handles for the sequencers of the agent in the virtual sequencer (vseqr):
amiq_axi_lite_sequencer axi_write_sequencer;
amiq_axi_lite_sequencer axi_read_sequencer;
- make the necessary connections in the connect_phase() of the environment:
- the handles previously declared in vseqr with the actual sequencers declared in the agent
vseqr.axi_write_sequencer = axi_agent.write_sequencer; vseqr.axi_read_sequencer = axi_agent.read_sequencer;
- the analysis ports of the UVC with the imports of the subscribers, if required
- for example, if you want to connect a scoreboard (scbd) that compares monitored transactions, the monitor’s port for complete transactions needs to be connected to the scoreboard’s port (collected_port in this example):
axi_agent.monitor.collected_complete_transaction_port.connect(scbd.collected_port);
- if the agent is active, it is essential to instantiate and start sequences in the virtual sequence:
- an example of how to start a write sequence for a manager agent:
amiq_axi_lite_manager_write_sequence write_sequence;
`uvm_do_on_with(write_sequence, vseqr.axi_write_sequencer, {
number_of_generated_items_on_write == 100;
seq_pre_delay_config == AMIQ_AXI_LITE_PRE_RANDOM_DELAYS;
seq_intra_delay_config == AMIQ_AXI_LITE_INTRA_SOME_ZERO_MOST_SMALL;
}) - an example of how to start a write sequence for a subordinate agent:
amiq_axi_lite_subordinate_write_sequence write_sequence;
`uvm_do_on_with(write_sequence, vseqr.axi_write_sequencer, {
seq_pre_resp_delay_config == AMIQ_AXI_LITE_PRE_RESP_RANDOM_DELAYS;
})
Sequence Library
The UVC comes with pre-defined sequences, for both manager and subordinate flavours:
| Sequence name | Description |
|---|---|
| amiq_axi_lite_manager_write_sequence | randomizes the items meant to be driven by the manager on write address and write data channels |
| amiq_axi_lite_manager_write_min_max_addr_sequence | constrains write items to have the minimum address with 10% probability and the maximum address with 90% probability |
| amiq_axi_lite_manager_read_sequence | randomizes the items meant to be driven by the manager on the read address channel |
| amiq_axi_lite_manager_read_min_max_addr_sequence | constrains read items to have the minimum address with 10% probability and the maximum address with 90% probability |
| amiq_axi_lite_subordinate_write_sequence | randomizes the items meant to be driven by the subordinate on write response channel |
| amiq_axi_lite_subordinate_write_lifo_id_sequence | constrains the subordinate to respond with an 80% chance to the most recent write request |
| amiq_axi_lite_subordinate_read_sequence | randomizes the items meant to be driven by the subordinate on read data channel |
| amiq_axi_lite_subordinate_read_lifo_id_sequence | constrains the subordinate to respond with an 80% chance to the most recent read request |
Conclusion
The proposed solution presents an open-source UVC for the AXI5-Lite protocol, designed to be easily configured as AXI4-Lite as well. It has been validated through an extensive set of metrics and checks. The main advantage is its increased configurability, which allows the user to set the protocol version, types of transactions, bus widths, and specific protocol features from a higher level and pass them to the agent through the configuration object.
Moreover, the GitHub repository includes an example of how to instantiate, configure, and use the UVC in a testbench as both manager and subordinate.
Download
We invite you to discover our solution on the AMIQ GitHub page by accessing the following link: AMIQ AXI-Lite Repository.