I have a set of ripple clocks. Yes, I know, don't do that, but we seem to get a decent power savings vs enables.
Now, I hope I'm not insane. I have a main global clock at 320MHz coming off the PLL, and I divide it down by various factors. So, lots of division, but all the derived clocks start at a flop that is clocked by my main global clock before going out.
So, I use create_generated_clock to create clk_160MHz, clk_80MHz etc. Source is the global PLL clock and I divide that down. That all seems to work fine. Paths that go from clk_160MHz to clk_160MHz, clk_80MHz to clk_80MHz, etc. seem to work and all meet my requirements without much issue.
However, the moment I have a path that originates from a flop clocked by clk_160MHz and terminates in a flop clocked by clk_80MHz, Timequest starts putting in all manner of clock skew and sometimes misses setup and hold constraints. This is true even if the path is literally flop-to-flop with no logic in between (I could see missing hold, but *setup*?). This is especially bad if I try to go from a flop clocked by 80MHz moving to 160MHz or 160MHz moving back to the global clock at 320MHz.
Why? All the edges are generated from global_clk. The skew should *at maximum* be a little uncertainty + a clock to Qdelay + some routing. Certainly nothing that should make a direct flop-to-flop path fail.
I presume I'm missing something in my constraints. I looked in the TimeQuest User Guide and it mentions multicycle paths, but I'm a little reluctant to activate that by hand without a much clearer understanding of why I should do so. This shouldn't need a multicycle as it goes flop-to-flop with more than enough time to work even at 320MHz, right?
I included a screenshot of what TimeQuest thinks is the path. I can provide other data if you tell me what to generate.
Any suggestions or pointers? Thanks.
Now, I hope I'm not insane. I have a main global clock at 320MHz coming off the PLL, and I divide it down by various factors. So, lots of division, but all the derived clocks start at a flop that is clocked by my main global clock before going out.
Code:
--------------- -------
|Divider logic| -----> |D Q|-----> clk_160MHz, clk_80MHz, clk_16MHz, etc.
--------------- | CLK |
-------
^
|
global_clk(320MHz)
However, the moment I have a path that originates from a flop clocked by clk_160MHz and terminates in a flop clocked by clk_80MHz, Timequest starts putting in all manner of clock skew and sometimes misses setup and hold constraints. This is true even if the path is literally flop-to-flop with no logic in between (I could see missing hold, but *setup*?). This is especially bad if I try to go from a flop clocked by 80MHz moving to 160MHz or 160MHz moving back to the global clock at 320MHz.
Why? All the edges are generated from global_clk. The skew should *at maximum* be a little uncertainty + a clock to Qdelay + some routing. Certainly nothing that should make a direct flop-to-flop path fail.
I presume I'm missing something in my constraints. I looked in the TimeQuest User Guide and it mentions multicycle paths, but I'm a little reluctant to activate that by hand without a much clearer understanding of why I should do so. This shouldn't need a multicycle as it goes flop-to-flop with more than enough time to work even at 320MHz, right?
I included a screenshot of what TimeQuest thinks is the path. I can provide other data if you tell me what to generate.
Any suggestions or pointers? Thanks.