logic_vector_array_axi environment

This environment has one high-level logic vector array agent and it works only with data. This package contains two environments. The RX environment generates and sends data to the DUT. The TX environment generates TREADY and observes the TX interface.

logic_vector_array_axi schema

The environment is configured by five parameters: For more information see AXI documentation.

  • DATA_WIDTH

  • TUSER_WIDTH

  • ITEM_WIDTH

  • ITEM_SIZE

  • REGIONS

Top sequencers and sequences

In the RX direction, there is the Logic vector array sequencer that handles the AXI TDATA and the TUSER.

In the TX direction, there is one sequencer of type axi::sequencer #(DATA_WIDTH, TUSER_WIDTH, REGIONS) which generates the TREADY signal.

Both directions have an analysis_export for logic vector array transactions.

Configuration

The config class has three variables.

Variable

Description

active

Set to UVM_ACTIVE if the agent is active, otherwise set to UVM_PASSIVE.

interface_name

The name of the interface under which you can find it in uvm config database.

seq_cfg

Configure a low-level sequence that converts logic_vector_array to AXI words.

The top level of the environment contains the reset_sync class, which is required for reset synchronization. The example shows how to connect the reset to the logic_vector_array_axi environment and its basic configuration.

class test extends uvm_test
    `uvm_componet_utils(test::base)
    reset::agent                m_resets;
    logic_vector_array_axi::env_rx#(...) m_env;

    function new(string name, uvm_component parent = null);
        super.new(name, parent);
    endfunction

    function void build_phase(uvm_phase phase);
         logic_vector_array_axi::config_item m_cfg;

         m_resets = reset::agent::type_id::create("m_reset", this);

         m_cfg = new();
         m_cfg.active = UVM_ACTIVE;
         m_cfg.interface_name = "AXI_IF";
         m_cfg.cfg = new();
         m_cfg.cfg.space_size_set(128, 1024);
         uvm_config_db#(logic_vector_array_axi_env::config_item)::set(this, "m_env", "m_config", m_cfg);
         m_env = logic_vector_array_axi::env_rx#(...)::type_id::create("m_env", this);
    endfunction

     function void connect_phase(uvm_phase phase);
        m_reset.sync_connect(m_env.reset_sync);
     endfunction
endclass

Low-level sequence configuration

The configuration object config_sequence contains two functions.

Variable

Type

Description

probability_set(min, max)

[percentage]

Set probability of no inframe gap, probability_set(100,100) => no inframe gap.

space_size_set(min, max)

[bytes]

Set min and max space between two packets.

RX Inner sequences

For the RX direction, there is one base sequence class “sequence_simple_rx_base” which simplifies the creation of other sequences. It processes the reset signal and exports the create_sequence_item virtual function. In this function, a child can create an axi::sequence_item as they like. Another important function in the “sequence_simple_rx_base” class is try_get() which gets the required data from the base array agent. It is also important to note that the base class is state-oriented. The following table describes the internal states.

State

Description

state_packet_none

No data for a packet.

state_packet_new

A new packet has been read by the try_get function.

state_packet_data

The process is somewhere in the middle of a packet.

state_pakcet_space

All data are sent and a space is generated before a new packet.

state_packet_space_new

Randomize a new space size before the new packet.

The environment has three sequences. All of them generate tuser and tdata signals described in the table below. In the default state, the RX env runs the sequence_lib_rx.

Sequence

Description

sequence_simple_rx

A base random sequence. This sequence behaves very variably.

sequence_full_speed_rx

The sequence gets data and sends them as quicky as possible.

sequence_stop_rx

The sequence doesn’t send any data. Simulates no data on the interface.

sequence_lib_rx

Repetitively randomize and choose one of the previous sequences.

The example below shows how to change the inner sequence to test maximum throughput. The environment runs the sequence_full_speed_rx instead of the sequence_lib_rx.

class axi_rx_speed#(...) extends logic_vector_array_axi_env::sequence_lib_rx#(...);

    function new(string name = "axi_rx_speed");
        super.new(name);
        init_sequence_library();
    endfunction

    virtual function void init_sequence();
        this.add_sequence(logic_vector_array_axi_env::sequence_full_speed_rx #(DATA_WIDTH, TUSER_WIDTH, REGIONS)::get_type());
    endfunction
endclass


class test extends uvm_test
    `uvm_componet_utils(test::base)
    logic_vector_array_axi::env_rx#(...) m_env;

    function new(string name, uvm_component parent = null);
        super.new(name, parent);
    endfunction

    function void build_phase(uvm_phase phase);
        ...
         logic_vector_array_axi_env::sequence_lib_rx#(...)::type_id::set_inst_override(axi_rx_speed#(...)::get_type(),
         {this.get_full_name(), ".m_env.*"});
         m_env = logic_vector_array_axi::env_rx#(...)::type_id::create("m_env", this);
    endfunction
endclass