07-02-2019 03:40 AM
I am getting data from two different sources with same clock but with different phase .so,for bringing them to the same clock domain ,I am writing the data of the two sources to their respective fifo's with their respective clocks but reading the data with only one clock (clock of any one source).Is this the correct way to handle "mesochronous" clocks?
07-02-2019 04:16 AM
08-20-2019 08:21 AM
I am writing the data of the two sources to their respective fifo's with their respective clocks but reading the data with only one clock (clock of any one source).Is this the correct way to handle "mesochronous" clocks?
Yes. If the phase difference between the two clocks is unknown "enough" so that synchronous crossing is impossible, then this is a valid solution. If possible, you can always use the clock from one of the two sources as the "common" clock, and just clock cross the other source into that domain (thus having only one clock crossing FIFO rather than two).
What you need to budget for is the maximum "phase wander" possible - what is the largest possible difference in delay between the source clock and the destination clock. You need to have a FIFO that is at least twice that depth plus an additional one depth for the uncertainty of the clock crossing FIFO (the metastability cycle). So, in general, unless the phase difference is very tight, you need a minimum of a 5 entry FIFO.
There are a couple of simplifications that you can do. The first is to use a distributed RAM based FIFO, rather than a block RAM based FIFO. The distributed RAMs can do 32x2 dual port FIFOs in two LUTs (so they can do 4 bits per CLB in a 7 series device). A depth of 32 is more than enough for a mesochronous FIFO. The disadvantage is that the FIFO18 primitive (block RAM) has all the address pointer, empty/full generation and clock crossing built in, whereas it has to be done in fabric logic for the distributed RAM FIFO.
But, you don't need empty/full - all you need is a simple "go" mechanism. Assuming data is arriving every clock (which is the case for most of these situations) then you only need to wait for "some time" after the first word arrives on the write side, before enabling your read side. So for example, if you wait 6 clocks after your first word arrives, then you will have 7-8 words in the FIFO (due to the metastability circuit on the "go" signal) before the read side starts. Once it does, you will have one read and one write for every clock, which will leave the fill level "stable" - except for the phase wander. So if your phase wander is (say) +/- 2 clocks, then the fill level will absorb this, varying between 5 and 10 entries; that has lots of margin in a 32 entry FIFO. It also has the advantage of guaranteeing that after the "go" signal on the read side occurs, you will get one new data for every clock without gaps - this means that you don't need to carry a "valid" signal with the data on the read side (and things like DSP processing can be done without the fear of missing samples).