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.
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
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:
Configure the AXI Stream FIFO
Read the occupancy of the FIFO
Read out the indicated number of words from the FIFO
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.