Intel® Quartus® Prime Software
Intel® Quartus® Prime Design Software, Design Entry, Synthesis, Simulation, Verification, Timing Analysis, System Design (Platform Designer, formerly Qsys)
17259 Discussions

timing constraint for clock mux and how to set output delay

Altera_Forum
Honored Contributor II
12,466 Views

Hi all, 

 

I have to constrain the output pins of my design by using "set_output_delay." 

The reference clock for those outputs pins comes from a clock mux. 

I've check the following link to know how to constrain the input clocks of a clock mux. 

http://www.altera.com/support/examples/timequest/exm-tq-clock-mux.html 

However, I don't know how to constrain the clock coming from the mux. 

Could anyone please teach me how to do that? 

 

The attached picture (following pic) depicts my design. 

https://www.alteraforum.com/forum/attachment.php?attachmentid=7583
0 Kudos
12 Replies
Altera_Forum
Honored Contributor II
8,186 Views

How is the clock divider done, with a register used as a ripple clock?  

In TQ, clocks propagate through logic, such as a much, but not through registers. Because of this, I might see a 2:1 clock mux in logic(where the sources are pins or PLLs) and the user doesn't do anything special and it all works out. They just cut timing between the two source clocks because they're not related. If they are related, the user has to put two generated clocks on the output of the mux, something like: 

 

create_generated_clock -name clkA_muxed -source [get_ports clkA] [get_pins {clk_mux_hierarchy|o}] 

create_generated_clock -name PLL_muxed -source [get_pins PLL_name] [get_pins {clk_mux_hierarchy|o}] -add 

set_clock_groups -asynchronous -group {clkA_muxed} -group {PLL_muxed} 

 

Now there are two clocks going through the mux, but they're not related, i.e. they can't both be driving through at the same time, but clkA_muxed can drive the base PLL, and PLL_muxed can connect to the base clkA for example, of course you can cut those too: 

set_clock_groups -asynchronous -group {clkA_muxed clkA} -group {PLL_muxed PLL_name} 

This cuts timing between the clkA and it's muxed version, and PLL and it's muxed version. It's really going to do the same analysis as not doing any generated clocks and just cutting timing between clkA and PLL. The difference is there are names for everything driven by the mux, so it's easier to analyze it's timing, i.e. you can do: 

report_timing -setup -npaths 100 -detail full_path -from_clock clkA_muxed -to_clock clkA_muxed -panel_name "setup: within clkA_muxed" 

Obviously you can do all sorts of combinations, like from clkA to clkA_muxed, to see if any paths cross and will have large skew. Another benefit is if it shows up in one of the summary reports, like Setup Summary, there will be separate lines for clkA, clkA_muxed, PLL and PLL_muxed, so you have a better idea if you see one failing where it's at. 

 

Now in your case, let's say the dividers are registers. Clocks do NOT propagate through registers and you must put a generated clock on them. You might have something like: 

create_clock -name clkA -period 10.0 [get_ports clkA] 

create_generated_clock -name B_div -source [get_ports clkA] -divide_by 2 [get_keepers {div_B_reg}] 

create_generated_clock -name C_div -source [get_ports clkA] -divide_by 4 [get_keepers {div_C_reg}] 

# First mux: 

create_generated_clock -name E_muxedA -source [get_ports clkA] [get_pins E_mux|o] 

create_generated_clock -name E_muxedB -source [get_keepers {div_B_reg}] [get_pins E_mux|o] -add 

# Second mux(I'm calling F) 

create_generated_clcok -name F_muxedA -source [get_pins E_mux|o] -master_clock E_muxedA [get_pins F_mux|0] 

create_generated_clcok -name F_muxedBdiv -source [get_pins E_mux|o] -master_clock E_muxedB [get_pins F_mux|0] -add 

create_generated_clcok -name F_muxedCdiv -source [get_keepers {div_B_reg}] [get_pins F_mux|0] -add 

 

# Finally the output port: 

create_generated_clock -name clk_out_A -source [get_pins F_mux|o] -maser_clock F_muxedA [get_ports clk_out] 

create_generated_clock -name clk_out_B -source [get_pins F_mux|o] -maser_clock F_muxedBdiv [get_ports clk_out] -add 

create_generated_clock -name clk_out_C -source [get_pins F_mux|o] -maser_clock F_muxedCdiv [get_ports clk_out] -add 

 

This is the worst case, most complicated manner, but it is complete. Note that for generated clocks, the -source is a physical node in the design, not a clock name. The reason this is done is for IP, the user can just specify a point in the design and not have to know the clock name that is applied to it. A good example is an input port driving a PLL. When they call derive_pll_clocks, TQ puts a generated clock on the output of the PLL, and it's source is just the pin going into the PLL(not the physical port, but the reference clock pin on the PLL cell). TimeQuest then traces back to the input port. The beauty of this is that the generated clock assignment doesn't need to know the name of the input port or the name of the clock assigned to it, and it still works. The user can change the input port name or clock on the fly and the PLL will automatically update. Anyway, when the -source of the assignment is a physical node that has more than one clock going through it, like a mux, the user needs to add the -master_clock option to specify which clock they are talking about. 

 

