cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 
Highlighted
14,711 Views
Registered: ‎01-22-2015

Multiple Clocks Entering FPGA

Jump to solution

In an ideal world, we would use only one clock for our FPGA-based logic designs.  The timing analysis done by Vivado can easily handle the one-clock design.  However, the one-clock design is just a dream and we live in a multiple-clock world.

 

It the multiple-clock world, it is best if you bring one master-clock into the FPGA, immediately feed it to a clock module (MMCM), and setup the MMCM to generate (from the master-clock) all the other clocks that you need in your design.  During setup of the MMCM (from Xilinx IP catalog), the necessary timing constraints for all the clocks will be automatically placed in the appropriate XDC-file.  Timing analysis done by Vivado can easily handle this type of multiple-clock design.

 

Now my problem.  I've inherited an old design where two synchronous clocks enter the FPGA.  I see from AR#13752 that the TIMESPEC timing constraint is needed to specify the frequency of each clock and the phase relationship between the two clocks.  Measuring the phase relationship between the two outputs of my external clock-generator is straightforward.  However, I suspect that Vivado wants to know the phase relationship between the clocks as referenced to some point inside the FPGA.

 

So, my questions are:

1) How do I measure and specify an accurate phase relationship between two synchronous clocks that enter the FPGA?

2) For Vivado, has the TIMESPEC constraint been replaced by the "create_clock" constraint?

1 Solution

Accepted Solutions
Highlighted
Guide
Guide
25,159 Views
Registered: ‎01-23-2009

If they are mesochronous then simply declare each clock as it should be

 

create_clock -name clkA -period 2.777 [get_clocks clkA]

create_clock -name clkB -period 8.333 [get_clocks clkB]

 

The clocks derived from the MMCM will take care of themselves.

 

The tools will treat these clocks as related and synchronous - if you try and do a synchronous clock crossing between them the will not fail timing! In spite of this, you must put a mesochronous clock domain crossing circuit on any path between them. When you put in the CDC, write appropriate XDC constraints for the CDC

 

set_max_delay -from [get_cells <source_ff>] -to [get_cells <dest_ff>] -datapath_only 2.777; # Period of faster clock

 

Make sure your metastability resolution flip-flops have the ASYNC_REG property set on them.

 

Use report_clock_interaction to be sure you have exceptions on all clock crossing paths, and use report_cdc to make sure that the tool recognizes all the CDCs and that the ASYNC_REG is properly set.

 

Avrum

View solution in original post

8 Replies
Highlighted
Guide
Guide
14,695 Views
Registered: ‎01-23-2009

First (just a correction) - when a primary clock reaches an MMCM, the generated clocks are automatically generated by the Vivado static timing engine - they do not come from the XDC file. This is a pretty important distinction - if (for example) you change the clock on the input clock pin (by putting a create_clock on the input clock port), the clocks coming out of the MMCM will automatically change based on the multipliers and dividers of the MMCM.

 

But, to your question...

 

The first question is "are these clocks related". If the two clocks entering the FPGA come from the same clock source (say two ouptuts of the same PLL or oscillator on the board), then they are related. If they come from two different sources, then they are unrelated.

 

If they are unrelated, then there is no meaningful phase measurement between the two. Even if they are the same frequency, the phase will vary continually. This means that you cannot do any kind of synchronous clock crossing between them, and you will need a clock domain crossing (CDC) circuit. When you use a CDC, you need an exception in Vivado to disable the normal synchronous checks on the paths.

 

Even if they come from the same source but through two different paths, it is necessary to understand if the variation on the paths is "too big" for synchronous clock crossing. If your clock is 250MHz and one input comes directly from the oscillator, but the other one goes through a device that forwards it with a propagation delay of 3ns to 8ns, then there is no meaninful phase difference between them, and they need to be treated as asynchronous (again, with a CDC and an exception).

 

However, if they are related and phase aligned with a fixed offset, then there are two ways within Vivado to specify them. Lets say they are 10ns clocks with a 2ns phase offset. One way is through the waveform

 

create_clock -name clkA -period 10 [get_ports clkA]

create_clock -name clkB -period 10 -waveform {2 7} [get_ports clkB]

 

This indicates that the rising edge of clkA is at 0ns (the default), but clkB is at 2ns.

 

Another option is with clock latency

 

create_clock -name clkA -period 10 [get_ports clkA]

