Community
cancel
Showing results for 
Search instead for 
Did you mean: 
Altera_Forum
Honored Contributor I
1,829 Views

Timequest constraints for a dynamically phase-shifted PLL

I've been trying to properly constrain a design that uses dynamic phase shifting of an instance of an altera_pll core that I created. I.e. to enable phase-shifting I checked the "enable access to dynamic phase shift ports" in the IP creation dialog box for my PLL. 

 

The dynamically phase-shifted PLL output is used to drive synchronous logic. I use a separate clock to actually dynamically shift the PLL and am careful to use the Altera-recommended 'asynchronous assert, synchronous de-assert' reset paradigm on the logic driven by the phase-shifted PLL after I do a phase shift. 

 

My .SDC file contains: 

 

derive_pll_clocks 

derive_clock_uncertainty 

 

...at the top of my file, yet there's no Timequest constraints automatically created w.r.t. phase shifting, which is disappointing because the wizard should know that I can only shift eight 45-degree increments and it knows all other parameters thereof because I gave it to the wizard, sigh. 

 

The intent here is to have a total of eight logically-exclusive clocks coming off of the output pin of the PLL. So I attempted to create some constraints: 

 

create_generated_clock -add -name apg_phase00_045 -source {drv1|mypll_apg_ph0|*|altera_pll_i|cyclonev_pll|counter.output_counter|vco0ph} -divide_by 1 -multiply_by 1 -duty_cycle 50.00 -phase 44.9 {drv1|mypll_apg_ph0|*|altera_pll_i|cyclonev_pll|counter.output_counter|divclk} create_generated_clock -add -name apg_phase00_090 -source {drv1|mypll_apg_ph0|*|altera_pll_i|cyclonev_pll|counter.output_counter|vco0ph} -divide_by 1 -multiply_by 1 -duty_cycle 50.00 -phase 90 {drv1|mypll_apg_ph0|*|altera_pll_i|cyclonev_pll|counter.output_counter|divclk} create_generated_clock -add -name apg_phase00_135 -source {drv1|mypll_apg_ph0|*|altera_pll_i|cyclonev_pll|counter.output_counter|vco0ph} -divide_by 1 -multiply_by 1 -duty_cycle 50.00 -phase 135 {drv1|mypll_apg_ph0|*|altera_pll_i|cyclonev_pll|counter.output_counter|divclk} create_generated_clock -add -name apg_phase00_180 -source {drv1|mypll_apg_ph0|*|altera_pll_i|cyclonev_pll|counter.output_counter|vco0ph} -divide_by 1 -multiply_by 1 -duty_cycle 50.00 -phase 179.9 {drv1|mypll_apg_ph0|*|altera_pll_i|cyclonev_pll|counter.output_counter|divclk} create_generated_clock -add -name apg_phase00_225 -source {drv1|mypll_apg_ph0|*|altera_pll_i|cyclonev_pll|counter.output_counter|vco0ph} -divide_by 1 -multiply_by 1 -duty_cycle 50.00 -phase 225 {drv1|mypll_apg_ph0|*|altera_pll_i|cyclonev_pll|counter.output_counter|divclk} create_generated_clock -add -name apg_phase00_270 -source {drv1|mypll_apg_ph0|*|altera_pll_i|cyclonev_pll|counter.output_counter|vco0ph} -divide_by 1 -multiply_by 1 -duty_cycle 50.00 -phase 270 {drv1|mypll_apg_ph0|*|altera_pll_i|cyclonev_pll|counter.output_counter|divclk} create_generated_clock -add -name apg_phase00_315 -source {drv1|mypll_apg_ph0|*|altera_pll_i|cyclonev_pll|counter.output_counter|vco0ph} -divide_by 1 -multiply_by 1 -duty_cycle 50.00 -phase 314.9 {drv1|mypll_apg_ph0|*|altera_pll_i|cyclonev_pll|counter.output_counter|divclk} 

 

...the '44.9', '179.9' and '314.9' were echoed to me by the Altera wizard after I tried entering '45'. '180', and '315' degrees for those respective phase shifts, so that’s why I chose those. 

 

That's seven generated clocks from eight possible phase-shifts, so where's the eighth? Answer: that's the default i.e. the PLL output pin (Wizard was given a 0-degree shift as the default): 

 

{drv1|mypll_apg_ph0|*|altera_pll_i|cyclonev_pll|counter[0].output_counter|divclk} 

 

Then I declare each of the eight clocks selections as logically-exclusive in my .SDC: 

 

