AXI4LITE2MI

ENTITY AXI4LITE2MI IS

This component converts AXI4-Lite interface (slave) to MI interface (master).

Generics

Generic

Type

Default

Description

DATA_WIDTH

natural

32

Data word width in bits, must be 32

ADDR_WIDTH

natural

32

Address word width in bits

ADDR_MASK

std_logic_vector(ADDR_WIDTH-1 downto 0)

(others => ‘1’)

Address mask vector

DEVICE

string

“AGILEX”

Target device

Ports

Port

Type

Mode

Description

=====

Clock and Reset

=====

=====

CLK

std_logic

in

RESET

std_logic

in

=====

AXI4-Lite interface (slave)

=====

=====

AXI_AWADDR

std_logic_vector(ADDR_WIDTH - 1 downto 0)

in

AXI_AWVALID

std_logic

in

AXI_AWREADY

std_logic

out

AXI_WDATA

std_logic_vector(DATA_WIDTH - 1 downto 0)

in

AXI_WSTRB

std_logic_vector(DATA_WIDTH / 8 - 1 downto 0)

in

AXI_WVALID

std_logic

in

AXI_WREADY

std_logic

out

AXI_BRESP

std_logic_vector(1 downto 0)

out

AXI_BVALID

std_logic

out

AXI_BREADY

std_logic

in

AXI_ARADDR

std_logic_vector(ADDR_WIDTH - 1 downto 0)

in

AXI_ARVALID

std_logic

in

AXI_ARREADY

std_logic

out

AXI_RDATA

std_logic_vector(DATA_WIDTH - 1 downto 0)

out

AXI_RRESP

std_logic_vector(1 downto 0)

out

AXI_RVALID

std_logic

out

AXI_RREADY

std_logic

in

=====

MI interface (master)

=====

=====

MI_DWR

std_logic_vector(DATA_WIDTH-1 downto 0)

out

MI_ADDR

std_logic_vector(ADDR_WIDTH-1 downto 0)

out

MI_RD

std_logic

out

MI_WR

std_logic

out

MI_BE

std_logic_vector((DATA_WIDTH/8)-1 downto 0)

out

MI_DRD

std_logic_vector(DATA_WIDTH-1 downto 0)

in

MI_ARDY

std_logic

in

MI_DRDY

std_logic

in

Read MI bus specification for more information on the MI bus. Refer to the AMBA AXI Protocol Specification for more information on the AXI4-Lite interface.

The component allows an AXI4-Lite master (e.g., an embedded processor or a vendor IP core with an AXI4-Lite management port) to access firmware components connected to the MI bus. It is an AXI4-Lite slave on one side and an MI master on the other side. It is the counterpart of the MI2AXI4 converter.

Specification

Both interfaces use common clock and reset signals. RESET is synchronous and active high; it resets only the FSM state, the data/address registers are not reset.

The component processes transactions strictly one at a time (no pipelining, no outstanding transactions). A new AXI request is accepted only when the previous one has been fully completed, including its AXI response. Every AXI read is translated to exactly one MI read request and every AXI write to exactly one MI write request.

Arbitration – When both AXI_ARVALID and AXI_AWVALID are asserted in the same cycle while the component is idle, the read is served first. A master issuing reads back-to-back can therefore delay writes.

Address – The AXI address (AXI_ARADDR or AXI_AWADDR) is masked with the ADDR_MASK generic (bitwise AND), registered and then presented on MI_ADDR. No other modification is performed (the address is not aligned by the component), so the byte address issued by the AXI master is passed to the MI bus as is. Follow the MI address alignment convention and use addresses aligned to DATA_WIDTH/8 bytes.

Write data and byte enable – AXI_WDATA and AXI_WSTRB are registered and presented on MI_DWR and MI_BE, respectively. For MI read requests, MI_BE is set to all ones (the whole data word is read), as AXI4-Lite has no byte strobes for reads.

Read data – MI_DRD is registered when MI_DRDY is asserted and returned on AXI_RDATA.

Responses – AXI_BRESP and AXI_RRESP are always "00" (OKAY). The MI bus provides no means of signalling an error, so SLVERR/DECERR responses are never generated.

Write channel ordering – AXI_WREADY is asserted only after the write address has been accepted. The master may assert AXI_WVALID before, together with, or after AXI_AWVALID, as permitted by the AXI specification; the write data are simply held by the master until the address handshake completes.

Combinational paths – In the idle state AXI_ARREADY and AXI_AWREADY depend combinationally on AXI_ARVALID and AXI_AWVALID (this is allowed by the AXI specification). There is no combinational path from the MI inputs to the AXI outputs or from the AXI inputs to the MI outputs.

Supported AXI4-Lite signals

Channel

Signals

Write address (AW)

AXI_AWADDR, AXI_AWVALID, AXI_AWREADY

Write data (W)

AXI_WDATA, AXI_WSTRB, AXI_WVALID, AXI_WREADY

Write response (B)

AXI_BRESP, AXI_BVALID, AXI_BREADY

Read address (AR)

AXI_ARADDR, AXI_ARVALID, AXI_ARREADY

Read data (R)

AXI_RDATA, AXI_RRESP, AXI_RVALID, AXI_RREADY

The protection signals AXI_AWPROT and AXI_ARPROT are not present; leave them unconnected on the master side. The optional MI metadata port (MI_MWR) is not present either.

FSM description

The whole conversion is controlled by a single FSM with the following states:

State

Description

Next state

ST_IDLE

No transaction in progress. If AXI_ARVALID is asserted, AXI_ARREADY is asserted in the same cycle, the masked read address is registered and the byte enables are set to all ones. Otherwise, if AXI_AWVALID is asserted, AXI_AWREADY is asserted and the masked write address is registered.

