Development of a Reusable AXI-Lite UVC

4 min reading

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.


Figure 1. UVC Structure

Integration & Usage

The recommended approach to instantiate and use the UVC in a testbench is described by the following steps:

  1. 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)
);
  1. 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);
  1. include the amiq_axi_lite_agent_pgk package in the environment package
import amiq_axi_lite_agent_pkg::*;
  1. in the environment configuration object:
    1. instantiate the agent configuration object:
    2. axi_config_obj = amiq_axi_lite_config_obj::type_id::create("axi_config_obj"); 
    3. set the fields of the agent configuration object:
Field nameDescription
agent_typemanager or subordinate
versionprotocol version: AXI4-Lite or AXI5-Lite
bus_configbus widths and optional signals
is_activeagent mode: active or passive
has_checksenabler for checks
has_coverageenabler for coverage collection
nof_write_outstandingmaximum number of write outstanding transactions; any non-zero positive integer
nof_read_outstandingmaximum number of read outstanding transactions; any non-zero positive integer
write_channels_ordering_capabilitysupport for write out-of-order responses, if the UVC is able to generate/receive write out-of-order transactions
read_channels_ordering_capabilitysupport for read out-of-order responses, if the UVC is able to generate/receive read out-of-order transactions
addr_data_orderingif 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_channelready signal toggling on each channel: random, ready-on-valid, high-rate, or custom
Table 1. UVC Configuration Fields
  1. 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);
  1. 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);
  1. 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;
  1. 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);
  1. 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 nameDescription
amiq_axi_lite_manager_write_sequencerandomizes the items meant to be driven by the manager on write address and write data channels
amiq_axi_lite_manager_write_min_max_addr_sequenceconstrains write items to have the minimum address with 10% probability and the maximum address with 90% probability
amiq_axi_lite_manager_read_sequencerandomizes the items meant to be driven by the manager on the read address channel
amiq_axi_lite_manager_read_min_max_addr_sequenceconstrains read items to have the minimum address with 10% probability and the maximum address with 90% probability
amiq_axi_lite_subordinate_write_sequencerandomizes the items meant to be driven by the subordinate on write response channel
amiq_axi_lite_subordinate_write_lifo_id_sequenceconstrains the subordinate to respond with an 80% chance to the most recent write request
amiq_axi_lite_subordinate_read_sequencerandomizes the items meant to be driven by the subordinate on read data channel
amiq_axi_lite_subordinate_read_lifo_id_sequenceconstrains the subordinate to respond with an 80% chance to the most recent read request
Table 2. Sequence Library

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.

Comments

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Subscribe to our newsletter

Do you want to be up to date with our latest articles?