FPGARelated.com
Forums

V4 FIFO16 and SRAM

Started by Brad Smallridge February 24, 2006
Hello Group,

I could use some advice on hooking up asynchonous FIFO16s to an SRAM 
interface.  Specifically I have two FIFOs on different clocks feeding the 
address lines of the SRAM, on a third clock. A control circuit looks at the 
two EMPTY flags to determine which fifo output should be muxed onto the 
address lines.

Starting with empty FIFOs and looking at the result of writing an address 
into one of the fifo I get the events as follows:

1) Write address into fifo
2) After a few RDCLKs the EMPTY flag will sync and drop
3) At the next RDCLK, the logic sets an enable FLAG  indicating which fifo 
it picked, and that FLAG signal goes to the fifo RD_EN
4) At the next RDCLK, the address is muxed to the address and the SRAM WR is 
made active. Since the RD_EN signal was on at last clock, the EMPTY flag 
goes high now.
5) Two clocks RDCLK later data is muxed out to the DATA bus. This is a No 
Bus Delay Latency SRAM.

My issue is that the EMPTY flag is active low for two clock cycles and this 
is ambiguous.  Does it mean that there are two data in the FIFO or just one? 
I have been thinking about running the FLAG  as combinatorial logic without 
a clock since both EMPTY signals are synched to the RDCLK.  But this doesn't 
seem right. Any advice would be appreciated.

Thanks,

Brad Smallridge
Ai Vision




 


Brad, synchronous FIFO controllers are trivial, just a state machine
that manipulates the addressing of a dual-ported RAM.
Asynchronous FIFOs are far more complex, especially when they are also
supposed to be clocked at, say, 500 MHz.
The difficulty is "only" with the flags. EMPTY goes active as a result
of the read clock. The rising edge of EMPTY is thus a synchronous
signal in the clock domain of interest, with <1 ns delay. But the
trailing (falling) edge is caused by a write operation, thus is
synchronous with the wrong clock. This requires  a few synchronization
flip-flops, if you want to avoid metastable problems. This delays the
trailing edge of EMPTY by a few read clock ticks.

I am describing a general-purpose controller. For special restricted
applications, you can design all sorts of clever circuits that might
avoid this extra delay...
Peter Alfke, Xilinx Applications (from home)

Hi Peter,

Well I am in the asynchronous world, not at 500 MHz. I am using the Virtex 4 
SX35 and I read that the falling edge of EMPTY is already being synched to 
the RDCLK by the primitive FIFO16. Is that not true?

My issue is that in my simulations I see the EMPTY go on for two RDCLKs, 
whereas I have only written one datum into the FIFO16.

Brad

 


