MicroZed Chronicles: AXI Stream FIFO IP Core

April 15, 2022


Editor’s Note: This content is republished from the MicroZed Chronicles, with permission from the author.

 

We looked at the AXI Virtual FIFO Controller in a blog a couple weeks ago and created an example design running on the Arty S7-50 while examining the input path. This design used the XADC to output an AXI stream which is input into a AXI Virtual FIFO Controller which then stores the samples in DDR. The read path of the example implemented a AXI Stream FIFO IP core connected to a MicroBlaze processor. This allows the MicroBlaze application to process the samples as they are pulled from the Virtual FIFO in the DDR.

 

MZ_439_AXI_Stream_FIFO_IP

In this blog, we are going to examine the output path that looks at how the AXI Stream FIFO is used to read out samples from the AXI Virtual FIFO in DDR.

If you have not come across it before, the AXI Stream FIFO allows developers to be able to access AXI streams from AXI memory mapped peripherals without the need to implement a full DMA solution. To enable this, the AXI Stream FIFO provides the ability to read and write from AXI MM to AXI streams. Just like this example, this can be used to interact with an AXI Virtual FIFO Controller or with IP like the Fast Fourier Transform which has configuration data over AXIS.

To interface with our designs, the AXI Stream FIFO provides the following interfaces:

  • RX Stream Data – This is the data to be received by the AXI Stream FIFO
  • TX Stream Data – This is data transmitted by the AXI Stream FIFO
  • TX Stream Control Data – This interface supports the transmission protocol for the AXI Ethernet IP cores
  • AXI Lite – Memory mapped interface for accessing configuration registers and data Tx and Rx data
  • AXI MM – Optional AXI MM interface for Tx/Rx of data
MZ_439_AXI_Stream_FIFO_Interfaces

The AXI Stream FIFO presents a simple register interface that enables the user to define the following:

  • Transmission Length – The length of the data to be transmitted
  • Transmission Vacancy – The number of slots in the FIFO currently empty
  • Receive Length – The length of the data packet received
  • Receive Occupancy – The number of occupied slots in the FIFO  
  • Receive / Transmission Destination – Side band AXIS Signal TIDest
  • Receive / Transmission ID – Side band AXIS Signal TId
  • Receive / Transmission User – Side band AXIS Signal TUser
  • System / Transmission and Receive Interrupts
  • System / Transmission and Receive Resets

 

Data is written or read from the AXI Stream FIFO via a memory address which writes into or reads from the FIFO.

In this application, we are only using the receive path to read from the AXI Virtual FIFO Controller using the MicroBlaze.

Setting this up in software is very straight forward. We need to do the following within the software:

  1. Configure the AXI Stream FIFO
  2. Read the occupancy of the FIFO
  3. Read out the indicated number of words from the FIFO
  4. Process the samples as desired in the application software 

#include <stdio.h>

#include "platform.h"

#include "xil_printf.h"

#include "xstreamer.h"

#include "xllfifo.h"

 

#define FIFO_DEV_ID XPAR_AXI_FIFO_0_DEVICE_ID

#define WORD_SIZE 4

 

XLlFifo_Config *Config;

XLlFifo FifoInstance;

 

int main()

{

    int Status,i;

    u32 RxWord;

    static u32 ReceiveLength;

    init_platform();

 

    Config = XLlFfio_LookupConfig(FIFO_DEV_ID);

    XLlFifo_CfgInitialize(&FifoInstance, Config, Config->BaseAddress);

 

    print("Hello World\n\r");

    print("Successfully ran Hello World application");

 

    /* Check for the Reset value */

    Status = XLlFifo_Status(&FifoInstance);

    XLlFifo_IntClear(&FifoInstance,0xffffffff);

    Status = XLlFifo_Status(&FifoInstance);

    if(Status != 0x0) {

        xil_printf("\n ERROR : Reset value of ISR0 : 0x%x\t"

        "Expected : 0x0\n\r",

        XLlFifo_Status(&FifoInstance));

        return XST_FAILURE;

    }

 

    while(1){

        while(XLlFifo_iRxOccupancy(&FifoInstance)) {

            /* Read Receive Length */

            ReceiveLength = (XLlFifo_iRxGetLen(&FifoInstance))/WORD_SIZE;

            for (i=0; i < ReceiveLength; i++) {

                RxWord = XLlFifo_RxGetWord(&FifoInstance);

                printf("%x \n\r",RxWord);

            }

        }

    }

    cleanup_platform();

    return 0;

}

The entire application as created can be access via my GitHub.

Having looked at the AXI Virtual FIFO Controller and the AXI Stream FIFO, these IP cores are both very useful in applications where we want to buffer large amounts of data and interact with AXI streams without the overhead of a DMA.