Article ID: 000076357 Content Type: Troubleshooting Last Reviewed: 02/01/2023

Why is the derived tx_bonding_clocks[0] frequency of Arria®10 PCIe Hard IP Gen3 wrong?

Environment

  • Intel® Quartus® Prime Pro Edition
  • Intel® Arria® 10 Cyclone® 10 Hard IP for PCI Express
  • BUILT IN - ARTICLE INTRO SECOND COMPONENT
    Description

    Due to a problem with Intel® Quartus® Prime Software 16.1, the generated clock tx_bonding_clocks[0] of Arria 10 PCIe Hard IP Gen3 design is wrong. 

    The reason is that the altera_pcie_express.sdc has some missing constraints.

     

    Resolution

    To work around this problem, please add the following sdc commands to the end of altera_pcie_express.sdc.

    proc skp_sdc_puts {msg {channelId stdout}} {
     puts $channelId "altera_pcie_a10_skp.sdc >> $msg"
    }

    proc parent_of_clock {clock_name {MAX_ATTEMPTS 100}} {
       skp_sdc_puts "***********************************************************************************************"
       skp_sdc_puts "************************ Searching for the hierarchy of $clock_name ***************************"
       skp_sdc_puts "***********************************************************************************************"

       set attempts 0
       set parent {}

       while { $attempts < $MAX_ATTEMPTS } {
        skp_sdc_puts "Searching for clocks that match \"$parent$clock_name\"..."

          set matched_clock_collection [get_clocks -nowarn $parent$clock_name]                   ;# Try this wildcard.
        set num_matched_clocks [get_collection_size $matched_clock_collection]

        if { $num_matched_clocks == 1 } {                               ;# This is the hierarchy we are looking for.
         # Find out the full name of the parent.
         set parent [join [lrange [split [query_collection $matched_clock_collection] {|}] 0 {end-1}] {|}]

             skp_sdc_puts "Parent found : $parent"
             skp_sdc_puts "***********************************************************************************************"
             skp_sdc_puts "************************** Finish searching with result : $parent *****************************"
             skp_sdc_puts "***********************************************************************************************"

             return $parent
        } elseif { $num_matched_clocks > 1 } {       ;# Multiple clocks with the same name - this should not happen.
         skp_sdc_puts "Error: Multiple clocks match $parent$clock_name !" {stderr}
         skp_sdc_puts "Error: Matched clocks are:" {stderr}
         skp_sdc_puts "Error: [query_collection $matched_clock_collection -report_format]" {stderr}
             skp_sdc_puts "***********************************************************************************************"
             skp_sdc_puts "******************************* Finish searching with error ***********************************"
             skp_sdc_puts "***********************************************************************************************"

             return
        } else {                                                                    ;# Go up one level of hierarchy.
         append parent {*|}
         incr attempts
        }
       }

       skp_sdc_puts "Error: Unable to find the parent of $clock_name in $MAX_ATTEMPTS attempts!"
       skp_sdc_puts "***********************************************************************************************"
       skp_sdc_puts "******************************* Finish searching with error ***********************************"
       skp_sdc_puts "***********************************************************************************************"

       return
    }


    derive_pll_clocks -create_base_clocks     ;# derive_pll_clocks needs to be called before calling parent_of_clock
    derive_clock_uncertainty                  ;# in order to generate proper hierarchy.


    set prefix [parent_of_clock {tx_serial_clk}]


    for {set i 0} {$i != 8} {incr i} {
       create_generated_clock -divide_by 1 \
          -source     "$prefix|altpcie_a10_hip_pipen1b|g_xcvr.altpcie_a10_hip_pllnphy|g_xcvr.g_phy_g3x8.phy_g3x8|phy_g3x8|g_xcvr_native_insts[$i].twentynm_xcvr_native_inst|twentynm_xcvr_native_inst|inst_twentynm_pcs|gen_twentynm_hssi_8g_rx_pcs.inst_twentynm_hssi_8g_rx_pcs|byte_deserializer_pcs_clk_div_by_2_txclk_reg" \
          -name       "$prefix|rx_pcs_clk_div_by_4[$i]" \
                      "$prefix|altpcie_a10_hip_pipen1b|g_xcvr.altpcie_a10_hip_pllnphy|g_xcvr.g_phy_g3x8.phy_g3x8|phy_g3x8|g_xcvr_native_insts[$i].twentynm_xcvr_native_inst|twentynm_xcvr_native_inst|inst_twentynm_pcs|gen_twentynm_hssi_8g_rx_pcs.inst_twentynm_hssi_8g_rx_pcs|sta_rx_clk2_by2_1" ;# target

       create_generated_clock -multiply_by 1 -divide_by 1 \
          -source     "$prefix|altpcie_a10_hip_pipen1b|g_xcvr.altpcie_a10_hip_pllnphy|g_xcvr.g_phy_g3x8.phy_g3x8|phy_g3x8|g_xcvr_native_insts[$i].twentynm_xcvr_native_inst|twentynm_xcvr_native_inst|inst_twentynm_pcs|gen_twentynm_hssi_8g_tx_pcs.inst_twentynm_hssi_8g_tx_pcs|byte_serializer_pcs_clk_div_by_2_reg" \
          -name       "$prefix|tx_pcs_clk_div_by_4[$i]" \
                      "$prefix|altpcie_a10_hip_pipen1b|g_xcvr.altpcie_a10_hip_pllnphy|g_xcvr.g_phy_g3x8.phy_g3x8|phy_g3x8|g_xcvr_native_insts[$i].twentynm_xcvr_native_inst|twentynm_xcvr_native_inst|inst_twentynm_pcs|gen_twentynm_hssi_8g_tx_pcs.inst_twentynm_hssi_8g_tx_pcs|sta_tx_clk2_by2_1" ;# target
    }

    remove_clock      "$prefix|tx_bonding_clocks[0]"
    create_generated_clock -multiply_by 1 -divide_by 10 \
       -source        "$prefix|altpcie_a10_hip_pipen1b|g_xcvr.altpcie_a10_hip_pllnphy|g_pll.g_pll_g3n.lcpll_g3xn|lcpll_g3xn|a10_xcvr_atx_pll_inst|twentynm_hssi_pma_cgb_master_inst|clk_fpll_b" \
       -master_clock  "$prefix|tx_serial_clk" \
       -name          "$prefix|tx_bonding_clocks[0]" \
                      "$prefix|altpcie_a10_hip_pipen1b|g_xcvr.altpcie_a10_hip_pllnphy|g_pll.g_pll_g3n.lcpll_g3xn|lcpll_g3xn|a10_xcvr_atx_pll_inst|twentynm_hssi_pma_cgb_master_inst|cpulse_out_bus[0]"

    set_multicycle_path -setup -through [get_pins -compatibility_mode {*pld_rx_data*}] 0

    set rx_clkouts [list]
    for {set i 0} {$i != 8} {incr i} {
     remove_clock      "$prefix|g_xcvr_native_insts[$i]|rx_clk"
     remove_clock      "$prefix|g_xcvr_native_insts[$i]|rx_clkout"
     
     create_generated_clock -multiply_by 1 \
          -source        "$prefix|altpcie_a10_hip_pipen1b|g_xcvr.altpcie_a10_hip_pllnphy|g_xcvr.g_phy_g3x8.phy_g3x8|phy_g3x8|g_xcvr_native_insts[$i].twentynm_xcvr_native_inst|twentynm_xcvr_native_inst|inst_twentynm_pcs|gen_twentynm_hssi_8g_rx_pcs.inst_twentynm_hssi_8g_rx_pcs|byte_deserializer_pcs_clk_div_by_4_txclk_reg" \
          -master_clock  "$prefix|tx_bonding_clocks[0]" \
          -name          "$prefix|g_xcvr_native_insts[$i]|rx_clk" \
                         "$prefix|altpcie_a10_hip_pipen1b|g_xcvr.altpcie_a10_hip_pllnphy|g_xcvr.g_phy_g3x8.phy_g3x8|phy_g3x8|g_xcvr_native_insts[$i].twentynm_xcvr_native_inst|twentynm_xcvr_native_inst|inst_twentynm_pcs|gen_twentynm_hssi_8g_rx_pcs.inst_twentynm_hssi_8g_rx_pcs|sta_rx_clk2_by4_1" ;# target

     create_generated_clock -multiply_by 1 \
          -source        "$prefix|altpcie_a10_hip_pipen1b|g_xcvr.altpcie_a10_hip_pllnphy|g_xcvr.g_phy_g3x8.phy_g3x8|phy_g3x8|g_xcvr_native_insts[$i].twentynm_xcvr_native_inst|twentynm_xcvr_native_inst|inst_twentynm_pcs|gen_twentynm_hssi_8g_rx_pcs.inst_twentynm_hssi_8g_rx_pcs|byte_deserializer_pld_clk_div_by_4_txclk_reg" \
          -master_clock  "$prefix|tx_bonding_clocks[0]" \
          -name          "$prefix|g_xcvr_native_insts[$i]|rx_clkout" \
                         "$prefix|altpcie_a10_hip_pipen1b|g_xcvr.altpcie_a10_hip_pllnphy|g_xcvr.g_phy_g3x8.phy_g3x8|phy_g3x8|g_xcvr_native_insts[$i].twentynm_xcvr_native_inst|twentynm_xcvr_native_inst|inst_twentynm_pcs|gen_twentynm_hssi_8g_rx_pcs.inst_twentynm_hssi_8g_rx_pcs|sta_rx_clk2_by4_1_out"

     set_clock_groups -exclusive \
          -group "$prefix|tx_bonding_clocks[0]" \
          -group "$prefix|g_xcvr_native_insts[$i]|rx_clkout"
       set_clock_groups -exclusive \
          -group "$prefix|tx_bonding_clocks[0]" \
          -group "$prefix|rx_pcs_clk_div_by_4[$i]"
    }

    This issue is fixed starting with the Intel® Quartus® Prime Standard Edition Software version 17.1. 

    Related Products

    This article applies to 2 products

    Intel® Arria® 10 GT FPGA
    Intel® Arria® 10 GX FPGA