set_clock_groups -logically_exclusive -group {apg_phase00_045} -group {apg_phase00_090} -group {apg_phase00_135} -group {apg_phase00_180} -group {apg_phase00_225} -group {apg_phase00_270} -group {apg_phase00_315} -group {drv1|mypll_apg_ph0|*|altera_pll_i|cyclonev_pll|counter[0].output_counter|divclk} 

 

I should mention that the PLL instance is fed a 50MHz clock "{u0|hps_0|fpga_interfaces|clocks_resets|h2f_user1_clk}", which comes from my Cyclone V's HPS (i.e. as created through the HPS section of the Qsys IP component), which is also used to drive an Avalon memory-mapped slave which does the triggering.  

 

The PLL output is 300 MHz (input mult’ed by 12, divided by 2), so as can be imagined, I've had to create a lot of timing constraints so that everything fits and makes timing, which it does, successfully, thanks to false-paths and multicycles where they can be used. 

 

Everything works great - the clocks look fine from the Timequest report, etc. I can see that the phase shifting is working via my oscilloscope - it's a pretty sight to see I must say. :) 

 

but there is one big problem - I am seeing apparent metastabiltiy when I trigger my dynamically-shifted synchronous logic via the Avalon slave – it sometimes causes the dynamically-phase shifted circuit to activate one cycle early or late, as if my carefully defined constraints were not in play and were violating T[SUB]sh[/SUB]/T[SUB]h[/SUB]. 

 

As can be guessed, the behavior of the metastabiltiy is a function of which phase I choose – some phases are very unstable, others apparently not at all, which is expected from eight logically-exclusive clocks sharing one fitted path. 

 

I'm baffled at this because all clocks look good, and everything appears perfectly constrained. In fact, for the dynamically-phase shifted logic, one way I checked that there was one fitting common to all of the clocks on the trigger path was to verify that there was the same 'clock skew' and 'data delay' for each of the phases as I varied 'to_clock' parameter - checking between phases via these Timequest reports, for example: 

 

report_timing -from_clock { u0|hps_0|fpga_interfaces|clocks_resets|h2f_user1_clk } -to_clock { apg_phase00_180 } -to *rEnableOutput* -setup -npaths 100 -detail full_path -panel_name {xxx} -multi_corner report_timing -from_clock { u0|hps_0|fpga_interfaces|clocks_resets|h2f_user1_clk } -to_clock { apg_phase00_225 } -to *rEnableOutput* -setup -npaths 100 -detail full_path -panel_name {xxx} -multi_corner 

 

I'm not sure what to do. I've scoured the internet for examples on how to properly constrain a design that uses PL dynamic phase shifting and haven't had any luck. Any help would be appreciated. Perhaps some timing quirk related to phase-shifting has been overlooked. or perhaps because some of my phases aren’t exactly 0, 44.9, 90, 135, 179,9, 225, 270, or 314.9 degrees? 

 

All of my logic is on rising edges, so I tried to add some T[SUB]sh[/SUB] elbow room by adding constraints like this (one per phase shift, of course), but that didn’t help: 

 

set_clock_uncertainty -rise_from -rise_to 0.380  

 

...default was 0.140. 

 

-Eric
Tags (2)
0 Kudos
29 Replies
Altera_Forum
Honored Contributor I
115 Views

Hi, 

 

I have read your post but did not understand for what purpose you are using dynamic phase shift option? Is there some data transfer between different clock domains?
Altera_Forum
Honored Contributor I
115 Views

Hi vlrean, 

 

The logic clocked by the dynamically phase-shifted PLL is used to drive an industrial device. 

 

-Eric
Altera_Forum
Honored Contributor I
115 Views

So you are seeing metastability issues in external device? Have you added set_output_delay constrains to your .sdc file?

Altera_Forum
Honored Contributor I
115 Views

Hi vlrean, 

 

The repro is purely in the domain of my synchronous logic driven by the dynamically phase-shifted PLL before our device is even hooked up. Not that it would matter anyway - our industrial device has no clock, so no source-synchronous constraints such as set_output_delay are needed. :) 

 

I should add that since I was concerned that the phase shifts weren't exactly every 45 degrees, I was able to derive what Quartus thinks they are via the technique discussed here (thanks, Brad!): https://www.alteraforum.com/forum/showthread.php?t=4567 (https://www.alteraforum.com/forum/showthread.php?t=4567

 

...and that didn't help when I specified them as such, unfortunately. FYI, what I did was instantiate a special just-for-investigation PLL that was statically phase-shifted so I could see what values Quartus created for passing to the '-phase' parameter, then I used those values for the non-investigation dynamically phase-shifted PLL instantiation. 

 

