Xilinx FIFO

I am using coregen to generate FIFOs for my design and get typically 77LUTs and 38Registers for a 1 BLOCK RAM FIFO. Seems like a lot. I remember using Cypress parts and all the addressing and such for a FIFO was already pretty much incorporated into the Channel RAM, no logic was used outside the Channel RAM to do the basic RAM functions including FIFO. Am I doing Xilinx right? Is there some primitive I should be using instead?

Brad Smallridge b r a d @ a i v i s i o n . c o m

Reply to
Brad Smallridge
Loading thread data ...

In the new Virtex-4 devices, we incorporate a FIFO controller in every BlockRAM,so the controller is free, and it can handle asynchronous clocks at up to 500 MHz.

The high logic count for the controller that you quoted may be due to elaborate design tricks to cope with fast asynchronous clocks, and the need to generate a reliable EMPTY and FULL signal, even at very high speed. And perhaps also a partial FULL/EMPTY output. That requires duplicated Binary and Gray counters with sophisticated comparators and special precautions against metastability problems (All of which we did in the hidden controller in Virtex-4). If you are not running so fast, some of this can be eliminated in your Virtex-II or Spartan design, but you have to be careful. Asynchronous clocks can bite you, unless you really know what you are doing... Peter Alfke

Reply to
Peter

No, as far as I know I picked the Synchronous option. And there seems to be no way to elliminate the Empty and Full flag outputs, which I don't think I will be using, left them open in the instantiation. There also is no relative placing of the support counters, either with respect to each other or close to the RAM block. Nice to know that the Virtex has some of this stuff built in.

Brad

Reply to
Brad Smallridge

Brad, if your FIFO uses one common clock for write and read, and you really do not care about FULL or EMPTY (because your system design takes care of or avoids that situation), then just ignore the core generator and simply hook two counters to the two address ports, and declare one port the write input side, and the other one the read output side. That means you need one slice per two address bits, and totally exactly as many slices as your addressing is wide, i.e. 16 max.

Most of the complexity (and trouble and frustration...) of a FIFO design is due to the asynchronous nature of the two clocks, while reliable EMPTY/FULL signals must be decoded. Peter Alfke

Reply to
Peter

Reply to
Symon

is

write

That's unfortunately true. Came too late for me to catch... The user should select the almost FULL output instead. FULL is not as critical a signal as EMPTY. A well-designed FIFO system should never go FULL, and the exact "full-ness" level is not so important. Hardly anybody cares whether the FIFO can hold 1024, 1023 or

1020 entries. But the user often really wants to empty the FIFO content completely. That's why reliable EMPTY decoding is more important than exact FULL decoding. Nevertheless, it's a cosmetic flaw that will be fixed next time around. Peter Alfke (FIFO is my middle name)
Reply to
Peter

Thanks Peter,

I took your advice and I attached the code below. It's for a 9 bit input, 9 bit output, 2K deep FIFO. Seems to simulate OK.

library IEEE;

use IEEE.STD_LOGIC_1164.ALL;

use IEEE.STD_LOGIC_ARITH.ALL;

use IEEE.STD_LOGIC_UNSIGNED.ALL;

library UNISIM;

use UNISIM.VComponents.all;

entity fifo9 is

port(

clk : in std_logic;

reset : in std_logic;

fifowren : in std_logic;

fiforden : in std_logic;

fifoin : in std_logic_vector(8 downto 0);

fifoout: out std_logic_vector(8 downto 0)

);

end fifo9;

architecture Behavioral of fifo9 is

component RAMB16_S9_S9

