cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 
ADGio
Visitor
Visitor
1,473 Views
Registered: ‎07-01-2020

dual clock FIFO and CDC timing constraint

Jump to solution

Hi, 

I have the following question.

I instantiated a Xilinx Axi4 stream FIFO core in dual clock mode.

The write clock (CLK_A) and read clocks (CLK_B) are indipendent, because they are generated by two different clocks generators, whose inputs are external indipendents clocks.

Is it correct in timing constraint file to create two different clockgroups, one for CLK_A and other for CLK_B?

Does the FIFO core manage it automatically?

Am I potencially "masking" some possible timing errors, assiming they are not related?

 

I know it's a newbie question, but I'm having some problems in understanding the concepts.

Thank you in advance

regards

0 Kudos
1 Solution

Accepted Solutions
avrumw
Expert
Expert
1,444 Views
Registered: ‎01-23-2009

Does the FIFO core manage it automatically?

Assuming the FIFO is a clock crossing FIFO (I am not familiar with the actual core, but if it has two clocks, then it is), then the Xilinx IP should take care of everything for you. All Xilinx IP come with "scoped constraints" - these constraints are automatically added to the project when the IP is added. For a clock crossing FIFO this should include whatever constraints are required for the clock crossing.

Is it correct in timing constraint file to create two different clockgroups, one for CLK_A and other for CLK_B?

DO NOT DO THIS!

Am I potencially "masking" some possible timing errors, assiming they are not related?

Yes!

First, the clock groups may override the more precise constraints that are used by the scoped IP from the FIFO; clock domain crossing FIFOs can use either the set_max_delay -datapath_only constraint, which is lower priority than the set_clock_groups, or may use the newer set_bus_skew (which is unaffected by the clock groups). 

But even if the FIFO itself will work with the set_clock_groups, this is still potentially dangerous. This command will disable all paths between the two clock. This means that if there are now, or ever will be, other clock domain crossings between these two clocks in the design, they will be disabled. This includes other intentional clock crossings through valid clock domain crossing circuits as well as any erroneous clock domain crossing - accidentally using a clock from one domain in the other domain. This can be very dangerous, since a bad clock crossing like this is unlikely to be detected in RTL simulations, and the set_clock_groups will prevent it from being detected in static timing analysis. The only place you will see this is in FPGA running in the system where it will be really hard to find - you will likely get an intermittent or unpredictable failure, and tracing that back to the bad clock crossing is going to be incredibly difficult...

Avrum

View solution in original post

3 Replies
avrumw
Expert
Expert
1,445 Views
Registered: ‎01-23-2009

Does the FIFO core manage it automatically?

Assuming the FIFO is a clock crossing FIFO (I am not familiar with the actual core, but if it has two clocks, then it is), then the Xilinx IP should take care of everything for you. All Xilinx IP come with "scoped constraints" - these constraints are automatically added to the project when the IP is added. For a clock crossing FIFO this should include whatever constraints are required for the clock crossing.

Is it correct in timing constraint file to create two different clockgroups, one for CLK_A and other for CLK_B?

DO NOT DO THIS!

Am I potencially "masking" some possible timing errors, assiming they are not related?

Yes!

First, the clock groups may override the more precise constraints that are used by the scoped IP from the FIFO; clock domain crossing FIFOs can use either the set_max_delay -datapath_only constraint, which is lower priority than the set_clock_groups, or may use the newer set_bus_skew (which is unaffected by the clock groups). 

But even if the FIFO itself will work with the set_clock_groups, this is still potentially dangerous. This command will disable all paths between the two clock. This means that if there are now, or ever will be, other clock domain crossings between these two clocks in the design, they will be disabled. This includes other intentional clock crossings through valid clock domain crossing circuits as well as any erroneous clock domain crossing - accidentally using a clock from one domain in the other domain. This can be very dangerous, since a bad clock crossing like this is unlikely to be detected in RTL simulations, and the set_clock_groups will prevent it from being detected in static timing analysis. The only place you will see this is in FPGA running in the system where it will be really hard to find - you will likely get an intermittent or unpredictable failure, and tracing that back to the bad clock crossing is going to be incredibly difficult...

Avrum

View solution in original post

ADGio
Visitor
Visitor
1,367 Views
Registered: ‎07-01-2020

Thank you very much, Avrum.

 

So I have another question, to clear the basic idea of clockgroup.

If I have to consider the clocks are always related, when they interact in a dual clock FIFO or in a whatever CDC element,  when should I use the clockgroup?

Only in the case the logic working with the two clocks is completely separated, i.e. when coexist two different designs in the same FPGA without interact between them?

 

A second question.

As I said, clk_A and clk_B comes from two different external sources. The problem is that I don't have any information about the relation between them (for example, I don't know the phase difference).

If I generate clk_A and clk_B from a common source, (for example by a MMCM, or a PLL), would the system work better? As the generation of them is managed by a Vivado core, I imagine it will have control over them, and the timing analisys would be better.

 

Thank you very much,

regards

 

0 Kudos
avrumw
Expert
Expert
1,344 Views
Registered: ‎01-23-2009

Only in the case the logic working with the two clocks is completely separated, i.e. when coexist two different designs in the same FPGA without interact between them?

So, no, you don't need clock groups here. If there are no paths between the two domains, then a set_clock_groups command wouldn't do anything. Yes, it would be harmless, but also pointless.

If I have to consider the clocks are always related, when they interact in a dual clock FIFO or in a whatever CDC element, when should I use the clockgroup?

In my opinion, basically never. This is pretty much the crux of the matter. If there are paths between two asynchronous domains, then there need to be clock domain crossing circuits (CDCCs). If there are CDCCs, then these CDCCs need exceptions as part of the CDCC - a CDCC isn't complete without the correct exceptions. Only in a few CDCCs is the set_false_path exception the correct one - in most, that is too loose and leaves the potential for the CDCC to fail; a set_max_delay -datapath_only is more often the correct exception. The set_clock_groups command is effectively a set_false_path between the clocks in both directions, which, as we discussed, overrides all other constraints (with the exception of the new set_bus_skew command).

So the only time you can use a set_clock_groups command is when all the CDCCs between the domains are correctly constrained with false path commands. But even here, this is dangerous, since if you ever add a new CDCC that isn't constrained correctly by this, then the new CDCC will have the wrong exception. So even in this case (all CDCCs can tolerate a set_false_path) it is still safer to put the set_false_path constraints on the CDCC, rather than between the clocks.

Which brings me back to my answer as to when to use set_clock_groups... Never!

As I said, clk_A and clk_B comes from two different external sources. The problem is that I don't have any information about the relation between them (for example, I don't know the phase difference).

These clocks are asynchronous (or maybe mesochronous depending on how they are generated). For these you need a CDCC.

If I generate clk_A and clk_B from a common source, (for example by a MMCM, or a PLL), would the system work better? As the generation of them is managed by a Vivado core, I imagine it will have control over them, and the timing analisys would be better.

If two clocks come from the same MMCM/PLL (or even two different ones driven by the same clock source) then the resulting clocks are not asynchronous. Since they are synchronous domains you don't need a CDCC; assuming the clock resources are reasonably well balanced (they use the same type of clocking resource, and in UltraScale/UltraScale+/Versal are in the same CLOCK_DELAY_GROUP), then you can pass data synchronously between these domains. Vivado will automatically create the generated clocks on the MMCM/PLL output; all you need to do is constrain the input clock and the tools will correctly time these synchronous paths. No exceptions are required.

Avrum

0 Kudos