Jump to content
  • 0

FIFO CDC and Gray codes


RedMercury

Question

Hi all,

One of my projects is to make an HDMI output core driven by an AXI stream (rather than act as an AXI memory master).  Since the video output is run by the pixel clock, it is in a different clock domain than the rest of the system.  I understand that to cross the domain correctly I'd need a FIFO, and it seems that most async FIFO designs utilize gray codes to synchronize the read and write pointers, restricting the potential metastability bit error to one.

Extrapolating this out, surely the number of potential bit errors increases when the frequencies are >2:1 (or some other multiple)?

For example, a high frequency sender could write 4 items into the queue, legitimately changing multiple bits of the gray code write pointer.  The receiver could then desynchronize the gray code write pointer and miss some MSB transitions, while some LSBs are updated giving a very incorrect write pointer.

Maybe since the transition frequency of a bit drops off logarithmically with its position, errors in the MSB are much less likely to occur?

Still quite new to FPGAs, so forgive me if I've gotten the wrong end of the stick..

Thanks!

Link to comment
Share on other sites

8 answers to this question

Recommended Posts

Thanks - I found this snippet useful:


 

Quote

 

First question. Noting that a synchronized Gray code that increments twice but is only sampled once will show multi-bit changes in the synchronized value, will this cause multi-bit synchronization problems?

The answer is no. Synchronizing multi-bit changes is only a problem when multiple bits are changing near the rising edge of the synchronizing clock. The fact that a Gray code counter could increment twice (or more) between slower synchronization clock edges means that the first Gray code change will occur well before the rising edge of the slower clock and only the second Gray code transition could change near the rising clock edge. There is no multi-bit synchronization problem with Gray code counters.

 

 

Link to comment
Share on other sites

3 hours ago, RedMercury said:

I understand that to cross the domain correctly I'd need a FIFO

FIFOs are multi-purpose elements. Single clock FIFOs can be used to absorb bursty data rates when the data sink can't keep up. Dual clock FIFOs are typically used for sending data across clock domains. I emphatically encourage you to carefully read the IP documentation where you will find all kinds of disclaimers, primarily with status flags and word counts, for all vendor supplied 2 clock FIFO IP. Clock domain analysis is a tricky business... you'll find this out for yourself with a bit of sleuthing. Hint: those parity bits are useful for sending status across the domain synchronous with the data.

Grey coded counters are very helpful in things like phase modulation applications. They are not a magic band-aid that prevents all problems.

The good news is that video applications are pretty tolerant of occasional random errors.

Link to comment
Share on other sites

7 hours ago, RedMercury said:

Still quite new to FPGAs, so forgive me if I've gotten the wrong end of the stick..

You might be re-inventing the tree.

j/k.  FPGAs have async fifo's as hard IP.  They also have vendor supplied IP generators.  For xilinx, the "primitives guide" has more info.  There is also coregen.  Someone also mentioned there is a new way to create generic fifo's that isn't the very-limited unimacros.

7 hours ago, RedMercury said:

For example, a high frequency sender could write 4 items into the queue, legitimately changing multiple bits of the gray code write pointer.  The receiver could then desynchronize the gray code write pointer and miss some MSB transitions, while some LSBs are updated giving a very incorrect write pointer.

A properly constrained design will ensure that the skew between bits in this bus will be less than one other-clock cycle.  In newer Vivado, there is a constraint for this specifically.  In older versions of Vivado and all of ISE, the bus was simply constrained to arrive to the other clock domain within one other-clock cycle.  This is a little more strict, but is safe.  The constraints guide has more info on what your options are based on tool version.

 

But again, for a first design I would avoid manually creating a dual-clock fifo unless it has some specific use that can't be met using pre-verified options.  As @zygot mentions, there can be some unexpected latency differences for various flags.  The xilinx memory resources guide can give you some information for common use cases.  For coregen'd fifos, the relevant user guide (product guide?) can also be useful.

 

I also suggest creating overflow/underflow error flags and having some way to access them.  These can be useful in simulation and can be useful to determine issues that occur in difficult to simulate cases.

Link to comment
Share on other sites

Using the hard FIFOs isn't as straightforward as you might assume either. There's some initialization work (reset assertion to when write enable can be asserted) involved that is not well documented in the IP manual. My PMOD challenge in the Project Vault provides an example (Testbed.vhd). It was the first time that I had used the Series 7 hard FIFO primitive and struggled to figure out why it wasn't behaving until I paid attention to a simulation message which led to research and finally figuring out how to use the darn thing.

Link to comment
Share on other sites

9 hours ago, Piasa said:

there can be some unexpected latency differences for various flags

I'd word this as the timing behaviour of flags for two clock FIFOs are not predictable depending on how you might want to use them.

Using a clocked signal in one clock domain that has been created in another unrelated clock domain provides the conditions for metastability on a repeatable basis. The effects of metastability is managed not (always) preventable. It is possible to have metastability due to long combinatorial and routing delays as well but this is preventable... and a lot more vexing to identify in working hardware. Metastability is a complex and interesting topic. 

Link to comment
Share on other sites

17 hours ago, D@n said:

You might consider reading the paper I referenced.  It's worth the read.

Yeah I have a small cache of SNUG articles from the past. The author uses the convention asynchronous to apply to 2 clock FIFOs which is not how I generally use the term to apply to logic. But as long as you state up front what you mean it's all good. The article isn't targeted to any particular architecture or technology and I'm not sure how much of it applies to the Xilinx Series 7 devices using Vivado. Still, the basic ideas, from an informational perspective, are good and lays out a number of concepts worth spending time to think about.

Right or wrong, here are my feelings toward grey coded counters. If they are incremented ( counting by 1 ) or decremented (counting by 1 ) then there will only be a change in 1 bit of the count word. That's pretty much it. The author, like most people who've espoused the necessity of grey coding glosses over the details as to how they improve reliability for FPGAs running a particular bitstream. What the grey code absolutely can do is provide a mechanism for detecting multi-bit changes when single bit changes are expected. If you add the logic to do this and don't add the functionality to do something with that detected error than what have you accomplished? A FIFO certainly has pointers (likely counters that count up or count up and down by 1 ) so grey-coded counters are certainly appropriate. Is there a difference between a 16-deep FIFO and a 1 Mword deep FIFO? For sure as you will need quite a few BRAMS to implement the very deep one. There are other coding schemes for particular purposes.

Personally, I'd never try to design my own 2 clock FIFO when I have the flawed but documented Xilinx IP or hard FIFO available. Regardless of how you handle it clock domains present the possibility of metastability.

Now what I might want to do is create a large dual clock 2-port BRAM circular buffer because none of the FPGA vendors offer such a beast. I've played along these lines but wouldn't want to publish anything to date. I could use a well designed circular buffer. It should be easier than a FIFO, I think....

Link to comment
Share on other sites

Archived

This topic is now archived and is closed to further replies.

×
×
  • Create New...