create_clock -name clkB -period 10 [get_ports clkB]

 

set_clock_latency -source 2 [get_ports clkB]

 

This has the advantage that you can do variation on the latency using the -min and -max options of the set_clock_latency.

 

NOTE: These are very different from the static timing analysis point of view. It has to do with how setup and hold checks are done. If you have an input that is launched on clkA (from a set_input_delay) and captured on clkB (internally), the first mechanism will assume the data launched at time 0 will be captued on the edge of clkB at 2ns. The second mechanism, though will assume that data launched at time 0, will be captured at time 12; the of clkB after clkA at 0ns is clkB at 10ns, which is propagated by 2ns to be at 12ns.

 

Avrum

Tags (1)
Highlighted
14,658 Views
Registered: ‎01-22-2015

If the clock input to the MMCM changes, then you need to reconfigure the MMCM.  -got it, thanks!

 

Jitter of the phase difference between two related clocks essentially makes them unrelated (asynchronous) -got it, thanks!

 

I see you are using "create_clock" instead of "TIMESPEC".  So, I guess that answers my second question. Thanks!

 

I am still unsure about the answer to my first question.  I have revised this question to be: "How does one measure the fixed-phase-offset (assuming one exists) between two related clock inputs to the FPGA?".  -or, said another way, "Where did you get the 2ns offset for your "create_clock" constraints?".  

 

Can I simply use at dual-channel oscilloscope and measure this phase offset directly at the pins where the clocks enter the FPGA?  -might be kinda tricky on a BGA package.

 

Mark

Highlighted
Guide
Guide
14,636 Views
Registered: ‎01-23-2009

If the clock input to the MMCM changes, then you need to reconfigure the MMCM.  -got it, thanks!

 

That is true from the hardware point of view, but wasn't my point. The generated clocks on the outputs of the MMCM are automatically derived by the timing engine at the time the constraint on the input is read from the XDC - there is only one create_clock, which propagates to the input of the MMCM; all the other clocks are automatically derived.

 

Jitter of the phase difference between two related clocks essentially makes them unrelated (asynchronous) -got it, thanks!

 

Jitter and phase difference are different things. Two clocks are related if there is a one to one correspondance between their edges - for every edge in clkA clock there is exactly one edge of clkB, and the difference between them stays in a specific range (phase wander). Two 100MHz clocks from different oscillators won't have this relationship - one of them will always be slightly faster than the other, resulting in the phase changing continuously, and there no longer being a 1-1 relationship between the edges.

 

More precicesly, there needs to be a N:M relationship between two related clocks; you can have a 100MHz and a 66MHz clock that are related if (say) they are both derived from the same 200MHz source clock (/2 and /3). These would have a 3:2 relationship.

 

I see you are using "create_clock" instead of "TIMESPEC".  So, I guess that answers my second question. Thanks!

 

I am confused by what tool you are using. TIMESPEC is a construct from UCF, which is used in ISE - there are no TIMESPECs in Vivado.

 

I am still unsure about the answer to my first question.  I have revised this question to be: "How does one measure the fixed-phase-offset (assuming one exists) between two related clock inputs to the FPGA?".  -or, said another way, "Where did you get the 2ns offset for your "create_clock" constraints?".  

 

Generally you don't. Measured phase difference is irrelevant - if the clocks have a relationship, they need to be a provable relationship across PVT; i.e. one goes through a buffer that is spec'ed as having a 1-2ns delay, or the two come out of a PLL with a guaranteed 90 degree phase shift, etc...

 

Measuring them at a particular FPGA pin merely tells you the relationship for THIS board at THIS temperature and THIS voltage, which really doesn't give you anything useful.

 

Generally, if you don't know what the relationship is based on system construction and specifications, you have to treat them as unrelated.

 

Avrum

Highlighted
14,626 Views
Registered: ‎01-22-2015

Avrum,

 

Thanks for clarification on many points.  I am using Vivado.

 

I feel some revelations coming....

 

Please comment on the following:

1) It is possible to have a clock generator external to the FPGA that produces two related(synchronous) high-speed clocks.  However, the relationship between the clocks is likely to be uncertain after routing these clocks through thru buffers, cables, and circuit board into the FPGA.  Hence, in your design, it is probably best to always assume that the two external clocks are unrelated (asynchronous).

 

