On Nov 17, 2011, at 11:47 AM, Al Kossow wrote:
On 11/16/11 6:55 PM, Eric Smith wrote:
Note that everything in the FPGA doesn't have
to operate on the same clock. You can have multiple clock domains.
Is there anything higher-level/better for describing an cross-domain signal beyond
specifying that it go through a
dual-rank synchronizer?
Well, dual-clock FIFOs work, too. But they're just regular FIFOs built on a dual-port
RAM with a bunch of synchronizers.
The whole reason to put cross-domain signals is to avoid metastability problems. Similar
problems plague discrete logic as well; I recall that there's a "bug"
(really just a lack of external synchronization) in the shifter of most 6522s that makes
them unreliable if you don't synchronize the input to the receiving clock domain
first. If you just drop a flip-flop in front of it in the 6522's clock domain, the
problem is solved (as long as that doesn't add a troublesome amount of latency). I
seem to recall this caused a number of problems for a certain C64 disk drive...
But yeah, dual (or better) rank flip-flops are your simplest answer. Each rank you add
reduces the probability of a metastable event propagating through; two (especially with
fast logic like we have on FPGAs) is usually enough for most purposes without sending
latency through the roof.
Here's a great exchange on metastability, with some fantastic pictures (also linked
below, but read the first link for context on what you're actually seeing).
http://www.fpga-faq.com/FAQ_Pages/0017_Tell_me_about_metastables.htm
http://www.fpga-faq.com/Images/meta_pic_1.jpg
http://www.fpga-faq.com/Images/meta_pic_2.jpg
http://www.fpga-faq.com/Images/meta_pic_3.jpg
I've been bitten by it several times, largely from totally asynchronous inputs. I had
a 16550 I wrote once where the "CTS delta" interrupt failed to fire about one
time out of a thousand; I had forgotten to synchronize the modem control lines (because
who cares about their state except over the long term, right?) and the first flip flop in
the edge detector would stumble over the metastability; on the next clock, the second
flip-flop would flip on the (now-settled) value and they would both be the same, thus no
edge was detected.
Plus, when you have multiple paths going through your device with different propagation
delays (FPGA or PCB), different flip-flops can catch different values on the same clock
edge because they catch the data at different points in time (often one after it has
flipped, and one before it). You'd think that would be caught by proper tSU/tCO
calculations, but what the metastable effect does is to effectively multiply the tCO by a
non-insignificant number.
So, short answer: double-register all your inputs (unless you KNOW they're
synchronous) to your boards, devices and clock domains. Otherwise you'll end up with
a handful of mysterious inconsistencies that "shouldn't be able to happen".
- Dave