AVL-AXI-STREAM Configuration

AVL-AXI-STREAM is configured via the provided RTL interface.

The default interface does not contain any modports or clocking blocs to remain compatible with the majority of simulators.

If the user wishes to add directionality or timing to the interface, they can do so by modifying the avl_apb.sv file.

Connection the interface to the APB bus should be done with standard assign statements.

All signals are included, however, optional signals are disabled by default. To enable optional signals, the user must set the appropriate parameters in the interface. Where defined the same configuration naming conventions used in the AMBA specification have been followed.

Assertion checks for optional signals that are not included ensure they remain unchanged during simulation and therefore can be ignored the the user.

These assertion checks are deliberately implemented as initial blocks with $fatals in order to be supported on the widest range of simulators.

// Copyright 2025 Apheleia
//
// Description:
// Apheleia Verification Library AXI_STREAM Interface
// As defined in https://developer.arm.com/documentation/ihi0051/latest/

`define AVL_AXI_STREAM_IMPL_CHECK(cond, signal) \
if (``cond`` == 1) begin : ``signal``_cond \
    initial begin \
        #0.1; \
        @(``signal``) $fatal("%m: ``signal`` not supported in configuration");\
    end \
end : ``signal``_cond

interface axi_stream_if #(parameter string CLASSIFICATION      = "AXI-STREAM",
                          parameter int    VERSION = 4,
                          parameter int    TDATA_WIDTH = 8,
                          parameter int    TID_WIDTH = 0,
                          parameter int    TDEST_WIDTH = 0,
                          parameter int    TUSER_WIDTH = 0,
                          parameter bit    Tready_Signal = 0,
                          parameter bit    Tstrb_Signal = 0,
                          parameter bit    Tkeep_Signal = 0,
                          parameter bit    Tlast_Signal = 0,
                          parameter bit    Wakeup_Signal = 0)();

    localparam TSTRB_WIDTH = int'(TDATA_WIDTH/8);
    localparam TKEEP_WIDTH = int'(TDATA_WIDTH/8);

    logic                                                aclk;
    logic                                                aresetn;
    logic                                                tvalid;
    logic                                                tready;
    logic [TDATA_WIDTH > 0 ? TDATA_WIDTH-1 : 0 :0]       tdata;
    logic [TSTRB_WIDTH > 0 ? TSTRB_WIDTH-1 : 0 :0]       tstrb;
    logic [TKEEP_WIDTH > 0 ? TKEEP_WIDTH-1 : 0 :0]       tkeep;
    logic                                                tlast;
    logic [TID_WIDTH > 0   ? TID_WIDTH-1   : 0 :0]       tid;
    logic [TDEST_WIDTH > 0 ? TDEST_WIDTH-1 : 0 :0]       tdest;
    logic [TUSER_WIDTH > 0 ? TUSER_WIDTH-1 : 0 :0]       tuser;
    logic                                                twakeup;

    initial begin
        assert (TDATA_WIDTH % 8 == 0) else $fatal("TDATA_WIDTH must be multiple of 8");
    end

    generate

        `AVL_AXI_STREAM_IMPL_CHECK((Tready_Signal == 0), tready)

        `AVL_AXI_STREAM_IMPL_CHECK((TDATA_WIDTH == 0), tdata)

        `AVL_AXI_STREAM_IMPL_CHECK((TSTRB_WIDTH == 0), tstrb)

        `AVL_AXI_STREAM_IMPL_CHECK((TKEEP_WIDTH == 0), tkeep)

        `AVL_AXI_STREAM_IMPL_CHECK((Tlast_Signal == 0), tlast)

        `AVL_AXI_STREAM_IMPL_CHECK((TID_WIDTH == 0), tid)

        `AVL_AXI_STREAM_IMPL_CHECK((TDEST_WIDTH == 0), tdest)

        `AVL_AXI_STREAM_IMPL_CHECK((TUSER_WIDTH == 0), tuser)

        `AVL_AXI_STREAM_IMPL_CHECK(((VERSION < 5) || (Wakeup_Signal == 0)), twakeup)

    endgenerate

endinterface

`undef AVL_AXI_STREAM_IMPL_CHECK

Integrating with a Build Environment

AVL-AXI-STREAM comes with a tools utility avl_axi_stream._tools.get_verilog() to help integrate the library into your build environment.

This is exposed to the environment as the command line tool avl_axi_stream_get_verilog which returns a list of all RTL files required for AVL-AXI-STREAM.

An example of integrating with the verilator build environment is shown below:

# HDL source files
VERILOG_SOURCES      += $(shell avl-axi-stream-get-verilog)

# include cocotb's make rules to take care of the simulator setup
include $(shell cocotb-config --makefiles)/Makefile.sim

Connecting to the AVL Environment

The recommended way to connect to the AVL environment is via the factory.

avl.Factory.set_variable("*.hdl", dut.apb_if)

When the agent is created it will automatically use this factory setting to connect to the APB interface.

Parameterization

The AVL environment automatically picks up the parameters (version, features and width) from the RTL interface. This ensures the AVL environment and HDL environment are always in sync.

Once connected the agent creates and internal avl_axi_stream.Interface object which is used to act as the physical interface to the AXI-STREAM bus and share the parameters with the rest of the environment.

This internal interface in generated to serve 2 purposes:

  1. It abstracts the simulator specific behaviour of the generate blocks. Some simulators flatten the generate blocks, while others do not.

  2. It provides Interface.get and Interface.set methods to access the HDL with knowledge of which signals are present based on the configuration of the bus.