You will also need a set_clock_groups assignment to say most of these clocks aren't related, otherwise TQ will analyze cases where one clock goes through the mux and feeds the source register, and the other clock goes through the mux and feeds the destination, and vice-versa. 

 

This all looks really complicated, but it accounts for all cases. You really do have three separate source clocks(A, divB and divC), then multiple combinations that comes out of the mux, and multiple ways they could all be related. This gives you complete control.
0 Kudos
Altera_Forum
Honored Contributor II
8,186 Views

Ryan, 

I am using: 

get_pins {umaxa|Mux0~0|datab}  

 

in my create_generated_clock to constrain clock mux (8 to 1 mux). If I change some areas of the source code (not related to the mux) and recompiled, I found out those clocks coming into the mux dataa, datab, datac, datad pins are changed and my SDC statements are not valid anymore. Is there any way to call out get_pins which tolerant the mux input pin changes because of the Quartus compiler? 

 

 

Thanks, 

 

my sdc:# #mux0~0 

create_generated_clock -name A_muxed0~0_dnclk[0] -source [get_ports {dnclk[0]}] [get_pins {umuxa|Mux0~0|datad}] 

create_generated_clock -name A_muxed0~0_dnclk[1] -source [get_ports {dnclk[1]}] [get_pins {umuxa|Mux0~0|datac}] -add# #mux0~1 

create_generated_clock -name A_muxed0~1_dnclk[2] -source [get_ports {dnclk[2]}] [get_pins {umuxa|Mux0~1|datac}] 

create_generated_clock -name A_muxed0~1_dnclk[3] -source [get_ports {dnclk[3]}] [get_pins {umuxa|Mux0~1|datab}] -add 

create_generated_clock -name A_muxed0~1_dnclk[0] -source [get_pins {umuxa|Mux0~0|datad}] -master_clock A_muxed0~0_dnclk[0] [get_pins {umuxa|Mux0~1|dataa}] -add 

create_generated_clock -name A_muxed0~1_dnclk[1] -source [get_pins {umuxa|Mux0~0|datac}] -master_clock A_muxed0~0_dnclk[1] [get_pins {umuxa|Mux0~1|dataa}] -add
0 Kudos
Altera_Forum
Honored Contributor II
8,186 Views

How come you're applying the generated clock to the LUT inputs(dataa, datab, etc.) instead of the LUT output. When doing a mux, I would recommend something like: 

create_generated_clock -name A_muxed0~0_dnclk[0] -source [get_ports {dnclk[0]}] [get_pins {umuxa|Mux0~0|combout}] 

create_generated_clock -name A_muxed0~0_dnclk[1] -source [get_ports {dnclk[1]}] [get_pins {umuxa|Mux0~0|combout}] -add 

This way it doesn't matter which pin dnclk[1:0] comes in on. 

Note that for an 8:1 mux, it is recommended to build that out of 2:1 muxes and put keeps on them, e.g. something like: 

(* keep *) wire muxa,muxb, muxc,muxd,muxe,muxf,muxg; 

assign muxa = s[0] ? a:b; 

assign muxb =s[0] ? c:d; 

assign muxc = s[0] ? e:f; 

assign muxd = s[0] ? g:h; 

 

assign muxe = s[1] ? muxa : muxb; 

assign muxf = s[1] ? muxc : muxd; 

 

assign muxg = s[2] ? muxe : muxf; 

 

I did that quick, but something like that. This is to avoid toggling from unselected clocks causing your output to glitch.
0 Kudos
Altera_Forum
Honored Contributor II
8,186 Views

Hi Ryan, 

Thanks for the quick reply. I got it corrected now ( getting the targets for the clocks, mux outputs). 

I have one more question. I created DDIO for data and clock to create synchronous clock interface (SDR). But fitter ignores the fast output register "on" settings. Any idea where should I look at it?
0 Kudos
Altera_Forum
Honored Contributor II
8,186 Views

What device? You used the altddio megafunction? Assuming the device has DDIO and you used the megafunction, the fitter has to use the DDIO cell because it can't put it in logic. How are you sure it's not using the I/O cell, i.e. is it a warning you're getting or are you looking to make sure it's not there? Perhaps it is using it because it has to, and then ignores the assignment because there's not a single-register it can push in, or something silly like that.  

I used to use Fast Input/Output assignments all the time, but haven't used them in years. I find the fitter does a good job packing them automatically, and if you have I/O timing assignments(which you should for anything you care about), it should always put them in the I/O cell if that's what's necessary to close timing.
0 Kudos
Altera_Forum
Honored Contributor II
8,186 Views

Hi Ryan, 

