cancel
Showing results for 
Search instead for 
Did you mean: 
Highlighted
Contributor
Contributor
8,330 Views
Registered: ‎02-24-2016

Clock Divider with BUFGCE: missing constraint?

Jump to solution

Hi All,

 

The FPGA I am working with receives an input CLK with a frequency that depends on ADC sampling rate, and it is upper bounded by the value of 400 MHz.

I want to use this CLK in my FPGA logic, however, since 400 MHz is obviously too high, I want to divide it by 2.

For this purpose, I want to use a BUFGCE, as pointed out in this post

 

My code is as follows

entity top is
  port (
    -- Reset and clock
    init 	: in  std_logic; -- 
    clk_p        : in    std_logic;
    clk_n        : in    std_logic;
	-- data  interface                           
    do_data   : out std_logic -- output  data
  );
end top;

architecture arch of top is

	signal clk_ibufgds	: std_logic;
	signal clk_bufg    	: std_logic;
	signal clk 	: std_logic;
	signal ce 	: std_logic;
	signal clk_div2 : std_logic;
	-- 
	signal pwg : std_logic; -- wave and inverted wave
 
begin

    -- get input clk
	inst_clk_ibufgds : IBUFGDS
	generic map (
		IOSTANDARD           => "DEFAULT"
	)
	port map (
		O                    => clk_ibufgds,
		I                    => clk_p,
		IB                   => clk_n
	);

	-- Put clock on global routing (alternatively to MMCM)
	inst_clk_bufg : BUFG
	port map (
		O                    => clk_bufg,
		I                    => clk_ibufgds
	);

	clk <= clk_bufg;
	
	--------------
	-- clk div 2
	--------------
	-- BUFGCE: Global Clock Buffer with Clock Enable Virtex-6
    -- Xilinx HDL Language Template, version 14.7
	BUFGCE_inst : BUFGCE
	port map (
	  O => clk_div2,   -- 1-bit output: Clock buffer output
	  CE => ce, -- 1-bit input: Clock enable input for I0 input
	  I => clk_ibufgds    -- 1-bit input: Primary clock input
	);

	process (clk)
	begin
		if (rising_edge(clk)) then
			if (init = '1') then
				ce <= '0';
			else 
				ce <= not ce;
			end if;
		end if;
	end process;
	
	-- Logic @clk_div2	(just an example)
	process(clk_div2)
	begin
		if (rising_edge(clk_div2)) then
			if (init = '1') then
				pwg <= '0';
				do_data <= '0';
			else 
				pwg <= not pwg;
				do_data <= pwg;
			end if;
		end if;
	end process;
	
end arch;

and these are the contraints

NET "clk_?" TNM_NET = "TNM_CLK";
TIMESPEC "TS_CLK" = PERIOD "TNM_CLK" 2.5 ns; #400MHz

NET "clk_div2" TNM_NET = "TNM_CLK_DIVIDED";
TIMESPEC "TS_CLK_DIVIDED" = FROM "TNM_CLK_DIVIDED" TO "TNM_CLK_DIVIDED" "TS_CLK" * 2;

 

I got an error message that I don't understand well, and I would like some help on how to fix it. The error is

Paths for end point BUFGCE_inst (BUFGCTRL_X0Y31.CE0), 1 path 
 -------------------------------------------------------------------------------- 
 Slack (setup path):     -1.334ns (requirement - (data path - clock path skew + uncertainty)) 
   Source:               ce (FF) 
   Destination:          BUFGCE_inst (OTHER) 
   Requirement:          2.500ns 
   Data Path Delay:      1.552ns (Levels of Logic = 1)(Component delays alone exceeds constraint) 
   Clock Path Skew:      -2.247ns (0.547 - 2.794) 
   Source Clock:         clk_bufg rising at 0.000ns 
   Destination Clock:    clk_ibufgds rising at 2.500ns 
   Clock Uncertainty:    0.035ns 
  
   Clock Uncertainty:          0.035ns  ((TSJ^2 + TIJ^2)^1/2 + DJ) / 2 + PE 
     Total System Jitter (TSJ):  0.070ns 
     Total Input Jitter (TIJ):   0.000ns 
     Discrete Jitter (DJ):       0.000ns 
     Phase Error (PE):           0.000ns 
  
   Maximum Data Path at Slow Process Corner: ce to BUFGCE_inst 
     Location             Delay type         Delay(ns)  Physical Resource 
                                                        Logical Resource(s) 
     -------------------------------------------------  ------------------- 
     SLICE_X111Y137.DQ    Tcko                  0.337   ce 
                                                        ce 
     BUFGCTRL_X0Y31.CE0   net (fanout=2)        1.059   ce 
     BUFGCTRL_X0Y31.I0    Tbccck_CE             0.156   BUFGCE_inst 
                                                        BUFGCE_inst 
     -------------------------------------------------  --------------------------- 
     Total                                      1.552ns (0.493ns logic, 1.059ns route) 
                                                        (31.8% logic, 68.2% route) 
  
 -------------------------------------------------------------------------------- 

 