generic (

WRITE_MODE_A : string := "READ_FIRST";

WRITE_MODE_B : string := "READ_FIRST";

INIT_A : bit_vector := X"000";

SRVAL_A : bit_vector := X"000";

INIT_B : bit_vector := X"000";

SRVAL_B : bit_vector := X"000";

INITP_00 : bit_vector(255 downto 0) :=

X"0000000000000000000000000000000000000000000000000000000000000000";

INITP_01 : bit_vector(255 downto 0) :=

X"0000000000000000000000000000000000000000000000000000000000000000";

INITP_02 : bit_vector(255 downto 0) :=

X"0000000000000000000000000000000000000000000000000000000000000000";

INITP_03 : bit_vector(255 downto 0) :=

X"0000000000000000000000000000000000000000000000000000000000000000";

INITP_04 : bit_vector(255 downto 0) :=

X"0000000000000000000000000000000000000000000000000000000000000000";

INITP_05 : bit_vector(255 downto 0) :=

X"0000000000000000000000000000000000000000000000000000000000000000";

INITP_06 : bit_vector(255 downto 0) :=

X"0000000000000000000000000000000000000000000000000000000000000000";

INITP_07 : bit_vector(255 downto 0) :=

X"0000000000000000000000000000000000000000000000000000000000000000";

INIT_00 : bit_vector(255 downto 0) :=

X"0000000000000000000000000000000000000000000000000000000000000000";

INIT_01 : bit_vector(255 downto 0) :=

X"0000000000000000000000000000000000000000000000000000000000000000";

INIT_02 : bit_vector(255 downto 0) :=

X"0000000000000000000000000000000000000000000000000000000000000000";

INIT_03 : bit_vector(255 downto 0) :=

X"0000000000000000000000000000000000000000000000000000000000000000";

INIT_04 : bit_vector(255 downto 0) :=

X"0000000000000000000000000000000000000000000000000000000000000000";

INIT_05 : bit_vector(255 downto 0) :=

X"0000000000000000000000000000000000000000000000000000000000000000";

INIT_06 : bit_vector(255 downto 0) :=

X"0000000000000000000000000000000000000000000000000000000000000000";

INIT_07 : bit_vector(255 downto 0) :=

X"0000000000000000000000000000000000000000000000000000000000000000";

INIT_08 : bit_vector(255 downto 0) :=

X"0000000000000000000000000000000000000000000000000000000000000000";

INIT_09 : bit_vector(255 downto 0) :=

X"0000000000000000000000000000000000000000000000000000000000000000";

INIT_0A : bit_vector(255 downto 0) :=

X"0000000000000000000000000000000000000000000000000000000000000000";

INIT_0B : bit_vector(255 downto 0) :=

X"0000000000000000000000000000000000000000000000000000000000000000";

INIT_0C : bit_vector(255 downto 0) :=

X"0000000000000000000000000000000000000000000000000000000000000000";

INIT_0D : bit_vector(255 downto 0) :=

X"0000000000000000000000000000000000000000000000000000000000000000";

INIT_0E : bit_vector(255 downto 0) :=

X"0000000000000000000000000000000000000000000000000000000000000000";

INIT_0F : bit_vector(255 downto 0) :=

X"0000000000000000000000000000000000000000000000000000000000000000";

INIT_10 : bit_vector(255 downto 0) :=

X"0000000000000000000000000000000000000000000000000000000000000000";

INIT_11 : bit_vector(255 downto 0) :=

X"0000000000000000000000000000000000000000000000000000000000000000";

INIT_12 : bit_vector(255 downto 0) :=

X"0000000000000000000000000000000000000000000000000000000000000000";

INIT_13 : bit_vector(255 downto 0) :=

X"0000000000000000000000000000000000000000000000000000000000000000";

INIT_14 : bit_vector(255 downto 0) :=

X"0000000000000000000000000000000000000000000000000000000000000000";

INIT_15 : bit_vector(255 downto 0) :=

X"0000000000000000000000000000000000000000000000000000000000000000";

INIT_16 : bit_vector(255 downto 0) :=

X"0000000000000000000000000000000000000000000000000000000000000000";

INIT_17 : bit_vector(255 downto 0) :=

X"0000000000000000000000000000000000000000000000000000000000000000";

INIT_18 : bit_vector(255 downto 0) :=

X"0000000000000000000000000000000000000000000000000000000000000000";

INIT_19 : bit_vector(255 downto 0) :=

X"0000000000000000000000000000000000000000000000000000000000000000";

INIT_1A : bit_vector(255 downto 0) :=

X"0000000000000000000000000000000000000000000000000000000000000000";

INIT_1B : bit_vector(255 downto 0) :=

X"0000000000000000000000000000000000000000000000000000000000000000";

INIT_1C : bit_vector(255 downto 0) :=

X"0000000000000000000000000000000000000000000000000000000000000000";

INIT_1D : bit_vector(255 downto 0) :=

X"0000000000000000000000000000000000000000000000000000000000000000";

INIT_1E : bit_vector(255 downto 0) :=

X"0000000000000000000000000000000000000000000000000000000000000000";

INIT_1F : bit_vector(255 downto 0) :=

X"0000000000000000000000000000000000000000000000000000000000000000";

INIT_20 : bit_vector(255 downto 0) :=

X"0000000000000000000000000000000000000000000000000000000000000000";

INIT_21 : bit_vector(255 downto 0) :=

X"0000000000000000000000000000000000000000000000000000000000000000";

INIT_22 : bit_vector(255 downto 0) :=

X"0000000000000000000000000000000000000000000000000000000000000000";

INIT_23 : bit_vector(255 downto 0) :=

X"0000000000000000000000000000000000000000000000000000000000000000";

INIT_24 : bit_vector(255 downto 0) :=

X"0000000000000000000000000000000000000000000000000000000000000000";

INIT_25 : bit_vector(255 downto 0) :=

X"0000000000000000000000000000000000000000000000000000000000000000";

INIT_26 : bit_vector(255 downto 0) :=

X"0000000000000000000000000000000000000000000000000000000000000000";

INIT_27 : bit_vector(255 downto 0) :=

X"0000000000000000000000000000000000000000000000000000000000000000";

INIT_28 : bit_vector(255 downto 0) :=

X"0000000000000000000000000000000000000000000000000000000000000000";

INIT_29 : bit_vector(255 downto 0) :=

X"0000000000000000000000000000000000000000000000000000000000000000";

INIT_2A : bit_vector(255 downto 0) :=

X"0000000000000000000000000000000000000000000000000000000000000000";

INIT_2B : bit_vector(255 downto 0) :=

X"0000000000000000000000000000000000000000000000000000000000000000";

INIT_2C : bit_vector(255 downto 0) :=

X"0000000000000000000000000000000000000000000000000000000000000000";

INIT_2D : bit_vector(255 downto 0) :=

X"0000000000000000000000000000000000000000000000000000000000000000";

INIT_2E : bit_vector(255 downto 0) :=

X"0000000000000000000000000000000000000000000000000000000000000000";

INIT_2F : bit_vector(255 downto 0) :=

X"0000000000000000000000000000000000000000000000000000000000000000";

INIT_30 : bit_vector(255 downto 0) :=

X"0000000000000000000000000000000000000000000000000000000000000000";

INIT_31 : bit_vector(255 downto 0) :=

X"0000000000000000000000000000000000000000000000000000000000000000";

INIT_32 : bit_vector(255 downto 0) :=

X"0000000000000000000000000000000000000000000000000000000000000000";

INIT_33 : bit_vector(255 downto 0) :=

X"0000000000000000000000000000000000000000000000000000000000000000";

INIT_34 : bit_vector(255 downto 0) :=

X"0000000000000000000000000000000000000000000000000000000000000000";

INIT_35 : bit_vector(255 downto 0) :=

X"0000000000000000000000000000000000000000000000000000000000000000";

INIT_36 : bit_vector(255 downto 0) :=

X"0000000000000000000000000000000000000000000000000000000000000000";

INIT_37 : bit_vector(255 downto 0) :=

X"0000000000000000000000000000000000000000000000000000000000000000";

INIT_38 : bit_vector(255 downto 0) :=

X"0000000000000000000000000000000000000000000000000000000000000000";

INIT_39 : bit_vector(255 downto 0) :=

X"0000000000000000000000000000000000000000000000000000000000000000";

INIT_3A : bit_vector(255 downto 0) :=

X"0000000000000000000000000000000000000000000000000000000000000000";

INIT_3B : bit_vector(255 downto 0) :=

X"0000000000000000000000000000000000000000000000000000000000000000";

INIT_3C : bit_vector(255 downto 0) :=

X"0000000000000000000000000000000000000000000000000000000000000000";

INIT_3D : bit_vector(255 downto 0) :=

X"0000000000000000000000000000000000000000000000000000000000000000";

INIT_3E : bit_vector(255 downto 0) :=

X"0000000000000000000000000000000000000000000000000000000000000000";

INIT_3F : bit_vector(255 downto 0) :=

X"0000000000000000000000000000000000000000000000000000000000000000"

);

