The principles of synchronous digital design state that we must have a clock, which will nicely mark the rhythm of the different signals traversing our device. We can think of this clock as a sort of orchestra director, which will make sure that everyone does its job exactly when it is required - not before, nor after.
However, complex digital designs will often have more than one clock domain. When this happens, it is like having a whole new orchestra, playing side by side to the old one. If we keep them away from each other, they will both play independently, each at its own pace - but what happens when we need to make them play together? Which director will the different instruments follow? What happens when one orchestra needs to “borrow” a player from the other one in the middle of the concert? This is the problem we face when dealing with clock domain crossings, or CDCs.
Timing rules for a flip-flop (FF) dictate that, for a signal to be correctly sampled, it must be valid in a certain time window centered in the rising edge of the operating clock.
The time window is defined by the setup (ts) and hold (th) times. If we can guarantee that the FF input signal (D) can remain stable both before (setup) and after (hold) the clock edge, then the signal will be captured and propagated to the Q pin, after some propagation time clk-to-q time (tp).
For signals coming from a different clock domain (and also from no clock domain at all, like some external signals), the destination clock domain is unknown and, therefore, the setup and hold constraints are not guaranteed to be met.
The following example shows an extreme case of what can happen when a signal is not properly sampled. Undetermined effects such as ringing on the output “q” are prone to happen, since the output of the FF (sync1) is not guaranteed to be stable when the input setup and hold constraints are not met.
These types of problems can be a real headache:
And the list goes on! The problems can have even a bigger impact if we consider data buses (several bits transferred between the clock domains), or clocks with related frequencies, whose CDCs are sometimes assumed to be “safe” when they are not.
Proper CDC handling is a very important skill for any digital designer starting to work on a project. And sadly, there isn't a one-size-fits-all solution - different factors that need to be accounted for will influence the choice of CDC technique.
Some of these factors are:
Therefore, designers must be really aware of what’s going on if they are to achieve a proper CDC.
Let’s start with some basic examples.
Basic assumptions for this technique:
This is one of the “classical” synchronization techniques, and probably the first one that we learn when we start to dip our toes in the CDC world.
The main concept was already presented above - the idea is to avoid any ringing or transient effects from being propagated to the rest of our design. For this, we add a second FF right after the one that captures the asynchronous signal.
While the first FF output may have a temporary undetermined behavior, this won’t trigger an update of the second FF, which will only update its output once the signal has stabilized on the first FF:
In this way, no undesired signal effects are propagated to the rest of the logic synchronous to clk2.
Basic assumptions:
Very often, we use pulses to signal that an event has happened - for example, the processing of a signal has been completed, an error has been detected, or a time counter has expired.
Let’s first analyze what would happen if we tried to use a 2 FF synchronizer for a single clock pulse. Since the phase between the clocks is unknown, for a single-cycle pulse it is likely that we will miss the destination clock edge at some point, resulting in a setup violation in this clock domain. Therefore, the source signal will be lost, and no one will know about it…
The key point when synchronizing a single-cycle pulse is that the information lies in the rising edge of the pulse - and this is what we can take advantage of when synchronizing pulses.
This scheme can be used to synchronize a single-cycle pulse originating from clk1, generating a single-cycle pulse in clk2. We can see that, in the middle, we’re using the well-known 2 FF synchronizer, but with the addition of:
We’ve presented the basics of CDCs, but certainly there is a lot more to learn. In our next blog entries we will continue building with these blocks and introduce more techniques and code samples. See you next time!
Jose Quinteros del Castillo
Senior FPGA Design Engineer at Emtech S.A
Any Comments or questions, please feel free to contact us: info@emtech.com.ar