Brad Smallridge wrote:
> Hi Peter, > > Well I am in the asynchronous world, not at 500 MHz. I am using the Virtex 4 > SX35 and I read that the falling edge of EMPTY is already being synched to > the RDCLK by the primitive FIFO16. Is that not true? > > My issue is that in my simulations I see the EMPTY go on for two RDCLKs, > whereas I have only written one datum into the FIFO16.
I don't get your problem ... The sequence you decribe on your first pos looks ok, the empty flag will stay low for two clocks because you only activate RDEN on the second clock cycle : 1 2 3 | | | _ _ _ _ _ _ _ _ rdclk / \_/ \_/ \_/ \_/ \_/ \_/ \_/ _____ ________________ empty \_______/ ___ rden _________/ \________________ 1 -> Empty goes low because some write has been done a few cycles before 2 -> Some registred control logic sample empty at 0 and raise rden for 1 cycle 3 -> rden is sampled by the FIFO16 logic and since there as no data left (only 1 written), it raises the empty flag. empty was low for two clock because the reading logic didn't pull the data out of the fifo directly but instead waited for 1 cycle to register it's input (or output). Sylvain
Brad, the rising edge of EMPTY is very important, since you must stop
any reading once EMPTY goes High.
The falling edge of EMPTY pays a price for coming from the other clock
domain. It has internal re-synchronizing flip-flops, which cause a
delay. It was our (my) decision to favor the rising edge and make the
falling edge less precise. In your case that may confuse you.
We designed this FIFO for 500 MHz asynchronous operation...
Peter Alfke, from home.
===============
Brad Smallridge wrote:
> Hi Peter, > > Well I am in the asynchronous world, not at 500 MHz. I am using the Virtex 4 > SX35 and I read that the falling edge of EMPTY is already being synched to > the RDCLK by the primitive FIFO16. Is that not true?
Yes, it's done inside, but it still takes a few clock ticks...
> > My issue is that in my simulations I see the EMPTY go on for two RDCLKs, > whereas I have only written one datum into the FIFO16.
Yes, I expected that, and, depending on the phase between read and write clocks, it might even be three. The horrors of asynchronous clock domains, where you cannot predict whether one clock is even a picosecond before or after the other. Peter
> > Brad
>My issue is that in my simulations I see the EMPTY go on for two RDCLKs, >whereas I have only written one datum into the FIFO16.
That's a reasonably common problem with FIFOs. There is a pipeline delay in deciding to read the FIFO and/or in updating the empty flag after you do the read. You can probably patch your code to ignore the EMPTY flag until it has had time to get the right answer. The disadvantage with that is that you can only read at half speed. (Or slower if your pipeline is longer.) I know two tricks to get around the half-speed problem. One is to use an almost-empty flag. If the FIFO is not "almost" empty then you know it won't go empty right after you read it so you can plan to read a second work and know there will be data ready. The other approach works for things like packets when you know the input side is faster than the output. Add another data bit to the FIFO (make it wider) and put an End-of-Packet flag in there. This works when the data path is faster than the empty-flag path. -- The suespammers.org mail server is located in California. So are all my other mailboxes. Please do not send unsolicited bulk e-mail or unsolicited commercial e-mail to my suespammers.org address or any of my other addresses. These are my opinions, not necessarily my employer's. I hate spam.
Brad Smallridge wrote:
> Hello Group, > > I could use some advice on hooking up asynchonous FIFO16s to an SRAM > interface. Specifically I have two FIFOs on different clocks feeding the > address lines of the SRAM, on a third clock. A control circuit looks at the > two EMPTY flags to determine which fifo output should be muxed onto the > address lines. > <snipped>
Brad, The Virtex4 FIFO16 flag logic has a design flaw that renders them unreliable for asynch operation. I'm rather surprised in fact that Peter did not mention it in his reply to you. Anyway, the issue is that if the read clock and write clock edges are close together, the flag logic can get corrupted, which then screws up the fifo operation when the fifo gets to the full or empty condition. To use the fifo synchronously, you have to move the read and write edges apart. The easiest way to do that is to use the falling clock for write and the rising clock for read. For async fifos, you cannot guarantee that the edges will never align, therefore for reliable operation, you cannot use the fifo16 asynchronously. You can, however use it synchronously and cascade it with a small async coregen fifo implemented in the fabric so that the net effect is an async fifo. It would be good for you to read Xilinx Answer 22462 at http://www.xilinx.com/xlnx/xil_ans_display.jsp?iLanguageID=1&iCountryID=1&getPagePath=22462
Yes, Ray, you are right.
I was about to follow up with this issue once I am back at work on
Monday.
There is the "Achilles heel" problem that Ray mentioned, and to avoid
it in asynchronous mode takes the work-aound that Ray may have listed.
I have been deeply involved in this, and I am still working on a
simpler work-around.
If you are willing to sacrifice a few percent of top capacity, and are
willing to have the two ALMOST flags at fixed locations
(non-programmable and with some tolerance), which I think are not too
unreasonable sacrifices, the  work-around boils down to less than 3
CLBs, and of course no speed loss.
We decided to not confuse the world (and ourselves) with two very
different fixes. So we published the bigger, no trade-off work-around
first. The smaller one will follow. Anybody interested can send me an
e-mail. This has been a painful experience.  ;-(
Peter Alfke, still at home.

> 1 2 3 > | | | > _ _ _ _ _ _ _ _ > rdclk / \_/ \_/ \_/ \_/ \_/ \_/ \_/ > _____ ________________ > empty \_______/ > ___ > rden _________/ \________________
This diagram is correct except for the fact that if your RDEN logic comes from the EMPTY flag, then RDEN will be two pulses long as well. That could be trouble is you only have one datum. By the way, how do you set up Outlook Express to give Courier fonts? Whenever I get a diagram like this, I have to cut and paste it into Notepad to see it. Thanks, Brad Smallridge Ai Vision
>> My issue is that in my simulations I see the EMPTY go on for two RDCLKs, >> whereas I have only written one datum into the FIFO16.
> Yes, I expected that, and, depending on the phase between read and > write clocks, it might even be three.
How does three happen? As far as I know, the effect I have described depends only on the synchronous rising edge of EMPTY flag, so either you don't understand what I'm trying to relate, or I don't understand some other issue in the FIFO16 EMPTY flag behavior. Brad Smallridge Ai Vision