Xilinx FIFO
CASTalk.com Forum Index CASTalk.com
Discussion of DSP, FPGA, storage and embedded system.
 
 FAQFAQ   MemberlistMemberlist     RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 
 
Google
 
Web castalk.com
Xilinx FIFO

 
Post new topic   Reply to topic    CASTalk.com Forum Index -> FPGA
Author Message
Brad Smallridge
Guest





Posted: Thu Dec 16, 2004 12:39 am    Post subject: Xilinx FIFO Reply with quote

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
Back to top
Peter
Guest





Posted: Thu Dec 16, 2004 2:51 am    Post subject: Re: Xilinx FIFO Reply with quote

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
Back to top
Brad Smallridge
Guest





Posted: Thu Dec 16, 2004 4:15 am    Post subject: Re: Xilinx FIFO Reply with quote

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
Back to top
Peter
Guest





Posted: Thu Dec 16, 2004 4:43 am    Post subject: Re: Xilinx FIFO Reply with quote

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
Back to top
Symon
Guest





Posted: Thu Dec 16, 2004 2:58 pm    Post subject: Re: Xilinx FIFO Reply with quote

I just read the V4 user guide, UG070. It seems the really tricky bit is
making sure the FULL signal goes high when the FIFO is full. Not one write
clock cycle later. ;-)
Cheers, Syms.
"Peter" <peter@xilinx.com> wrote in message
news:1103155097.582753.217240@c13g2000cwb.googlegroups.com...

Quote:
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
Back to top
Peter
Guest





Posted: Fri Dec 17, 2004 10:34 am    Post subject: Re: Xilinx FIFO Reply with quote

Symon wrote:
Quote:
I just read the V4 user guide, UG070. It seems the really tricky bit
is
making sure the FULL signal goes high when the FIFO is full. Not one
write
clock cycle later. ;-)
Cheers, Syms.

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)
Back to top
Brad Smallridge
Guest





Posted: Tue Dec 21, 2004 2:45 am    Post subject: Re: Xilinx FIFO Reply with quote

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.

Quote:
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

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<=(others=>'0');

fifordaddr<=(others=>'0');

else

if(fifowren='1') then

fifowraddr<=fifowraddr+1;

end if;

if(fiforden='1') then

fifordaddr<=fifordaddr+1;

end if;

end if;

end if;

end process;

end Behavioral;
Back to top
 
Post new topic   Reply to topic    CASTalk.com Forum Index -> FPGA All times are GMT
Page 1 of 1

 
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum




VoIP Electronics Powered by phpBB