TimeQuest User Guide | Diagnostic
negative Clock to Output does not generally make sense. In essence, it treats the phase-shift like a delay element on the clock path.
This is not like normal setup and hold analysis, where any user inserted phase-shift is not
a -180 degree phase-shift. All in all, the way the Datasheet Report handles phase-shifts is how many users think, but it’s important to understand the differences between its report and the real analysis being done for setup and hold.
This command is the only diagnostic report that runs as part of Report All Summaries.
This report nicely tells what the clocks look like after everything has been read in, including .sdc files, and hence what TimeQuest is using for analysis. This “view” can be much more straightforward of what’s going on, rather than digging through RTL for clock names, or into
.sdc files from IP vendors to see what clocks are created. It also clearly states the clock name, which can be cut and paste from for use in .sdc constraints or timing reports.
I’m a big fan of this command. It gives an excellent report of how many paths exist between every pair of clocks, false paths included. If there are no physical connections between two clocks, they won’t show up. Here’s the report from a sample design:
This report gets generated for setup, hold, recovery and removal. I find Setup Transfers to be the most interesting. Note that RR Paths refer to paths where both registers are clocked on the rising edge. RF, FR and FF refer to different combinations of rise/fall clock transfers.
Finally, domains with false_path indicate that timing was cut between these clocks, either with a set_false_path between the clocks or in a set_clock_groups assignment. If the clock transfer is not cut at the clock level but some individual paths are cut, the number of paths between those clocks will be reported and the false paths will be included in that number. (E.g if there are 10 paths between two clocks, and 5 of them are cut with a set_false_path, this report will still state 10 paths exist.)
The user can right-click on any row and either do a Report Timing…, or Report False
Path. These two commands will explicitly show the paths between those domains, with the number of paths and detail level specified by the user. Remember that Report False Path, which is just report_timing with the -false_path flag added to it, will only report paths that have been cut, either at the path level or at the clock level, so Report Timing and Report False Path will create a mutually exclusive list of all paths between those clocks made up of real paths and false paths.
Major domains that clock a lot of logic will have a LOT of paths listed, which is expected and not that useful of a number. Instead, it’s the domains that have a small number of transfers, usually less than 100, that I find interesting. The first thing to ask is if the domains are related.
If they are it’s not a big deal, it just means a small number of paths send synchronous data. But if the clocks are asynchronous to each other and paths exist, is that expected? Quite often it is, and the paths will be inside an asynchronous FIFO, or perhaps a clock adaptor bridge inside
SOPC Builder. But if the transfers are not expected, the user should investigate those paths and see if a mistake was made. Debugging incorrect transfers between asynchronous clocks is difficult in simulation, and extremely difficult in hardware, so being able to identify them in
There’s a quick trick for getting rid of the “false path” description in this report. I will open my .sdc file and comment out the set_clock_group assignments, as well as any
set_false_path assignments that are between clocks. I will reset_design, and then double-click
Report Clock Transfers. This will read in the edited .sdc files that do not have any domains cut, and will report the number of paths between every domain. It may be helpful to take a screenshot of the original report or put it in a text file to compare which domains are really cut with this new report that shows how many paths exist between all domains.
Report Unconstrained Paths - report_ucp
This is an extremely important report, as it identifies unconstrained paths in the design.
The most useful items it reports are unconstrained clocks and unconstrained I/O.
Unconstrained clocks start at the most basic, which is an input port that is used as a clock and does not have a clock constraint. After that are generated clocks, such as PLL outputs and transceiver outputs, which are usually covered by derive_pll_clocks, but would be missed if you’re not using that command. Finally, ripple clocks, which occur when a register’s output drives the .clk port of another register, need a create_generated_clock assignment or else they will show up as an unconstrained clock in this report. The one thing that will not show up is a
gated clock, i.e. when clocks go through purely combinatorial logic such as a mux. In these cases, the base clocks just pass through the structure, and hence it is not unconstrained, but could be constrained with a create_generated_clock at the mux output if the user wishes. See the
The unconstrained clock report is useful first off for any clocks the user forgot to constrain. If some clocks are unconstrained, they will be optimized for area during synthesis and the fitter will not try optimize paths within this domain. The user may say that’s all right, as the domain may be very slow, but remember that hold violations can occur on the slowest of clock domains, i.e. 1Hz clocks can still fail a hold violation and still fail in hardware. More importantly, transfers between this domain and other domains will not be analyzed, which is another source for failure.
The second big use for unconstrained clocks is when a clock shows up that the user thought they constrained. The most likely scenario is from an error in the SDC file where their assignment did not take. The user should re-examine their assignment, as well as go back to the
TimeQuest messages to see if a warning was issued when the assignment was processed.
Besides clocks, I/O ports are the next major portion of this report. Minimally, most users know they have not constrained all of their I/O, and hence this is a quick list of which I/O they missed. A constrained I/O port has one of the following constraints on it, set_input_delay,
set_output_delay, set_max_delay, set_min_delay, or set_false_path. Note that output ports which send out a clock usually have a create_generated_clock assignment on them, but nothing else. These outputs show up in the unconstrained path report, although the comment section nicely states that it does have a clock assignment. I generally leave output ports sending clocks as unconstrained, although this will annoy some users, and some designs have requirements that all I/O are constrained. Adding a loose timing constraint would work around this:
set_max_delay 200.0 -to [get_ports clkout] set_min_delay -200.0 -to [get_ports clkout]
The clock output won’t be anywhere near those values, but these assignments will stop the port from showing up as unconstrained.
If your .sdc is straightforward, then this report won’t do much more than report out what you put in. I find this most useful for complex constraints. For example, if the user’s constraints are made of variables, it’s sometimes helpful to see the constraint at its most basic level. For example, with an .sdc like so(I made up the values):
# CPU Specs: set cpu_tco_max 6.123 set cpu_tco_min 3.434
# Board delays: set cpu2fpga_max 0.877 set cpu2fgpa_min 0.488
set clk2cpu_max 1.455 set clk2cpu_min 1.011 set clk2fpga_max 1.505 set clk2fpga_min 1.074
# Equations for CPU to FPGA: set iMax_cpu [expr $clk2cpu_max + $cpu_tco_max + $cpu2fpga_max - $clk2fpga_min] set imin_cpu [expr $clk2cpu_min + $cpu_tco_min + $cpu2fpga_min - $clk2fpga_max]
# FPGA’s inputs from CPU: set_input_delay -max -clock cpu_clk_ext $iMax_cpu [get_ports i_cpu_*] set_input_delay -min -clock cpu_clk_ext $imin_cpu [get_ports i_cpu_*]
That makes for a nicely descriptive SDC file, with the benefit of auto-calculating new requirements if the user changes the board delays or parameters of the external device. The only problem is that the final value isn’t apparent without doing the math by hand. The user could add something like the following to their .sdc to echo the calculated value to the messages:
puts “iMax_cp => $iMax_cpu \n imin_cpu => $imin_cpu”
The problem is that you still have to find it in the messages. Running report_sdc allows the user to quickly find:
Of course, the user could also run basic timing analysis on the path:
report_timing -setup -detail full_path -from [get_ports i_cpu*] -panel_name “s: i_cpu*” report_timing -hold -detail full_path -from [get_ports i_cpu*] -panel_name “s: i_cpu*”
the hold report.
The report_sdc command is also useful if looking at constraints from an SDC created elsewhere, such as Altera’s DDR2/3 IP cores. The user won’t hand-edit machine-generated SDC files, but can use report_sdc to see what constraints were added.
Report Ignored Constraints - “report_sdc -ignored”
Ignored constraints will always produce a warning in TimeQuest’s messages, which is useful, but often ignored by the user. I find this panel very useful to manage ignored constraints and try to get them down to as few as possible.
Note that ignored constraints are not always a problem. I have seen designs with various parameters that add/remove large sections of code depending on the build configuration. That code might have a lot of assignments, say multicycles and false paths, which are ignored when that block of code is not in the design. But unless the reason is well understood and accepted, ignored constraints should be cleaned up by the user. I also think they should be taken care of early on, rather than as a final design clean-up. The reason is that an ignored constraint often causes other problems that are difficult to debug.
A common example is when a user’s set_clock_groups command has errors and is ignored, whereby all their asynchronous clocks become related, analyzed, and fail timing. The designer spends time analyzing a bunch of failing paths with impossible requirements, finally realizing they should not have been analyzed in the first place, and then going back to the
TimeQuest messages to find why a constraint was ignored. If the user checked this report first, the problem would have been found much more quickly.
A more serious situation is when a user has multicycles or false paths within a domain that are ignored. The fitter might actually be able to close timing on those paths, so they don’t show up as failures, but because they compete with real paths, those real paths suddenly get lessthan-ideal placement. Without looking at the Ignored Constraints report, the user may never know of this problem and spend days/weeks trying to optimize timing through other methods, always assuming their exceptions were working.
And be aware that exceptions which are working might stop working midway through a project. One of the most common issues is when a hierarchy path changes, and hence the node names to everything beneath it have changed. If the assignments use full path names, they will no longer take. The hierarchy may change due another designer making a modification. It might be due to a different naming convention for generate statements. It may be due to regeneration of IP. All of these might occur without the user thinking to check if their .sdc constraints are still valid.
Recommendation: When possible, strive to get your design’s Ignored Constraints report as close to having no ignored constraints as possible. The benefit is that if anything changes, new Ignored Constraints should be easily identifiable, and the user can fix the problem up front rather than debugging the secondary effects of an ignored constraint.
This report was created by the TimeQuest group to look for common mistakes they see.
Some of them are covered in other reports, such as unconstrained clocks or I/Os, and some give warnings in the messages, such as the PLL cross-check. These checks are not saying something is wrong, and if the user knows what they are doing there are many conditions where they would purposely design something that is flagged by check_timing. These checks are mostly stating that the design is doing something uncommon, and so the user might want to verify what they are doing is correct.
These checks are not documented very well. When they flag a possible issue, they give a quick description of the problem which is often clear enough, but in a few scenarios can leave the user scratching their head. I’ll try to address as many as I can:
Virtual_clock - This flag occurs when no virtual clocks are found, which is generally a bad thing, since they are the basis of I/O constraints and really the first step for creating
This flag also occurs when a virtual clock is created, but not used in any constraints.
Naturally if it’s never used, there isn’t any point in creating it, and so something may be wrong.
No Input Delay/No Output Delay - This check is not saying that the I/O are unconstrained, just that they don’t have a set_input_delay or set_output_delay assignment on them. If they have a set_false_path assignment, then I consider that more than enough since you’re explicitly saying the I/O should not be constrained. If the design has only set_max_delay and set_min_delay constraints, then it is not the official methodology for constraining I/O, but fine for users who understand what they’re doing. A section on using these constraints for I/O is
I have found this check get flagged on True LVDS I/O, which generally do not need
DPA Receivers, don’t get reported at all. This is a case where the check needs to be analyzed by the user. Yes, True LVDS ports might not have input/output delay constraints, but they are also not needed.
Generated_IO_delay - This check occurs when the user has a set_input_delay or
set_output_delay assignment whose -clock option uses a clock internal to the FPGA. The common scenario is when a new user enters the clock that drives the register inside the FPGA, such as the PLL that drives the input register:
set_input_delay -clock the_adc_pll|altpll_component|auto_generated|pll1|clk -max 4.0 \
As highlighted in red, the user is specifying an internal PLL clock for their set_input_delay constraint. New users often make this mistake and it is always wrong, since the analysis to the external register will use part of the FPGA’s clock tree up to the PLL output, but
Note that the name is a little misleading, since there is one common case where generated clocks work for I/O constraints. If the user has a create_generated_clock assignment on an output port to designate a clock being sent off chip, it is perfectly fine to use that clock for the
-clock option of set_input_delay and set_output_delay constraints. This will not be flagged by check timing either. It is only when a set_input_delay or set_output_delay’s -clock option uses a generated clock from inside the FPGA, such as a PLL output or ripple clock, will this get checked.
Partial Input/Output/MinMax Delay - These constraints usually come in pairs. For example, if the user does the following constraint, they have only applied the max delay analysis(i.e. setup analysis): set_input_delay -max -clock cpu_clk_ext 6.0 [get_ports cpu_data*]
To be complete, the user should have a matching set_input_delay -min constraint to make sure the path is not too fast, which will be checked during hold analysis. This check occurs when a user has constrained a path, but only half of it.
Like many of the other checks, something getting flagged does not mean it is wrong. A user may override the default setup relationship on a path with set_max_delay, but keep the default hold analysis. This path would be flagged as only having a Partial Min-Max Delay constraint, which is true, but the user is all right with that since the min analysis done by the default hold relationship is what they want.
Partial Multicycle - This check occurs when a path has either a multicycle setup or hold,
path will have a positive hold requirement and the design may become unroutable as it adds delay to meet that requirement, where the necessary multicycle -hold would fix the problem. If
can be ignored. To get rid of the check, the user could add a matching multicycle hold that mimics the default hold: set_multicycle_path -setup -from [get_clocks clk_a] -to [get_clocks clk_b] 2
set_multicycle_path -hold -from [get_clocks clk_a] -to [get_clocks clk_b] 0
The first constraint shifts the window. The second constraint is unnecessary since it mimics the default hold relationship, but it would prevent this timing check from being flagged.
PLL Cross Check - PLL’s are configured based on how they are instantiated in the design, not what the timing constraints say. So if the user creates a PLL that has a 10ns input and creates a 5ns output, then physically the PLL will be configured for that. But if the user applies a timing constraint stating the input is 8ns, and derive_pll_clocks says the output is 4ns, there will be a PLL Cross Check flag. There will also be a warning in the messages.
The ability to have different settings is useful for a user who may want to run timing analysis at different rates without re-generating the PLL and creating a new image. In the example above, they may be curious if they can meet an 8ns input if they move up a speed grade, so they would create_timing_netlist for the faster speed grade and modify the SDC for the faster requirement, and just run TimeQuest to see the results. But if they are actually going to production, they need to regenerate the PLL with the new settings to ensure the correct bandwidth, VCO, and other internal settings are chosen for optimal performance.
Input Delay assigned to Clock - Clocks coming into the FPGA generally have a
create_clock assignment, but do not have any set_input_delay assignments, which are for data inputs. This check alerts they user they have put a set_input_delay constraint on a clock, which
* Your assessment is very important for improving the work of artificial intelligence, which forms the content of this project