cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 
Highlighted
Participant
Participant
394 Views
Registered: ‎01-19-2020

How to resolve #BUFGCE_DIV is not enough in a clock region error?

Jump to solution

Hi,

 

We are using ZCU104 and Vivado 2019.2.

Our design has 6 BUFGCE_DIV instances.

When implementation, Vivado shows an error:

"Place [30-1222] BUFGCE_DIV capacity exceeded for a clock region."

We don't know why Vivado doesn't put the clock divider to other clock regions.

Is there any suggestion to resolve it?

 

We have tried to assign BUFGCE_DIV manually to different clock regions (use pblock),

however, Vivado fail without any error.

The message is as follows,

------------------------------------------------------------------------

INFO: [Common 17-83] Releasing license: Implementation
62869 Infos, 461 Warnings, 0 Critical Warnings and 0 Errors encountered.
phys_opt_design failed

------------------------------------------------------------------------

 

Thanks.

 

0 Kudos
1 Solution

Accepted Solutions
Highlighted
Guide
Guide
210 Views
Registered: ‎01-23-2009

As opposed to other families (before UltraScale) where the BUFG resources were "global", they are not in UltraScale.

In the 7 series, there were 32 BUFGCTRLs located just north and south of the middle of the FPGA. For inputs, they could (basically) take any valid input from the same half (north/south) of the FPGA. Specifically, the I pin of the BUFGCTRL could use a dedicated route from:

  • Any clock capable input pin in the same half
  • Any MMCM or PLL output in the same half

In UltraScale, the clock buffers are now in regions; they are in the I/O columns next to the clock capable pins and MMCMs/PLLs in that clock region. Consequently, they can only be driven by the resources in the same region. But, there are many more of them; 24 BUFGCE, 8 BUFGCTRL and 4 BUFCE_DIV per region (contrast this with the 7 series, which had no BUFGCE_DIV, and only 32 BUFCTRL - of which the BUFGCE is a simplification - per FPGA). Although, you can only use 24 in total per region (so if you use all the BUFGCE_DIV you can only use up to 20 BUFCE/BUFGCTRL).

But the connectivity is limited; the I input of all these clock buffers must come from clock inputs in the same region; the four clock capable input pins in this clock region and the outputs of the MMCMs/PLLs in the same region.

So the problem you are having is (presumbly) that you are trying to drive more than 4 BUFGCE_DIV from inputs in the same clock region. There are only 4, so it can't do this. And since they are not "global" like in other families, it can't simply use resources from other clock regions.

So, if this is really your need - you have 6 divided clocks coming from inputs in the same clock, then you have to do things differently. First of all, it is unusual to need this many divided clocks - why do you need them? Can you generate these clocks in an MMCM rather than using BUFGCE_DIVs. If not, you need to understand that the BUFGCE_DIV is a "new" resource in UltraScale/UltraScale+/Versal - previous generations didn't have them. In older families, you would need to use a BUGCE and generate the logic to drive the CE of the BUFGCE appropriately. While it is easier to use the BUFGCE_DIV, you can still use the BUFGCE to do division - you just need your own logic to drive the CE (and you also need constraints). Take a look at this post on using the BUFCGE for clock division.

Finally, don't confuse the "CLOCK_ROOT" with the location of the BUFG*. The CLOCK_DELAY_GROUP controls where the CLOCK_ROOT goes - this is the transfer point between the clock routing network and the clock distribution network - this has nothing (directly) to do with the location of the BUFG* itself - it is in the clock region determined by the thing driving it.

Avrum

View solution in original post

5 Replies
Highlighted
Moderator
Moderator
272 Views
Registered: ‎01-16-2013

@chiaming_hung 

This is not timing issue. This is Implementation issue, It is best practice to ask query in correct board to get swift and correct response as many experts follow specific board to help the users.

Please post your query in Implementation board. I can move this post to Implementation but as it's old this may get lost in that board, hence asking you to re-post your query in respective board.

Thanks,
Yash

0 Kudos
Highlighted
Participant
Participant
262 Views
Registered: ‎01-19-2020

Hi,

 