2) If you have two different clocks in your design and there is interaction between the two clock domains, then you need clock domain crossing (CDC) circuits.  If the two clocks are synchronous then sometimes you can attempt a "synchronous CDC".  However, it seems that this is rarely done.  Instead, one mostly uses a CDC-circuit that assumes the clocks are asynchronous.

 

3) Popular CDC-circuits (eg. handshaking) are inherently asynchronous (ie. they assume the clocks in the two domains are asynchronous).

 

It seems that we can almost never make use of the fact that two clocks are synchronous.  Right?

 

Highlighted
Guide
Guide
14,622 Views
Registered: ‎01-23-2009

1) It is possible to have a clock generator external to the FPGA that produces two related(synchronous) high-speed clocks.  However, the relationship between the clocks is likely to be uncertain after routing these clocks through thru buffers, cables, and circuit board into the FPGA.  Hence, in your design, it is probably best to always assume that the two external clocks are unrelated (asynchronous).

 

Kind of yes. These two clocks entering the FPGA are technically "mesochronous" - they have the same frequency, they have the "one to one" edge relationship, but their phase wander is greater than a period. To cross between these you still need a CDC, but it can be a special one for mesochronous clocks, which has fewer restrictions than true asynchronous clocks.

 

But from the static timing point of view, you cannot define a phase relationship between these two clocks.

 

2) If you have two different clocks in your design and there is interaction between the two clock domains, then you need clock domain crossing (CDC) circuits.  If the two clocks are synchronous then sometimes you can attempt a "synchronous CDC".  However, it seems that this is rarely done.  Instead, one mostly uses a CDC-circuit that assumes the clocks are asynchronous.

 

This is most often true. It is rare to have two truly synchronous clocks (with a known phase relationship) enter an FPGA. It does happen sometimes (rarely), so there must be a mechanism to constrain them, but it is uncommon.

 

 

3) Popular CDC-circuits (eg. handshaking) are inherently asynchronous (ie. they assume the clocks in the two domains are asynchronous).

 

Again, there are some specialized CDC circuits for mesochronous clocks, but generally this is true.

 

It seems that we can almost never make use of the fact that two clocks are synchronous.  Right?

 

When we are talking about two external clocks, this is generally true.

 

However, with internal clocks, we use the synchronous relationship all the time. If the same MMCM generates two clocks, where one is 2x the period of the other, we do synchronous clock crossing between them (easily and normally). If the MMCM generates two clocks that are 90 degrees out of phase - again, we can cross between them easily (as long as the frequency isn't rediculously high).

 

Avrum

Tags (1)
Highlighted
14,594 Views
Registered: ‎01-22-2015

Avrum,

 

-again thanks!

 

I now understand that my external clocks should be classified as mesochronous - and that special mesochronous CDC circuits are available.  For the record, my clocks are derived from the same master clock but their frequencies are different (periods for the clocks are 2.777ns and 8.333ns).

 

Currently, each of my clocks enters the FPGA and is immediately buffered by an MMCM.   What constraints should I manually place in the XDC file for these mesochronous clocks?  I suspect your recommendation for these constraints has changed from those found in your first reply to my post.

Highlighted
Guide
Guide
25,160 Views
Registered: ‎01-23-2009

If they are mesochronous then simply declare each clock as it should be

 

create_clock -name clkA -period 2.777 [get_clocks clkA]

create_clock -name clkB -period 8.333 [get_clocks clkB]

 

The clocks derived from the MMCM will take care of themselves.

 

The tools will treat these clocks as related and synchronous - if you try and do a synchronous clock crossing between them the will not fail timing! In spite of this, you must put a mesochronous clock domain crossing circuit on any path between them. When you put in the CDC, write appropriate XDC constraints for the CDC

 

set_max_delay -from [get_cells <source_ff>] -to [get_cells <dest_ff>] -datapath_only 2.777; # Period of faster clock

 

Make sure your metastability resolution flip-flops have the ASYNC_REG property set on them.

 

Use report_clock_interaction to be sure you have exceptions on all clock crossing paths, and use report_cdc to make sure that the tool recognizes all the CDCs and that the ASYNC_REG is properly set.

 

Avrum

View solution in original post

Highlighted
14,580 Views
Registered: ‎01-22-2015

Avrum,

 

Thanks lots for solving this post and for your many contributions to the forum.

-enjoy your Christmas pudding tomorrow.

 

Mark

0 Kudos