Thanks for the reply. Yes you are right. It is just a warning but it already in the IO. Compiler just issued those warning for some other reason like you said in your reply. This morning, I found out when I tried to located the outputs and inputs in the chip planner and resource property editor and found those are already packed in the IOs. It is a Stratix device. I use the Megafunction to generate ddio. Attached are some screen shots in resource property editor. Thanks again. 

http://www.alteraforum.com/forum/attachment.php?attachmentid=9536&stc=1
0 Kudos
Altera_Forum
Honored Contributor II
8,186 Views

Hi Ryan, 

Thanks for the reply. Yes it is already in the IO. I found out this morning when I search IOs in the property resource editor. The compiler issued a warning for some other reasons like you said in your reply. It is Stratix device and I use Megafunction to generate the DDIOs. I have attached the screen short of the property resource editor.  

Thanks again. 

 

https://www.alteraforum.com/forum/attachment.php?attachmentid=9537
0 Kudos
Altera_Forum
Honored Contributor II
8,186 Views

The Fast I/O assignments don't work on DDR, so you have to use the MegaWizard/IP Console to create the altddio megafunction, and once done it will always be put in the I/O cell. This is unlike a SDR register, which can be done in RTL, is put into the I/O cell by the fitter, and the assignment can therefore tell the fitter what to do. I'm guessing with the assignment it either looked for an RTL register and couldn't find one to put into the I/O cell(not even check if DDR was used), or it found one but couldn't put it into the I/O cell because the DDR was already used. Regardless, it's dumb to say it was ignored.  

I do think the Fast I/O assignments should be deprecated, as there's little use for them nowadays. (Once upon a time that was the only way to get them used...) 

 

A quicker way to check is go to the Fitter Report, Input/Output pins, and there is a column that says whether the input or output register was used. (Although it is nice to physically see it in the Resource Property Editor, as your screen-shot shows). And if you have timing constrains, report_timing will show it going to/from an I/O cell too.
0 Kudos
Altera_Forum
Honored Contributor II
8,186 Views

Ryan, 

Thanks for the explanation. You recommended to use 2to1 mux to create 8 to 1 mux with "synthesis keep" on wires. you said "This is to avoid toggling from unselected clocks causing your output to glitch. ". Can you please explain the reason behind that? I did not follow that because I did not want to rewrite all clock constraints at that time. My clock output is toggling even when no input clock was selected. I put data and clock together in the mux ( I have 8 different channels of data and clock to be muxed). please see the technology map viewer shot for the clock mux portion in my design.
0 Kudos
Altera_Forum
Honored Contributor II
8,186 Views

I once saw a large clock mux get synthesized into some ugly logic. It wasn't a mux tree like you're showing here. Instead, it had a larger blob, and though I forget the exact details, but in one case the clock selected went through two different paths through the LUT blob. It was technically correct from the logic, but it did glitch. This was probably ten years ago, but I've been paranoid since then and always hand-code as 2:1 muxes feeding each other and put KEEPS on each stage. Note that Settings -> Analysis & Synthesis -> More Settings has an option called Clock Mux Protection and has the following description: 

Causes the multiplexers in the clock network to be decomposed to 2to1 multiplexer trees, and protected from being merged with, or transferred to, other logic. This option helps the TimeQuest timing analyzer to understand clock behavior. 

 

So I think synthesis is going to try and do this naturally and I'm being paranoid. I don't know if there are any reports when this occurs, although your Technology Map Viewer looks correct.
0 Kudos
Altera_Forum
Honored Contributor II
8,186 Views

Hi Ryan, 

I have clkctrl automatically included behind the clock mux by Quartus II in a Cyclone II design. When I do "create_generated_clock" to constrain 2 clocks go through the clock mux, do I need to do another "creat_generated_clock" after the Mux0~clkctrl? 

 

Example,  

at the Mux0 output pin: 

create_generated_clock -name muxed0_clk-a -source [get_pins {mux39x3:inst102|mux0~0|combout}] -master_clock muxed0~0_clk-a [get_pins {mux39x3:inst102|mux0|combout}] 

create_generated_clock -name muxed0_clk-b -source [get_pins {mux39x3:inst102|mux0~0|combout}] -master_clock muxed0~0_clk-b [get_pins {mux39x3:inst102|mux0|combout}] -add 

at the Mux0~clkctrl output pin: 

create_generated_clock -name clkctrl_clk-a -source [get_pins {inst102|mux0~clkctrl|inclk[0]}] -master_clock muxed0_clk-a [get_pins {inst102|mux0~clkctrl|outclk}] 

create_generated_clock -name clkctrl_clk-b -source [get_pins {inst102|mux0~clkctrl|inclk[0]}] -master_clock muxed0_clk-b [get_pins {inst102|mux0~clkctrl|outclk}] -add 

 

Please see the attached screen shot ( technology map viewer) 

 

Thanks,
0 Kudos
Altera_Forum
Honored Contributor II
8,186 Views

No, you only need one of those generated clocks. It doesn't matter either, but I do the first one since it's name is independent of the global being inserted.

0 Kudos
Reply