What I really need is a timing guru to tell me whether my constraints look okay and if the '-logically_exclusive' does actually work for dynamically phase-shifted PLLs. Anyone? 

 

-Eric
Altera_Forum
Honored Contributor I
115 Views

Hi,  

I think you are providing to little info about your project to attract gurus :) maybe draw some basic block diagram from which clocks and PLLs can be seen. In addition Can you post your .sdc file? As from my experience I would do like: 

1. Constrain all base clocks. 

2. Constrain generated clocks with correct properties frequency phase shift, use -add Argument if there is more than one clock. Check TimeQuest "Clock" and "Clock Tree" reports to see if all you clock constrains are correct.  

3. Use set_clock_groups with -logically_exclusive Argument to cut clock transfers between PLL phase shifted clocks. Check TimeQuest "Clock Transfers" report to see if detected clock transfers are correct. 

4. Check setup and hold reports for every phase shifted clock, check that you have proper launch and latch clock edge relationship.  

5. set_multicycle_path if they are necessary. 

6. Check if any constrains are ignored.  

 

That should be enough to constrain dynamically phase shifted PLL clocks (I am assuming you allready done that).  

 

As I understand you have some timing related issues when running on hardware but TimeQuest reports say that there are no timing errors in all corners? Maybe you have added some false path exceptions where you should not?
Altera_Forum
Honored Contributor I
115 Views

It's not clear what you mean by "activating one cycle early or late". However could it be that you are expecting a given phase to be "later" than another particular phase i.e. lag rather than "early" or lead? 

 

I mean once it has activated, does it work fine? Does it malfunction in any other way? Is it just that the time of so called "activation" is not what you expect?
Altera_Forum
Honored Contributor I
115 Views

Hi vlrean, 

 

Items 1 thru 6 you list are already done - my timing is fully constrained, and there are no errors reported. 

 

] As I understand you have some timing related issues when running on hardware but TimeQuest reports say that there are no timing errors in all corners? 

 

Correct. 

 

] Maybe you have added some false path exceptions where you should not?  

 

Yeah, that was one of the first things I thought of, but the affected path has the correct timing relationship, as verified by Timequest's reports.
Altera_Forum
Honored Contributor I
115 Views

Hi de-em, 

 

Once the PLL is locked on a new phase, it will output correctly on most of the eight phases, but on some of the phases (varies by build which ones they are) the output randomly comes in one latching-clock early or late. This suggests to me that it is a metastability issue - as if my logically-exclusive timing constraints were NOT being analyzed correctly by Timequest and/or the fitter.
Altera_Forum
Honored Contributor I
115 Views

A variable phase-shifted clock domain has to be considered as asynchronous to other clocks, respective synchronization methods for domain crossing data signals are required. Timing constraints don't help because STA isn't able to check a variable timing. I guess that Timequest is simply calculating timing for the initial phase shift of the respective clock output. 

 

By the way, 99% of random results in case of timing violations are not caused by true metastability but simple clock and data delay variations if a is latched in more than register.
Altera_Forum
Honored Contributor I
115 Views

eh291, what clock transfers does Timequest report? Presumably it does not report any between the multiple phases but at the boundary of the logic, are there any transfers between some other clock and each of the phases? Are these analyzed separately and do they all meet timing? 

 

FvM, shouldn't Quartus report a critical warning if it cannot analyze this type of timing arrangement? There are examples in the cookbook of multiple clocks on a single node and I don't see how this is any different.
Altera_Forum
Honored Contributor I
115 Views

Timing errors can sometimes occur when paths are inappropriately or mistakenly cut either through setting an exclusive clock group or by explicitly cutting a path (I know, I have done this myself). If there are or should be valid clock transfers which should be analyzed between each of the phases and some other reference clock, then that clock presumably could be included in each of the exclusive groups. 

 

