Electronic – Access elements randomly in RAM based FIFO VHDL FPGA

fpgaintel-fpgaramvhdl

The thing is: new data is being generated every "time step" that can be few clock cycles. So I want to store the data generated for few time steps in a "buffer". The data must be stored like in a queue. That is, the latest datum goes at the end of the queue and the first one is discarded. All the rest are moved one step ahead. That is, the second becomes the first, the third becomes the second and so on.

I want to avoid registers to save circuit area. That is why I am thinking of using on-chip memory like SRAM.

It can be understood as a FIFO based in RAM in which I could access any stored element by means of an address.

Something like:

entity special_fifo is
  generic (
    WIDTH : natural := 8;
    DEPTH : integer := 32;
    WIDTH_DEPTH : integer:=5
    );
  port (

    clock      : in std_logic;
    reset      : in std_logic;
    wren      : in std_logic;
    ren     : in std_logic;
    address    : std_logic_vector(WIDTH_DEPTH-1 downto 0);—-This is the thing that I would like to have
    data      : in std_logic_vector(WIDTH-1 downto 0);
    q       : out std_logic_vector(WIDTH-1 downto 0)

end special_fifo;

Can anyone clarify if it is doable?

Another way to ask the question could be:

Is it possible to shift the elements stored in RAM as if they formed an array. Something like this:
RAM(address)<=RAM(address+1).

The number of clock cycles required does not matter in principle.

Edit: The data does need to be moved in the ram. It is data that has to be updated (thats why the latest is incorporated whereas the oldest is removed). Every single element of the current data must be accessible by means of the address. It is like updating a matrix row by row.

Best Answer

Besides using RAM blocks as a FIFOs with read and write circular pointers, Xilinx FPGAs can transform some logic cells into shift registers (SRL16, SRL32) which can be used to implement small synchronous FIFOs (for example 32bits * 16)

Here is a sample inferrence :

  -- FIFO
  IF push='1' THEN
    fifo<=data_in & fifo(0 TO FIFO_SIZE-2); -- Shift register
  END IF;
  IF push='1' AND pop='0' THEN
    IF not_empty='1' THEN
      level<=level+1;
    END IF;
    not_empty<='1';
  ELSIF push='0' AND pop='1' THEN
    IF level>0 THEN
      level<=level-1;
    ELSE
      not_empty<='0';
    END IF;
  END IF;

  IF flush='1' THEN
     not_empty<='0';
     level<=0;
  END IF;

  data_out<=fifo(level)

Intel/Altera Quartus handles also well that syntax and use efficient distributed RAM blocks (not hundreds of DFFs)