ST_READ on AXI_ARVALID, else ST_WRITE on AXI_AWVALID

ST_READ

MI read request is issued (MI_RD = 1, MI_ADDR = registered read address, MI_BE = all ones) and held until the MI slave asserts MI_ARDY. If MI_DRDY is asserted together with MI_ARDY, MI_DRD is registered immediately.

ST_READ_RESP on MI_ARDY and MI_DRDY; ST_READ_ARDY on MI_ARDY only

ST_READ_ARDY

MI read request has been accepted (MI_RD = 0); waiting for the read data. MI_DRD is registered when MI_DRDY is asserted.

ST_READ_RESP on MI_DRDY

ST_READ_RESP

Registered read data are presented on the R channel (AXI_RVALID = 1, AXI_RRESP = OKAY) until the master accepts them.

ST_IDLE on AXI_RREADY

ST_WRITE

Write address has been accepted. AXI_WREADY is asserted; AXI_WDATA and AXI_WSTRB are registered when AXI_WVALID is asserted.

ST_WRITE_DATA on AXI_WVALID

ST_WRITE_DATA

MI write request is issued (MI_WR = 1, MI_ADDR = registered write address, MI_DWR/MI_BE = registered data/strobes) and held until the MI slave asserts MI_ARDY.

ST_WRITE_RESP on MI_ARDY

ST_WRITE_RESP

Write response is presented on the B channel (AXI_BVALID = 1, AXI_BRESP = OKAY) until the master accepts it.

ST_IDLE on AXI_BREADY

The FSM stays in its current state whenever the condition for leaving it is not met. The state transitions can be summarized as follows:

             AXI_ARVALID
   +---------------------------> ST_READ ---------------------+
   |                                |                         | MI_ARDY &
   |                                | MI_ARDY &               | MI_DRDY
   |                                | !MI_DRDY                |
   |                                v                         v
   |                          ST_READ_ARDY ------------> ST_READ_RESP
   |                                          MI_DRDY         |
   |                                                          | AXI_RREADY
ST_IDLE <-----------------------------------------------------+
 |   ^
 |   +----------------------------------------------------+
 |                                                        | AXI_BREADY
 | !AXI_ARVALID & AXI_AWVALID                             |
 v                                                        |
ST_WRITE ------------> ST_WRITE_DATA ------------> ST_WRITE_RESP
         AXI_WVALID                   MI_ARDY

Timing

Assuming the MI slave responds immediately (MI_ARDY and MI_DRDY asserted in the first cycle of the request) and the AXI master is always ready to accept responses (AXI_RREADY/AXI_BREADY held high), the transactions take:

  • Read: 3 clock cycles – AR handshake (ST_IDLE), MI read request (ST_READ), R handshake (ST_READ_RESP). AXI_RVALID is asserted two cycles after the AR handshake.

  • Write: 4 clock cycles – AW handshake (ST_IDLE), W handshake (ST_WRITE), MI write request (ST_WRITE_DATA), B handshake (ST_WRITE_RESP). AXI_BVALID is asserted three cycles after the AW handshake.

Every cycle of MI_ARDY/MI_DRDY latency on the MI side and every cycle of AXI_WVALID/AXI_RREADY/AXI_BREADY delay on the AXI side extends the transaction accordingly. Hence, the maximum throughput is one read per 3 cycles or one write per 4 cycles.

Warning

The component has no timeout. If the MI slave never asserts MI_ARDY (or MI_DRDY for a read), for example because the address is not mapped to any MI component, the FSM waits forever and the AXI master is blocked. Make sure that the whole AXI address range reachable through this component is mapped on the MI side (e.g., by an MI splitter with a default/catch-all port).

Note

The DATA_WIDTH generic must be set to 32. The DEVICE generic is currently unused and has no effect.

Verification

The component is verified with cocotb in the cocotb/ directory. The AXI4-Lite port is driven by AxiLiteMaster from cocotbext-axi, the MI port is terminated by an MI slave memory model with configurable MI_ARDY backpressure and MI_DRDY latency, including MI_DRDY in the same cycle as MI_ARDY. Two independent observers check the DUT: an AXI4-Lite checker on the slave port (handshake rules, one transaction at a time, read priority, WREADY only after the address handshake, OKAY responses) and the MI slave model on the master port (request held until MI_ARDY, MI_BE all ones for reads, no new request while a read response is pending). At the end of every test, a scoreboard compares each AXI beat with its MI request, the returned read data and the final content of the MI memory.

The tests cover a randomized mix of concurrent reads and writes in several backpressure scenarios, write-and-read-back of partial and unaligned accesses, read priority, the order of the AW and W channels, MI read latency and MI_ARDY stalls, response backpressure, the latency and throughput listed in the Timing section, the full address range, reset during traffic and an idle bus.

cd cocotb
make cocotb-venv
source venv-AXI4LITE2MI/bin/activate
make

The number of random transactions per scenario is set by the COCOTB_TRANSACTIONS environment variable (default 2000). ver_settings.py lists further generic combinations for build/scripts/multi_ver/multi_ver_cocotb.py; the tests read ADDR_WIDTH and ADDR_MASK from the DUT, so any configuration is checked against its own address mapping.

An older directed VHDL testbench is located in the sim/ directory (sim/testbench.vhd). It covers reads with MI_DRDY asserted together with MI_ARDY, reads with delayed MI_DRDY, reads with delayed MI_ARDY, and writes with AXI_WVALID asserted after or together with AXI_AWVALID and with immediate or delayed MI_ARDY. The testbench is not self-checking; the results have to be inspected in the waveform.