Maybe something like (though I haven't tried this): 

 

set_clock_groups -logically_exclusive -group {apg_phase00_045 clock_x} -group {apg_phase00_090 clock_x} -group {apg_phase00_135 clock_x} -group {apg_phase00_180 clock_x} -group {apg_phase00_225 clock_x} -group {apg_phase00_270 clock_x} -group {apg_phase00_315 clock_x} -group {drv1|mypll_apg_ph0|*|altera_pll_i|cyclonev_pll|co unter[0].output_counter|divclk clock_x}
Altera_Forum
Honored Contributor I
115 Views

 

--- Quote Start ---  

A variable phase-shifted clock domain has to be considered as asynchronous to other clocks, respective synchronization methods for domain crossing data signals are required. Timing constraints don't help because STA isn't able to check a variable timing. 

--- Quote End ---  

 

 

Is it?  

Lets say that we have clock CLK_A which feeds PLL with one output, PLL dynamic phase shift feature is used and PLL can generate two clocks CLK_B_0deg or CLK_B_90deg on same output. Data is launched from CLK_A domain and latched in CLK_B_0deg/CLK_B_0deg domain. 

 

so we have following constrains:  

 

#Base clock create_clock -period 10 -name CLK_A # PLL constrains create_generated_clock -name CLK_B_0deg -master -source ] -phase 0 ] create_generated_clock -name CLK_B_90deg -master -source ]] -phase 90 ] -add # Clock groups set_clock_groups -exclusive -group {CLK_B_0deg} -group {CLK_B_90deg} \ 

 

CLK_B_0deg and CLK_B_90deg can not be active both in same time, any paths between those two clocks are cut. So TimeQuest should detect that CLK_A is synchronous to CLK_B_0deg and CLK_A is synchronous to CLK_B_90deg. If my understanding is correct we should be able to generate following timing reports: 

1 - from CLK_A to CLK_B_0deg.  

2 - from CLK_A to CLK_B_90deg.  

 

And we should be able to see if one of those paths fail timing and one of those PLL clock phases can not be used right?
Altera_Forum
Honored Contributor I
115 Views

For those following this thread visually, a post from more than a day ago by me containing screenshots and updated info was just cleared by a moderator, but it appeared above an existing post. Apparently posts are sorted by the webserver according to authored time, not accepted time.

Altera_Forum
Honored Contributor I
115 Views

Why do you need the multicycle constraints? Have you tried not having them?

Altera_Forum
Honored Contributor I
115 Views

Yeah, it fails timing without the relaxed constraints, because there's a default setup relationship of 416.66 picoseconds for the 45-degree phase shift (because the phase shifted clock is running 300MHz therefore a 3.333 nanosecond period, and then the divide by eight for the phase shifts).

Altera_Forum
Honored Contributor I
115 Views

So are you generating appropriate clock enables to sample the signal with enough setup and hold time for each clock transfer at each phase setting? It's not enough just to define a multicycle constraint as that will not alter the physical clock relationship and if this is the case then I would expect metastability issues to arise.

Altera_Forum
Honored Contributor I
115 Views

Yeah, that's what I believe I did, and I think that's what the waveform and clock relationship screenshots show in the .ZIP files I attached to this thread. I'd very much like to be proven wrong so I can fix my code.

Altera_Forum
Honored Contributor I
115 Views

With respect, I'm not sure if you understood what I am asking (you say that you "believe you did"??). It is all very well to apply your constraints as you have (and the images show the relaxed setup relationships etc), but the fact is that without specific clock enable signals to enable the latch register at the appropriate time, you are setting things up for timing failure or metastability.

Altera_Forum
Honored Contributor I
115 Views

I read your "generating appropriate clock enables to sample the signal with enough setup and hold time for each clock transfer at each phase setting" to mean do I have the timing constraints properly in place for all phases by having only two ‘set_multicycle_paths’ in my Timequest constraints file (because it seems unlikely at first glance that those two would cover all eight phases, but they appear to me to do). 

 

So, do you mean am I using clock enables AKA gated clocks? I.e. such as those described in the “Clock Enable Multicycle” section of ‘mnl_timequest_cookbook.pdf’, page 25 {document revision 2017.11.21}]? If that’s what you meant, I am not using any gated clocks. 

 

Thanks for your continued interest.
Altera_Forum
Honored Contributor I
56 Views

Clock enables are not the same as gated clocks though (the clock would still be running freely but the clock enable would enable the register). There may be some of your clock phases where the latch register is sampling the data input in a time frame where the result could be metastable or uncertain (I think that much is clear from the description of your problem). So simply relaxing the setup time with a multicycle constraint does not alter the outcome. 

 

Imagine a system where you generate a series of clock enable signals which enable the latch register clocked by the selected 300 MHz clock phase; now in that system, the multicycle constraints would make sense because they describe exactly when the actual launch and latch occur. You only have half of the solution and that is the constraints. This is how I see it anyway. I'm not suggesting that the clock enable idea is a solution because I don't fully understand what the firmware is attempting to achieve and I can only see the small bit currently under the microscope.
Reply