Quartus® Prime Pro Edition User Guide: Timing Analyzer

ID 683243
Date 9/30/2024
Public
Document Table of Contents

2.4.1.5.3. set_clock_groups Constraint Tips

When you use derive_pll_clocks to create clocks, it can be time consuming to determine all the clock names to include in set_clock_groups constraints. However, you can use the following technique to somewhat automate clock constraint creation, even if you do not know all of the clock names.

  1. Create a basic .sdc file that contains the Recommended Initial Conventional SDC Constraints, except omit the set_clock_groups constraint for now.
  2. To add the .sdc to the project, click Assignments > Settings > Timing Analyzer. Specify the .sdc file under SDC files to include in the project.
  3. To open the Timing Analyzer, click Tools > Timing Analyzer.
  4. In the Task pane, double-click Report Clocks. The Timing Analyzer reads your .sdc, applies the constraints (including derive_pll_clocks), and reports all the clocks.
  5. From the Clocks Summary report, copy all the clock names that appear in the first column. The report lists the clock names in the correct format for recognition in the Timing Analyzer.
  6. Open .sdc file and the paste the clock names into the file, one clock name per line.
  7. Format the list of clock names list into the set_clock_groups command by cutting and pasting clock names into appropriate groups. Next, paste the following template into the .sdc file:
    set_clock_groups -asynchronous -group { \  
    } \
     -group { \ 
    } \  
    -group  { \
    } \ 
    -group { \
    } 
  8. Cut and paste the clock names into groups to define their relationship, adding or removing groups, as necessary. Format the groups to make the code readable.
    Note: This command can be difficult to read on a single line. You can use the Tcl line continuation character "\" to make this more readable. Place a space after the last character, and then place the "\" character at the end of the line. Be careful not to include any spaces after the escape character. Otherwise, the space becomes the escape character, rather than the end-of-line character.
    set_clock_groups -asynchronous \  
        -group {adc_clk \ 
           the_adc_pll|altpll_component_autogenerated|pll|clk[0] \
           the_adc_pll|altpll_component_autogenerated|pll|clk[1] \
           the_adc_pll|altpll_component_autogenerated|pll|clk[2] \
        } \
        -group {sys_clk \ 
           the_system_pll|altpll_component_autogenerated|pll|clk[0] \
           the_system_pll|altpll_component_autogenerated|pll|clk[1] \
        } \  
        -group {the_system_pll|altpll_component_autogenerated|pll|clk[2] \
        }
Note: The last group has a PLL output system_pll|..|clk[2] while the input clock and other PLL outputs are in different groups. If you use PLLs, and the input clock frequency does not relate to the frequency of the PLL's outputs, you must treat the PLLs asynchronously. Typically the outputs of a PLL are related and are in the same group, but this is not a requirement.

For designs with complex clocking, creating clock groups can be an iterative process. For example, a design with two DDR3 cores and high-speed transceivers can have thirty or more clocks. In such cases, you start by adding the clocks that you manually create. Timing Analyzer assumes that the clocks not appearing in the clock groups command relate to every clock and conservatively groups the known clocks. If the design still has failing paths between unrelated clock domains, you can add the new clock domains, as necessary. In this case, a large number of the clocks are not in the set_clock_groups command, because they are either cut in the .sdc file for the IP (such as the .sdc files that the DDR3 cores generate), or they connect only to related clock domains.

For many designs, that is all that's necessary to constrain the IP.