Article ID: 000092741 Content Type: Errata Last Reviewed: 08/15/2023

Why is my calculated value for rx_tam_adjust incorrect when using the scripts found in the design examples for multilane PTP variants of the F-tile Ethernet Intel® FPGA Hard IP?

Environment

  • Intel® Quartus® Prime Pro Edition
  • BUILT IN - ARTICLE INTRO SECOND COMPONENT
    Description

    Due to a problem in the Intel® Quartus® Prime Pro Edition Software version 22.3, the ptp_fw.tcl” script provided in the design examples for multilane PTP variants of the F-tile Ethernet Intel® FPGA Hard IP might yield incorrect rx_tam_adjust values.

    Resolution

    To work around this problem, perform the following steps:

    1. Open the PTP firmware script located at <generated example design folder>/hardware_test_design/hwtest/altera/ptp/ptp_fw.tcl
    2. Find and replace the following lines of code:
    FROMTO

    # b) Calculate pulse adjustment

    for {set fl 0} {$fl < $::FL} {incr fl} {
        set rx_xcvr_if_pulse_adj($fl) [format 0x%X $rx_fec_cw_pos_fl($fl)]
    }

    # b) Calculate pulse adjustment and check for FEC's cw_pos rollover between FEC lane received from the same transceiver lane

            for {set fl 0} {$fl < $::FL} {incr fl} {
                set fl_minus [expr $fl - [expr $fl % $::PL_FL_MAP]]
                set cond1a [expr ($rx_fec_cw_pos_fl($fl) >= $rx_fec_cw_pos_fl($fl_minus))]
                set cond1b [expr (($rx_fec_cw_pos_fl($fl) - $rx_fec_cw_pos_fl($fl_minus)) > 0x4E20)] 

                set cond2a [expr ($rx_fec_cw_pos_fl($fl_minus) > $rx_fec_cw_pos_fl($fl))]
                set cond2b [expr (($rx_fec_cw_pos_fl($fl_minus) - $rx_fec_cw_pos_fl($fl)) > 0x4E20)]

                if {$cond1a && $cond1b} {
                    if {$::FEC == 2} {
                        # KRFEC
                        set rx_xcvr_if_pulse_adj($fl) [expr 0x5280 - $rx_fec_cw_pos_fl($fl)]
                    } elseif {($::FEC == 3) || ($::FEC == 4)} {
                        # KP/LLFEC
                        set rx_xcvr_if_pulse_adj($fl) [expr 0x5500 - $rx_fec_cw_pos_fl($fl)]
                    }
                    set rx_xcvr_if_pulse_adj_sign($fl) 0x1
                } elseif {$cond2a && $cond2b} {
                    if {$::FEC == 2} {
                        # KRFEC
                        set rx_xcvr_if_pulse_adj($fl) [expr 0x5280 + $rx_fec_cw_pos_fl($fl)]
                    } elseif {($::FEC == 3) || ($::FEC == 4)} {
                        # KP/LLFEC
                        set rx_xcvr_if_pulse_adj($fl) [expr 0x5500 + $rx_fec_cw_pos_fl($fl)]
                    }
                    set rx_xcvr_if_pulse_adj_sign($fl) 0x0
                } else {
                     set rx_xcvr_if_pulse_adj($fl) [format 0x%X $rx_fec_cw_pos_fl($fl)]
                    set rx_xcvr_if_pulse_adj_sign($fl) 0x0
                }
            }

    return [array get rx_xcvr_if_pulse_adj]

    set l_rx_xcvr_if_pulse_adj [array get rx_xcvr_if_pulse_adj]
    set l_rx_xcvr_if_pulse_adj_sign [array get rx_xcvr_if_pulse_adj_sign] 

    return [list $l_rx_xcvr_if_pulse_adj $l_rx_xcvr_if_pulse_adj_sign]

    proc determine_rx_ref_lane {lst_rx_xcvr_if_pulse_adj VL ui rx_pcs_bitslip_cnt rx_pcs_dlpulse_aligned l_rx_apulse_offset l_rx_apulse_offset_sign l_rx_apulse_wdelay l_rx_apulse_time ip_inst_base_addr} {

        #

        # arguments:

        # returns: 'array-lists' for rx spulse offset (+sign bit). rx ref pl/vl/fl

     

        array set rx_apulse_offset      $l_rx_apulse_offset

        array set rx_apulse_offset_sign $l_rx_apulse_offset_sign

        array set rx_apulse_wdelay      $l_rx_apulse_wdelay

        array set rx_apulse_time        $l_rx_apulse_time

        array set rx_xcvr_if_pulse_adj  $lst_rx_xcvr_if_pulse_adj

     

        print_info_time "Determine RX reference lane"

        # a) Determine sync pulse (Alignment Marker) offsets with reference to async pulse

        if {$::FEC > 0} {

            print_out "\tVariant                    : FEC>0"

            for {set fl 0} {$fl < $::FL} {incr fl} {

                set fl_minus [expr $fl - [expr $fl % $::PL_FL_MAP]]

                set val0 [format 0x%X [expr $rx_xcvr_if_pulse_adj($fl_minus) & 0x0000001F]]

                set val1 [format 0x%X [expr $rx_xcvr_if_pulse_adj($fl) + $val0]]

     

                if {$val1 > $rx_xcvr_if_pulse_adj($fl_minus)} {

                    set rx_spulse_offset_sign($fl) 0

                    set rx_spulse_offset_0      [format 0x%lX [expr [expr ($rx_xcvr_if_pulse_adj($fl) - $rx_xcvr_if_pulse_adj($fl_minus)) + $val0] * $ui * $::PL_FL_MAP]]

                    set rx_spulse_offset_1      [format 0x%lX [expr $rx_spulse_offset_0 & 0x7FFFFFFFFFF]] ; # 43'rx_spulse_offset_0

                    set rx_spulse_offset($fl)   [format 0x%X [expr $rx_spulse_offset_1 >> [expr 28 - 16]]]

                } else {

                    set rx_spulse_offset_sign($fl) 1

                    set rx_spulse_offset_0      [format 0x%lX [expr [expr ($rx_xcvr_if_pulse_adj($fl_minus) - $rx_xcvr_if_pulse_adj($fl)) - $val0] * $ui * $::PL_FL_MAP]]

                    set rx_spulse_offset_1      [format 0x%lX [expr $rx_spulse_offset_0 & 0x7FFFFFFFFFF]] ; # 43'rx_spulse_offset_0

                    set rx_spulse_offset($fl)   [format 0x%X [expr $rx_spulse_offset_1 >> [expr 28 - 16]]]

                }

    proc determine_rx_ref_lane {lst_rx_xcvr_if_pulse_adj lst_rx_xcvr_if_pulse_adj_sign VL ui rx_pcs_bitslip_cnt rx_pcs_dlpulse_aligned l_rx_apulse_offset l_rx_apulse_offset_sign l_rx_apulse_wdelay l_rx_apulse_time ip_inst_base_addr} {

        #

        # arguments:

        # returns: 'array-lists' for rx spulse offset (+sign bit). rx ref pl/vl/fl

     

        array set rx_apulse_offset      $l_rx_apulse_offset

        array set rx_apulse_offset_sign $l_rx_apulse_offset_sign

        array set rx_apulse_wdelay      $l_rx_apulse_wdelay

        array set rx_apulse_time        $l_rx_apulse_time

        array set rx_xcvr_if_pulse_adj  $lst_rx_xcvr_if_pulse_adj

        array set rx_xcvr_if_pulse_adj_sign  $lst_rx_xcvr_if_pulse_adj_sign

     

        print_info_time "Determine RX reference lane"

        # a) Determine sync pulse (Alignment Marker) offsets with reference to async pulse

        if {$::FEC > 0} {

            print_out "\tVariant                    : FEC>0"

            for {set fl 0} {$fl < $::FL} {incr fl} {

                set fl_minus [expr $fl - [expr $fl % $::PL_FL_MAP]]

                set val0 [format 0x%X [expr $rx_xcvr_if_pulse_adj($fl_minus) & 0x0000001F]]

                set val1 [format 0x%X [expr $rx_xcvr_if_pulse_adj($fl) + $val0]]

     

                if {$rx_xcvr_if_pulse_adj_sign($fl) == 1} {

                    set rx_spulse_offset_sign($fl) 1

                    set rx_spulse_offset_0      [format 0x%lX [expr $rx_xcvr_if_pulse_adj($fl) * $ui * $::PL_FL_MAP]]

                    set rx_spulse_offset_1      [format 0x%lX [expr $rx_spulse_offset_0 & 0x7FFFFFFFFFF]] ; # 43'rx_spulse_offset_0

                    set rx_spulse_offset($fl)   [format 0x%X [expr $rx_spulse_offset_1 >> [expr 28 - 16]]]

                } else {

                if {$val1 > $rx_xcvr_if_pulse_adj($fl_minus)} {

                    set rx_spulse_offset_sign($fl) 0

                    set rx_spulse_offset_0      [format 0x%lX [expr [expr ($rx_xcvr_if_pulse_adj($fl) - $rx_xcvr_if_pulse_adj($fl_minus)) + $val0] * $ui * $::PL_FL_MAP]]

                    set rx_spulse_offset_1      [format 0x%lX [expr $rx_spulse_offset_0 & 0x7FFFFFFFFFF]] ; # 43'rx_spulse_offset_0

                    set rx_spulse_offset($fl)   [format 0x%X [expr $rx_spulse_offset_1 >> [expr 28 - 16]]]

                } else {

                    set rx_spulse_offset_sign($fl) 1

                    set rx_spulse_offset_0      [format 0x%lX [expr [expr ($rx_xcvr_if_pulse_adj($fl_minus) - $rx_xcvr_if_pulse_adj($fl)) - $val0] * $ui * $::PL_FL_MAP]]

                    set rx_spulse_offset_1      [format 0x%lX [expr $rx_spulse_offset_0 & 0x7FFFFFFFFFF]] ; # 43'rx_spulse_offset_0

                    set rx_spulse_offset($fl)   [format 0x%X [expr $rx_spulse_offset_1 >> [expr 28 - 16]]]

                }

                }

    array set rx_xcvr_if_pulse_adj [configure_rx_fec_cw_pos $inst_num $init_pl]

    if {$::FEC > 0} {

        set int_list [configure_rx_fec_cw_pos $inst_num $init_pl]

        lassign $int_list l_rx_xcvr_if_pulse_adj l_rx_xcvr_if_pulse_adj_sign

     

        array set rx_xcvr_if_pulse_adj $l_rx_xcvr_if_pulse_adj

        array set rx_xcvr_if_pulse_adj_sign $l_rx_xcvr_if_pulse_adj_sign

        if {$::debug} {

            for {set fl 0} {$fl < $::FL} {incr fl} {

                print_out "\trx_xcvr_if_pulse_adj($fl)        : [format 0x%08X $rx_xcvr_if_pulse_adj($fl)]"

                print_out "\trx_xcvr_if_pulse_adj_sign($fl)   : [format 0x%08X $rx_xcvr_if_pulse_adj_sign($fl)]"

            }

        }

    # Step 3: Determine RX reference lane

    set int_list [determine_rx_ref_lane [array get rx_xcvr_if_pulse_adj]\

                    $VL\

    # Step 3: Determine RX reference lane

    set int_list [determine_rx_ref_lane [array get rx_xcvr_if_pulse_adj]\

                    [array get rx_xcvr_if_pulse_adj_sign]\

                    $VL

    1. Save the file

    This problem is fixed beginning with the Intel® Quartus® Prime Pro Edition Software version 22.4.

    Related Products

    This article applies to 2 products

    Intel Agilex® 7 FPGAs and SoC FPGAs F-Series
    Intel Agilex® 7 FPGAs and SoC FPGAs I-Series