Intel® Quartus® Prime Software
Intel® Quartus® Prime Design Software, Design Entry, Synthesis, Simulation, Verification, Timing Analysis, System Design (Platform Designer, formerly Qsys)
The Intel sign-in experience has changed to support enhanced security controls. If you sign in, click here for more information.

set_clock_groups notes

Honored Contributor II

I did a quick write-up on set_clock_groups and thought I'd post it here. In general, I think every design should use set_clock_groups in their .sdc, so it's worth understanding. (It looks complicated at first, but the more I use it the more I realize it's very powerful while remaining elegant). Anyway, onto the syntax(I'm shortening the clock names for readability in a post): 


set_clock_groups -asynchronous  

-group {clkA  




-group {clkB  




-group {dsp_clk  





That's the basic syntax. In essence, what it does is a set_false_path between the clocks n the first group to the clocks in the second two groups, and between the second two group(i.e. all clocks in a group are asynchronous to the clocks in another group). It's nice because the above constraint would have to be done with 66 individual constraints, which would be completely unreadable. Some notes: 


- I run Report Clocks in TimeQuest, and copy all the clock names out of the first column and paste them into the .sdc. Then it's just a matter of formatting them into this command, but I know I have all the clock names spelled correctly(see last note for exceptions to this) 


- Be careful of the escape character at the end of each line. If there's a space or tab after it, you won't see it, but the escape character will just escape that space or tab and not the end of line. The next line will be considered a new, unrecognizable command and TQ will error out. You will bang your head on the desk for an hour figuring it out. 


- Any clocks not in this command are related to all clocks. So if I add another output called PLL2_c3 and forget to add it to this command, it will be related to all the clocks.  


- You can have as many groups as you want. You can also have multiple set_clock_groups assignments. 


- A clock cannot appear in more than one group in a single set_clock_group command. 


- The -asynchronous command could also be -exclusive. This says the clocks are mutually exclusive(only one will be running at a time) as opposed to being asynchoronous. As for as TimeQuest is concerned, the two commands do the identical thing and cut timing between clocks in different groups. This option comes from ASIC land, where SI affects like cross-talk are analyzed, and so if two clocks are -exclusive, not only will paths between them not be analyzed, they won't have any secondary affects. Not only is this used by ASICs, but on our Hardcopy back-end, so if your design is going to Hardcopy it's worth thinking about. (And note that the above example, where the first two groups have the same input clock coming into PLL1, technically you would want to make those -exclusive) But if not going to Hardcopy, don't worry about it. 


- There is a special syntax where one -group is used. Basically it means cut the clocks from this group to any other clocks in the design. Something like: 


set_clock_groups -asynchronous -group {altera_jtag_tck} 


I've seen users take advantage of that like so: 


set_clock_groups -asynchronous -group {clkA PLL1_c0 PLL1_c1 } 

set_clock_groups -asynchronous -group {clkB PLL2_c0 PLL2_c1 } 

set_clock_groups -asynchronous -group {dsp_clk PLL3_c0 PLL3_c1 PLL3_c2} 


This will do the same thing as the first example. The reason I recommend it is because of the second bullet. If you add another output called PLL2_c3 and forget to add it to the third group, it will be cut to all the other outputs of that PLL. In other words, this can be dangerous. 


- In general, I recommend adding all clocks to the group. Exceptions are: 


1) DDR and GXB designs, where there are about 50 millions clocks added to the design that the user doesn't know about. 95% of them have paths only to domains that are relevant or are cut in the .sdc files that get created, so basically I don't worry about them and it keeps the command a little cleaner. 


2) I recommend doing virtual clocks for all I/O interfaces(except source-synch outputs, naturally). I don't add those virtual clocks to this because the only paths they connect to our I/Os that I explicitly designate, i.e. they tend to only have real paths. But it doesn't hurt to add them in either.
7 Replies
Honored Contributor II

Once you separate clock groups as asynchronous, is there any way to still lightly constrain the paths that cross the clock domains?  


Without some loose constraints, FPGA routing can add extraordinary delays, and in extreme cases you could have problems. Two examples might include (1) grey coded fifo pointers, or (2) a synchronized read strobe accompanied by an unsynchronized address. 


It is for this reason that I have usually specified multicycle paths for what are really asynchronous crossings, though the asynchronous groups are much less complicated. Sometimes I get odd results with the multicycle paths, too, requiring 3 or even 4 as the cycle count. 


Honored Contributor II

I understand this concern. One thing of note is that the placer/router has two main goals while doing it's thing, meeting timing and reducing wire usage(which increases routability). If it weren't for the second one, then a design with a 5MHz goal would take 10 seconds to place, since the first legal placement would meet timing. So there is a goal of reducing delays, it just usually comes secondary if something else needs that placement/route for better timing. In other words, just because a path is cut, it won't get a 30ns route on it. FIFOs are a good example, in which case it's true that a absolutely huge delay across gray code transfers would probably mess it up, yet almost all designs cut this path and I've never heard of anyone having a problem.  

I'm not saying your methodology doesn't make sense, it's just one of those things that I don't think is necessary in practice.
Honored Contributor II

Is there an sdc command that would allow a loose constraint? Maybe 

set max_delay 10ns -from [get_clocks clock1] -to [get_clocks clock2] 


Or does the asynchronous group command cut all analysis of those paths? 


Honored Contributor II

The asynchronous command has priority. But set_max_delay and set_min_delay has second highest priority, so if you didn't do set_clock_groups, and instead did a set_max_delay 10 between all asynchronous clocks(in both directions), that would be what you want. I would also recommend doing a set_min_delay -5.0 or something like that. It's possible for paths to go between clocks, where they might be on different clock resources like a global and a regional, and if you had a 0ns hold requirement, the router would be adding delay on these "semi-asynchronous" paths, just to meet timing.  

And on a thread where I'm trying to show people how powerful and good set_clock_groups is, thanks for scaring everyone. (Just kidding...:) )
Honored Contributor II

Naturally, some straightforward for-loops would do what you want without a bazillion lines of code that becomes unreadable. 


I'm also a fan of the following, which goes through every clock combination and reports timing on the worst 50 false paths between them: 

set npaths 50 

set detail summary ;#summary path_only full_path 

set ac [all_clocks] 

foreach_in_collection clk1 $ac { 

foreach_in_collection clk2 $ac { 

set clk1_name [get_clock_info -name $clk1] 

set clk2_name [get_clock_info -name $clk2] 

report_timing -setup -npaths $npaths -detail $detail -from_clock $clk1_name -to_clock $clk2_name -panel_name "$clk1_name -> $clk2_name" -false_path 


It takes a while to run, but you generally wouldn't do it that often. And of course the slacks are somewhat meaningless, since the requirements are based off unrelated clocks. That all being said, if you had a path that suddenly had 50ns of route on it, it would show up here.
Honored Contributor II

(laughing) sorry... I agree that set_clock_groups -asynchronous is good and powerful - and despite my qualms, I'm using it right now because of troubles encountered with the multicycle paths.


Thanks for the concise summary.   Just a note here, which may be obvious but was not for me:

For the warning message

My_clock "could not be matched with a clock"

Check the case of the designated clock.  It seems to matter here - My_clock and My_Clock are not the same.