port (DIA : in STD_LOGIC_VECTOR (7 downto 0);

DIB : in STD_LOGIC_VECTOR (7 downto 0);

DIPA : in STD_LOGIC_VECTOR (0 downto 0);

DIPB : in STD_LOGIC_VECTOR (0 downto 0);

ENA : in STD_logic;

ENB : in STD_logic;

WEA : in STD_logic;

WEB : in STD_logic;

SSRA : in STD_logic;

SSRB : in STD_logic;

CLKA : in STD_logic;

CLKB : in STD_logic;

ADDRA : in STD_LOGIC_VECTOR (10 downto 0);

ADDRB : in STD_LOGIC_VECTOR (10 downto 0);

DOA : out STD_LOGIC_VECTOR (7 downto 0);

DOB : out STD_LOGIC_VECTOR (7 downto 0);

DOPA : out STD_LOGIC_VECTOR (0 downto 0);

DOPB : out STD_LOGIC_VECTOR (0 downto 0)

);

end component;

signal fifowraddr : std_logic_vector(10 downto 0);

signal fifordaddr : std_logic_vector(10 downto 0);

begin

bram00 : RAMB16_S9_S9

port map (

DIA => fifoin(7 downto 0),

DIB => (others=>'0'),

DIPA => fifoin(8 downto 8),

DIPB => (others=>'0'),

ENA => '1',

ENB => '1',

WEA => fifowren,

WEB => '0',

SSRA => '0',

SSRB => '0',

CLKA => clk,

CLKB => clk,

ADDRA => fifowraddr,

ADDRB => fifordaddr,

DOA => open,

DOB => fifoout(7 downto 0),

DOPA => open,

DOPB => fifoout(8 downto 8)

);

fifocnt: process(clk)

begin

if(clk'event and clk='1') then

if(reset='1') then

fifowraddr'0');

fifordaddr'0');

else

if(fifowren='1') then

fifowraddr

Reply to
Brad Smallridge

ElectronDepot website is not affiliated with any of the manufacturers or service providers discussed here. All logos and trade names are the property of their respective owners.