Forum Discussion
Hi Dima,
The approach I ended up taking was to use an IOPLL in its "direct" compensation mode, and then deal with the non-zero skew at the clock domain crossings.
With the IOPLL in direct compensation mode, you do end up with some positive skew from the upstream clock to the downstream clock. But this skew is predictable/repeatable, doesn't vary significantly from build to build, and is on the order of a couple of nanoseconds. So, knowing the approximate skew relationship between the clocks, you can still deal with it statically using fully synchronous design techniques.
As to handling the domain crossings, the following is a relatively simple approach that can meet timing up to moderately high clock frequencies (for an Arria 10 in -1 speed grade, say ~350 MHz):
Crossing from the downstream clock domain to the upstream clock domain is the simpler of the two crossings. You can simply go direct reg-to-reg. Setup is the limiting factor here, and the time available for the reg-to-reg path is essentially the entire clock period minus the clock skew (and of course minus the clock-to-out of the source reg and the setup time requirement of the destination reg). Even after losing those couple of nanoseconds to clock skew, at the clock frequencies we're talking about you should still have ample setup slack on a direct reg-to-reg path.
Crossing from the upstream clock domain to the downstream clock domain is the more tricky crossing, with hold being the limiting factor. If you simply go direct reg-to-reg, you will probably end up with unfixable hold violations due to the clock skew. My solution to this was to go reg-to-reg-to-reg, where the first register stage is on the rising edge of the upstream clock, the second is on the falling edge of the downstream clock, and the third is on the rising edge of the downstream clock. This ensures that you have no less than half a clock period of time available for each reg-to-reg path, assuming a 50% duty cycle on the downstream clock. Or more precisely, you have half a clock period plus the clock skew for the first reg-to-reg path, and exactly half a clock period for the second reg-to-reg path. This should ensure ample hold slack, though we are now setup limited again.
If you're pushing for a high clock frequency where the half-period reg-to-reg path becomes the critical path for setup, you can further balance the time available between the register stages by modifying the duty cycle of the downstream clock, which you can naturally do using the configuration of the IOPLL. You have a total of one clock period plus the skew to go reg-to-reg-to-reg, so nominally you'd want the falling edge used for the middle register stage right in the middle of that, which you can get closer to by adjusting the duty cycle of the downstream clock. But again, I'd only bother with this optimization if this crossing becomes your critical path. Otherwise just keep it simple with a 50% duty cycle.
For applications where the attainable timing performance is adequate, the above approach has the advantages of being relatively simple, fully synchronous, having no timing exceptions, requiring no additional clock phases, and requiring no special timing constraints.
And if you need to push the performance even higher, you'll have to get even more creative, and I have... but I won't go into that here.
Hope this helps, and let me know if you have any questions.
-Roee
roee@porcupinetech.com
Thank you for the detailed answer!
I appreciate your insight. I need to cross signals from the upstream to the downstream clock domain, but the frequency is rather low, and your method looks very promising.
Thanks,
Dima
- roeekalinsky4 years ago
Contributor
You're welcome. Good luck!
-Roee