Electrical – How does one read a FIFO outside Qsys system using Nios II

intel-fpganios-ii

There is a FIFO block that has Avalon interface compatible with Qsys that can be used in Qsys systems. However, in my case there is an external block that generates data that is to be read by a Nios II. The external block has a FIFO interface, thus the signals are basically q, empty and rdreq. I could try to use a PIO block to connect to the external FIFO and write some simple drivers to aid in communication. However, is there a better way to do this? Is it possible to somehow communiate with this external FIFO as if it was in the Qsys block with Avalon MM or Avalon streaming interface?

Best Answer

FIFOs are typically used with streaming type interfaces. You can actually convert your FIFO signals into an Avalon ST interface quite easily. They map as follows:

  • Valid = ~empty
  • Ready = rdreq
  • Data = q

You don't actually need any other signals to make Avalon ST. The only weird one above is making sure to invert the empty signal.

Once in Qsys you will need to convert from Avalon ST to Avalon MM of which there are a few options. You could for example use a DMA controller to read data from the FIFO into on-chip memory that Nios can then read (e.g. the Scatter-Gather DMA Controller in Qsys).


Alternatively thinking about it, it might be easier to simply build a module to create an Avalon-MM interface. Something like:

module fifo_to_mm (
    input         clk,
    input         rst,

    input  [31:0] q,
    output        rdreq,
    input         empty,

    input         read,
    input         address,
    output [31:0] readdata
);

assign rdreq = read && (address == 1'b0);
assign readdata = address ? {31'b0, empty} : q;

endmodule

In that example, if you read address 0, it will read the next word from the FIFO. If you read address 1, it will tell you whether or not the FIFO has any data available.

I would make a TCL wrapper around this module (you can use the "File->New Component" tool in Qsys to help you).

  • Add a clock and reset interface. You should connect these to the same clock/reset that you feed out for your FIFO.
  • Add the FIFO signals into a conduit which you export from your Qsys system.
  • Add the Avalon-MM signals to an Av-MM slave interface which is configured as:
    • Bits Per Symbol: 8
    • Read wait: 0
    • Read latency: 1 or 2 (*)
    • Address units: WORDS

You should then be able to hook this straight up to Nios, and Qsys will take care of the interconnect fabric for you.


(*) read latency depends on your FIFO latency - i.e. number of cycles between asserting the rdreq signal and the q signal being updated.

If you want, you can register the readdata signal to improve Fmax, in which case add 1 to the read latency.