V4 FIFO16 and SRAM

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

Reply to
Brad Smallridge
Loading thread data ...

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

Reply to
Peter Alfke

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

Reply to
Brad Smallridge

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

Reply to
Sylvain Munaut

Yes, it's done inside, but it still takes a few clock ticks...

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

Reply to
Peter Alfke

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.
Reply to
Hal Murray

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

formatting link

Reply to
Ray Andraka

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.

Reply to
Peter Alfke

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

Reply to
Brad Smallridge

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

Reply to
Brad Smallridge

Thanks, Hal. You might be the only one that understood my question.

I'm not following you. The EMPTY flag is actually working OK. It's the extra cycle of geting the RDEN on that I suspect must be worked on. So I guess, because you mentioned pipeline, and I've been thinking that an extra register needs to be added to the data output, that there is some circuit that will be robust and will handle one input data burst or multiple-input data burst. Right now I can't wrap my head around what that circuit might be. If you can give me any clues I would be most appreciative.

Presently, I am working on driving the RDEN with combinatorial logic, directly from the two EMPTY flags to get it off faster. I think this should work, since both EMPTY flags are synched to the same RDCLK. There seems to be some flickers, though, on the output.

Brad Smallridge Ai Vision

Reply to
Brad Smallridge

Brad, I really do not understand what you are doing with the FIFOs. I was just (poorly) describing the naturally synchronous rising edge of EMPTY, and its artificially re-synchronized trailing edge. That's all in the inards of FIFO16. I know the FIFO16 inside out (and have designed FIFOs over the past 30 years), so I should be able to understand what you do. But I don't. Send me an e-mail or call me at work, and we can get to the bottom of it. Then I can also explain in detail what Ray was referring to. Peter

Reply to
Peter Alfke

Thanks Ray,

I was aware of this issue. However I thought that I was "safe" since I am not using the ALMOSTEMPTY flag, nor should the two FIFO16s ever be in a situation where the ALMOSTEMPTY flag would ever be in transition. It should always be on. My circuit is fairly straightforward, as soon as the EMPTY flag comes on, address information is passed from the FIFO output to the SRAM address lines. There are two FIFOs competing for the address lines with one FIFO having priority for the situation when both EMPTY flags come on at the same time. The data is spread out so presently I would never expect to see more than one data in either FIFO at any time.

Since the ALMOSTEMPTY flag is always on, I was hoping that it's metastable effect on the EMPTY flag was circumvented. I guess that's a question for Xilinx to answer.

And the coregen fifo is OK?

Brad Smallridge Ai Vision

Reply to
Brad Smallridge

Brad If you program the ALMOST EMPTY flag to a high enough offset above EMPTY, such that ALMOST EMPTY never (never!) gets deactivated, then the FIFO16 will always operate perfectly, and you can ignore all work-arounds. Absolutely, no question...

The problem with the ALMOST flags has nothing to do with metastability, (we understand that pretty well, and would not be fooled by that), but is caused by simultaneous read and write clock edges. It's a simple logic error, hidden and covered up in a piece of "hard logic".

Regarding EMPTY, you must understand that it is obviously started by the read clock, obviously terminated by the write clock, but then internally re-synchronized to the read clock. That's where the ambiguities come from. Peter

Reply to
Peter Alfke

Be careful with that. I thought I was safe too, but I got tripped up by the flag issue. I never looked at almost empty, but I don't think my design should have reached it (I found this problem before Xilinx did).

The coregen fifo is fine. It is designed by a separate group, and its design is mature.

Reply to
Ray Andraka

Ray, with all due respect: Yes, this problem was first found by a couple of customers, and you were probably the first. But only we at Xilinx know the innards of the control logic implementation, and I was the one that clearly traced the problem to the inputs of two internal flip-flops. Having analyzed it, I can assure you that there is nothing mysterious about the misbehavior. It happens very rarely, but always for an identifyable logic reason. It has nothing to do with metastability, it is totally deterministic. The description may sound convoluted, but the behavior is clear. It has to do with the ALMOST EMPTY flag potentially getting and staying inverted. And since ALMOST EMPTY is used as a necessary condition for decoding EMPTY, the EMPTY flag also gets impacted, if, AND ONLY IF, there is a simultaneous read/write operation on the second clock tick AFTER REACHING OR LEAVING THE THRESHOLD OF "ALMOST EMPTY". That's why the failure occurs so rarely in an asynchronous FIFO use. If ALMOST EMPTY stays active,( i.e. if its deactivating threshold is set high enough to never be reached) there will never ever be an erroneous EMPTY flag. We have analyzed this, and then also simulated and tested it, and provoked it. I know all the gory details. That's why I gave Brad this strong assurance that in his design he can 100% rely on the EMPTY flag going active when it should, and going inactive soon after something has been written into the FIFO16. I have had sleepless nights over this. Brad does not have to... Peter Alfke, from home

Reply to
Peter Alfke

????

If you set for example

rden

Reply to
Sylvain Munaut

Peter,

I didn't go back and revisit the design afterwards. At the time I was debugging this, we didn't know that the issue was with the almost empty flag, and since I was not using it I didn't look at it at all. I don't think the FIFO should have ever gotten full enough in the design to cause the almost empty to change state, but it is possible either it was getting filled up more than I thought during the start-up sequence due to the test fixture, or that the almost empty depth attribute was still at the default of 4. Since I didn't have the benefit of Xilinx's description of the problem, I didn't know to look at the almost empty and didn't consider it at all in the debug effort (my design doesn't use it).

Brad, make sure you set the almost empty threshold high enough that you will *never* hit it if you use it as Peter suggests.

Reply to
Ray Andraka

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.