OK, could you help to remove this post here?

I don't find any deletion option.

 

Thanks.

0 Kudos
Highlighted
Moderator
Moderator
260 Views
Registered: ‎01-16-2013
Hi,

Let it be here not a problem. If someone has same query and he landed on this link at least they will know that they need to look for implementation board for answer.

Thanks,
Yash
0 Kudos
Highlighted
241 Views
Registered: ‎01-22-2015

@chiaming_hung 

The placement-error tells you that Vivado is trying to place too many BUFGCE_DIV into a single clocking region (CR).  In an UltraScale device, each CR has only 4ea BUFGCE_DIV.

Here are methods for solving this placement-error:

  • If you have a BUFGCE_DIV with a DIVIDE value of 1, then you can replace it with a BUFGCE.  If required, a BUFGCE can be used in the feedback path of an MMCM/PLL. 
  • Don't cascade clock buffers.  A single clock buffer is all that is needed to drive a clock into the FPGA clock tree.
  • The  CLOCK_DELAY_GROUP constraint should only be placed on pairs of clocks for which you are doing a direct crossing of data between the two clock domains.   Overuse of this constraint can cause Vivado to attempt placing all your BUFGCE_DIV into one clocking regio(CR). 
  • You can sometimes force Vivado to place a BUFGCE_DIV in a specific CR by using the CLOCK_REGION constraint (page 100, UG949).  This is a way to spread out your BUFGCE_DIV to separate clocking regions.

These methods are completely successful only if they both solve the placement-error and allow your design to pass timing analysis.

Cheers,
Mark

Highlighted
Guide
Guide
211 Views
Registered: ‎01-23-2009

As opposed to other families (before UltraScale) where the BUFG resources were "global", they are not in UltraScale.

In the 7 series, there were 32 BUFGCTRLs located just north and south of the middle of the FPGA. For inputs, they could (basically) take any valid input from the same half (north/south) of the FPGA. Specifically, the I pin of the BUFGCTRL could use a dedicated route from:

  • Any clock capable input pin in the same half
  • Any MMCM or PLL output in the same half

In UltraScale, the clock buffers are now in regions; they are in the I/O columns next to the clock capable pins and MMCMs/PLLs in that clock region. Consequently, they can only be driven by the resources in the same region. But, there are many more of them; 24 BUFGCE, 8 BUFGCTRL and 4 BUFCE_DIV per region (contrast this with the 7 series, which had no BUFGCE_DIV, and only 32 BUFCTRL - of which the BUFGCE is a simplification - per FPGA). Although, you can only use 24 in total per region (so if you use all the BUFGCE_DIV you can only use up to 20 BUFCE/BUFGCTRL).

But the connectivity is limited; the I input of all these clock buffers must come from clock inputs in the same region; the four clock capable input pins in this clock region and the outputs of the MMCMs/PLLs in the same region.

So the problem you are having is (presumbly) that you are trying to drive more than 4 BUFGCE_DIV from inputs in the same clock region. There are only 4, so it can't do this. And since they are not "global" like in other families, it can't simply use resources from other clock regions.

So, if this is really your need - you have 6 divided clocks coming from inputs in the same clock, then you have to do things differently. First of all, it is unusual to need this many divided clocks - why do you need them? Can you generate these clocks in an MMCM rather than using BUFGCE_DIVs. If not, you need to understand that the BUFGCE_DIV is a "new" resource in UltraScale/UltraScale+/Versal - previous generations didn't have them. In older families, you would need to use a BUGCE and generate the logic to drive the CE of the BUFGCE appropriately. While it is easier to use the BUFGCE_DIV, you can still use the BUFGCE to do division - you just need your own logic to drive the CE (and you also need constraints). Take a look at this post on using the BUFCGE for clock division.

Finally, don't confuse the "CLOCK_ROOT" with the location of the BUFG*. The CLOCK_DELAY_GROUP controls where the CLOCK_ROOT goes - this is the transfer point between the clock routing network and the clock distribution network - this has nothing (directly) to do with the location of the BUFG* itself - it is in the clock region determined by the thing driving it.

Avrum

View solution in original post