I know that the CE must be synchronous,  but to which clock? What does the "-2.247 ns clock path skew" mean? Is it a false path that I can ignore? If yes, how?

 

Thank you very much

 

 

0 Kudos
1 Solution

Accepted Solutions
Guide
Guide
14,422 Views
Registered: ‎01-23-2009

Re: Clock Divider with BUFGCE: missing constraint?

Jump to solution

What does the "-2.247 ns clock path skew" mean? Is it a false path that I can ignore?

 

So, this is not a false path, and it cannot be ignored...

 

The CE of the BUFGE is synchronous to the clock input of the BUFGCE (the .I input). You can see this in UG472, v1.12, figure 2-8 as tBCCCK_CE (which can be looked up in the appropriate DS - like DS182 for Kintex-7).

 

However, the FF that is driving the CE is clocked on the output of a BUFG (through a global clock network), and hence has a significant amount of delay - that is the 2.247ns skew.

 

To be honest with you, I am not certain how to solve this - at 400MHz, it may not be possible... As much as I hate to suggest it, you might consider using a local clock (i.e. clk_ibufgds directly) for driving the FF that drives the CE (but that's always dangerous).

 

If you don't need to drive a "lot" of logic on this divided clock, then you have two options:

 

Instead of generating a gated clock, just use the "ce" as an enable

 

-- Logic @clk_div2	(just an example)
	process(clk)
	begin
		if (rising_edge(clk)) then
if (ce) then if (init = '1') then pwg <= '0'; do_data <= '0'; else pwg <= not pwg; do_data <= pwg; end if;
end if; end if; end process;

 

Another option would be to use a BUFHCE. As opposed to the BUFGCE, the BUFHCE goes in series with the BUFG (not in parallel) - so the .I of the BUFHCE would be clk_bufg, not clk_ibufgds. This will minimize the clock skew. However, the output of a BUFHCE can only drive the clocked logic in one clock region, as opposed to the BUFGCE, which can clock logic anywhere on the die.

 

Finally, you can always generate both clocks as outputs of an MMCM/PLL. When you generate two clocks from the same MMCM/PLL they are always in phase, so you can have CLKOUT0 generate the 1x clock and CLKOUT1 generate the clk_div2 (use a BUFG for each of them).

 

Avrum

View solution in original post

5 Replies
Guide
Guide
14,423 Views
Registered: ‎01-23-2009

Re: Clock Divider with BUFGCE: missing constraint?

Jump to solution

What does the "-2.247 ns clock path skew" mean? Is it a false path that I can ignore?

 

So, this is not a false path, and it cannot be ignored...

 

The CE of the BUFGE is synchronous to the clock input of the BUFGCE (the .I input). You can see this in UG472, v1.12, figure 2-8 as tBCCCK_CE (which can be looked up in the appropriate DS - like DS182 for Kintex-7).

 

However, the FF that is driving the CE is clocked on the output of a BUFG (through a global clock network), and hence has a significant amount of delay - that is the 2.247ns skew.

 

To be honest with you, I am not certain how to solve this - at 400MHz, it may not be possible... As much as I hate to suggest it, you might consider using a local clock (i.e. clk_ibufgds directly) for driving the FF that drives the CE (but that's always dangerous).

 

If you don't need to drive a "lot" of logic on this divided clock, then you have two options:

 

Instead of generating a gated clock, just use the "ce" as an enable

 

-- Logic @clk_div2	(just an example)
	process(clk)
	begin
		if (rising_edge(clk)) then
if (ce) then if (init = '1') then pwg <= '0'; do_data <= '0'; else pwg <= not pwg; do_data <= pwg; end if;
end if; end if; end process;

 

Another option would be to use a BUFHCE. As opposed to the BUFGCE, the BUFHCE goes in series with the BUFG (not in parallel) - so the .I of the BUFHCE would be clk_bufg, not clk_ibufgds. This will minimize the clock skew. However, the output of a BUFHCE can only drive the clocked logic in one clock region, as opposed to the BUFGCE, which can clock logic anywhere on the die.

 

Finally, you can always generate both clocks as outputs of an MMCM/PLL. When you generate two clocks from the same MMCM/PLL they are always in phase, so you can have CLKOUT0 generate the 1x clock and CLKOUT1 generate the clk_div2 (use a BUFG for each of them).

 

Avrum

View solution in original post

Highlighted
Contributor
Contributor
8,260 Views
Registered: ‎02-24-2016

Re: Clock Divider with BUFGCE: missing constraint?

Jump to solution

@avrumw thank you so much for your answer.

 

I replaced the BUFGCE with the BUFHCE, as per your suggestion, and everything works fine now - so thank you very much!

 

The topic of timing constraints and timing resources is quite hard to grasp for me: I have yet to find a clear and complete exposure of the concepts behind,and the best source of info are the answer on this forum. Do you by chance happen to know a document that explains in a tutorial way how to write timing constraints and how to use Xilinx timing resources?

 

And if you have some extra time, I'd like to ask you few questions on your previous answer.

 

However, the FF that is driving the CE is clocked on the output of a BUFG (through a global clock network), and hence has a significant amount of delay - that is the 2.247ns skew

Could you elaborate a bit more on this? Why do you say that the FF, being on the global clock network, has a significant delay? What does add to the 2.247ns skew? I would say that the skew is only due to the delay added by the BUFG, correct?

 

Instead of generating a gated clock, just use the "ce" as an enable

I considered this option, but then I discarded it because I did not know how to tell to the tool that that block of logic would operate at half the CLK rate (200 MHz in this case). Could you please point out what time constraint construct I should have used?

 

Finally, you can always generate both clocks as outputs of an MMCM/PLL.

This was my first attempt. But the clock wizard requires a deterministic and constant value for the input frequency of the MMCM/PLL. In my case, the CLK is generated externally, and its frequency it is configured dynamically by the user, so I can't specify a fixed value. Or could I have used the PLL anyway?

 

Once again, thank you very much for your help

Marco

0 Kudos
Highlighted
Guide
Guide
8,250 Views
Registered: ‎01-23-2009

Re: Clock Divider with BUFGCE: missing constraint?

Jump to solution

Do you by chance happen to know a document that explains in a tutorial way how to write timing constraints and how to use Xilinx timing resources?

 

Not really. There is, however, a class given by Xilinx through its Authorized Training Provider network that covers this material really well - Vivado Design Suite Advanced XDC and Static Timing Analysis for ISE Software Users (but, of course, there is a cost for this).

 

Why do you say that the FF, being on the global clock network, has a significant delay?

 

The global clock network is a pre-routed dedicated clock network. It starts at the BUFG, but fans out to the entire FPGA - every clocked element anywhere on the die can be clocked by the global clock. To fan out to potentially tens or hundreds of thousands of endpoints, this network is huge and (therefore, by definition) slow - it can definitely take 2+ns for the clock to go through the BUFG, and the entire clock network before ending up at the C input of a particular flip-flip.

 

...logic would operate at half the CLK rate (200 MHz in this case). Could you please point out what time constraint construct I should have used?

 

This would be

 

set_multicycle_path           2 -from $slow_ff_list -to $slow_ff_list

set_multicycle_path -hold 1 -from $slow_ff_list -to $slow_ff_list

 

However the construction of $slow_ff_list can be difficult. While there are commands that will allow you to (maybe) find all FFs that use a particular signal as a CE (using a combination of the all_fanout command and the "IS_ENABLE" property of pins), I don't consider this to be reliable and I don't recommend using it. If you have a way of identifying the list (ideally through hierarchy as in "all FFs in these modules use the ce as their enables), then you can do it that way.

 

By the way, you still have to modify constraints for the BUFGCE or BUFHCE - the tools cannot recognize this "clock division" automatically. You can do it via a set_multicycle_path (as above) with

 

set slow_ff_list [all_fanout -flat -endpoints_only -only_cells [get_pins my_bufhce/O]

 

Or you can do it with

 

create_generated_clock -divide_by 2 -source [get_pins my_bufghce/I] [get_pins my_bufhce/O]

 

or more accurately

 

create_generated_clock -edges {1 2 5} -source [get_pins my_bufghce/I] [get_pins my_bufhce/O]

 

(yeah - you will have to look that one up in the constraint guide...)

 

But the clock wizard requires a deterministic and constant value for the input frequency of the MMCM/PLL.

 

The "fixed" value needed by the clock wizard just helps the wizard figure out the best dividers to keep the VCO and PFD frequencies in the optimal ranges. The MMCM/PLL can actually accept different clock rates, as long as the VCO and PFD frequencies remain in legal ranges. You will need to look in the data sheet to determine the legal ranges, and then do the calculations manually to determine if a particular set of dividers are legal across the entire range. As a general rule, if the range is more than about 2:1 (or a bit more), then the MMCM/PLL can't do it.

 

Even if you do find a legal set of dividers, you cannot "dynamically" change the input frequency; if the input frequency changes, you have to reset the MMCM/PLL to have it re-lock to the new frequency.

 

Avrum

0 Kudos
Highlighted
Contributor
Contributor
8,207 Views
Registered: ‎02-24-2016

Re: Clock Divider with BUFGCE: missing constraint?

Jump to solution

Awesome!

Thank you

0 Kudos
Highlighted
Explorer
Explorer
1,964 Views
Registered: ‎06-09-2018

Re: Clock Divider with BUFGCE: missing constraint?

Jump to solution

@avrumw

you said: "you might consider using a local clock (i.e. clk_ibufgds directly) for driving the FF that drives the CE (but that's always dangerous)."

 

why generating a clk (locally) is dangerous?

0 Kudos