Correctly Matching Xilinx Native FIFOs to Streaming AXI FIFOs

It could be unusual to connect a Xilinx's Native FIFO interface to a streaming AXI FIFO, but sometimes this small trick might be necessary. For instance, the Native FIFOs can be configured with non-symmetric aspect ratios if the Independent Clocks Block RAM configuration is selected. This feature is very useful to appropriately cross different clock domains. For instance the input port of the FIFO could be at 100 MHz with a data width of 256 bits and the output at 50 MHz with a data with of 512 bits.

The AXI-Streaming FIFOs don't have the ability to configure different aspect ratios between the input and output ports, but they are compatible with different AXI standard IP blocks provided by Xilinx. The IP integrator tool of Vivado allows the easy interconnection between IP Cores using a graphical interface.

To demonstrate a case where this might be useful, a DDR3 controller is to be design using the IP Cores provided by Xilinx. The idea is to achieve a behavior so that a simple very large FIFO is instantiated instead of having to deal with addresses in the DDR3 Memory. For this the DataMover IP Block is selected, effectively translating the Address mapped domain (AXI-MM) into a streaming domain (AXI-S). This post will go only in the detail of interconnecting two Native FIFOs with different aspect ratios between input and output to the AXI-S interfaces of the DataMover which is the same interface as if it was a AXI-Streaming FIFO.

The Block Design tool of Vivado is not enough to implement some simple connections containing some logic gates, therefore it is necessary to create a small Verilog or VHDL file which do the connections for us. Also, in the case of using the Datamover as in the image, it also issues the commands and checks for the statuses.


Block Design

For a simple Native FIFO to AXI FIFO these are the only connections we would need to implement.

assign s_axis_s2mm_tkeep = 64'hFFFF_FFFF_FFFF_FFFF;

assign s2mm_fifo_rd_en = s_axis_s2mm_tready & ~s2mm_fifo_empty;
assign s_axis_s2mm_tvalid = s_axis_s2mm_tready & s2mm_fifo_valid & ~s2mm_fifo_empty;

assign m_axis_mm2s_tready = ~mm2s_fifo_prog_full;
assign mm2s_fifo_wr_en = m_axis_mm2s_tready & m_axis_mm2s_tvalid;

Waveform of the involved signals created with Wavedrom

One final remark is that the input FIFO, to convert from Native to Streaming FIFO it is necessary to be First Word Fall Through, this will correctly align the s_axis_s2mm_tready signal to the s_axis_s2mm_tvalid. For the output FIFO from Streaming to Native it is not required to have this feature, and probably we do not even want it, just by having the Valid signal when data is available is sufficient for the subsequent stages.


Comments powered by Disqus