F-Tile Ethernet Intel® FPGA Hard IPユーザーガイド

ID 683023
日付 7/08/2024
Public
ドキュメント目次

4.4.3.2. PTP RXクライアント・フロー

このセクションでは、頭字語のPLは物理レーンを表し、VLは仮想レーンを表します。

次のフローで示す擬似コードは、概念的な説明を目的としています。実際のソフトウェア・ルーチンについては、デザイン例を参照してください。
注: RX PTP Ready信号は、TXリセットがアサートされるとデアサートします。RX PTP Ready信号は、TXリセットが解除されるとアサートされます。初期化フローは、RXリンクを損失していない、もしくはTXリセットの間にRXリセットがアサートされていない場合は実行する必要はありません。
  1. 電源投入後、もしくはRXリセット後や損失RXリンクの再構築後は、RX PCSが完全にアライメントするまで待機します。
    ステータスは、次のいずれかで監視することができます。
    • 出力ポート
      o_rx_pcs_fully_alligned = 1'b1
    • Avalon®メモリーマップド・インターフェイス・レジスターを介してのポーリング (アサートされるまで)
      • 10GEから100GEでFECなしのバリアント、および25GのFECバリアント
        csr_read(phy_rxpcs_status.rx_aligned) = 1’b1
      • 50GEから400GEのFECバリアント
        csr_read(rsfec_aggr_rx_stat.not_align) = 1’b0
  2. FECバリアントの場合、RX FECコードワード位置をトランシーバーにコンフィグレーションします。
    重要: FECなしのバリアントの場合は、このステップをスキップします。
    1. 各PMAレーンのRX FECコードワード位置とFECレーンマッピングを読み出します。

      PMAレーンからFECレーンへのマッピングを特定します。

      pl_fl_map = Speed / 25 / PL
      where Speed = {25, 50, 100, 200, 400}
      
      for (fl = 0; fl < FL; fl++) {
         rx_fec_cw_pos[fl] = csr_read(rsfec_cw_pos_rx[fl][14:0])
      }
    2. パルス調整を計算し、同じトランシーバー・レーンから受信しているFECレーン間のFEC cw_pos ロールオーバーを確認します。
      for (fl = 0; fl < FL; fl++) {
         if ((rx_fec_cw_pos[fl] >= rx_fec_cw_pos[fl-(fl%pl_fl_map)])
         && (rx_fec_cw_pos[fl]–rx_fec_cw_pos[fl-(fl%pl_fl_map)] > 15'h4E20))
         {
           KR FEC Variants:
           rx_xcvr_if_pulse_adj[fl] = 15'h5280 - rx_fec_cw_pos[fl]
           
      	 KP & LL FEC Variants:
      	 rx_xcvr_if_pulse_adj[fl] = 15'h5500 - rx_fec_cw_pos[fl]
      
           rx_xcvr_if_pulse_adj_sign[fl] = 1'b1
      
      	} else if ((rx_fec_cw_pos[fl-(fl%pl_fl_map)] > rx_fec_cw_pos[fl])
      	 &&(rx_fec_cw_pos[fl - (fl%pl_fl_map)]
           - rx_fec_cw_pos[fl] > 15'h4E20)
          {     
      	 KR FEC Variants:
           rx_xcvr_if_pulse_adj[fl] = 15'h5280 + rx_fec_cw_pos[fl]
      
      	 KP & LL FEC Variants:
      	 rx_xcvr_if_pulse_adj[fl] = 15'h5500 + rx_fec_cw_pos[fl]
      
      	 rx_xcvr_if_pulse_adj_sign[fl] = 1'b0
      	} else {
           rx_xcvr_if_pulse_adj[fl] = rx_fec_cw_pos[fl]
      	 rx_xcvr_if_pulse_adj_sign[fl] = 1'b0
      	}
      }
    3. パルス調整をIPに書き込みます。
      複数のFECレーンが単一のトランシーバー内でインターリーブする場合は、インデックスが最も小さいFECレーンの調整値を選択します。PMAレーンと対応するCSRレジスター間のマッピングが正しいことを確認する必要があります。
      • FGTトランシーバーの場合
        for (pl = 0; pl < PL; pl++) {
           csr_write(ux_q_dl_ctrl_a_l<apl>.cfg_rx_lat_bit_for_async[17:0], 
                     rx_xcvr_if_pulse_adj[pl*pl_fl_map])
        }
        注: 4つのFGTクアッドがあり、それぞれに4つのaplレーンがあります。すべてのアクティブなクアッドレーンのレジスターをプログラムする必要があります。異なるFGTクアッドへのアクセスについては、ユーザーガイド を参照してください。
      • FHTトランシーバーの場合
        for (pl = 0; pl < PL; pl++) {
           csr_write(rxdl_async_l<apl>.cfg_rx_lat_bit_for_async_lane<pl>[17:0],
                     rx_xcvr_if_pulse_adj[pl*pl_fl_map])
        }
        注: このステップでは、aplとplの両方を使用します。物理レーンに関しては、PTPクライアント・フロー のセクションでクライアント・フローにおける用語の表を参照してください。
    4. パルス調整がコンフィグレーションされたことをソフトPTPに通知します。
      csr_write(ptp_rx_user_cfg_status.rx_fec_cw_pos_cfg_done, 1'b1)
  3. RXロー・オフセットデータの準備が整うまで待機します。
    ステータスは、次のいずれかで監視することができます。
    • 出力ポート
      o_rx_ptp_offset_data_valid = 1'b1
    • CSRを介したポーリング
      csr_read(ptp_status.rx_ptp_offset_data_valid) = 1’b1
  4. IPからRXロー・オフセットデータを読み出します。
    • すべてのバリアント
      rx_const_delay = csr_read(ptp_rx_lane_calc_data_constdelay[30:0])
      rx_const_delay_sign = csr_read(ptp_rx_lane_calc_data_constdelay[31])
      
      for (pl = 0; pl < PL; pl++) {
       rx_apulse_offset[pl] = csr_read(ptp_rx_lane<pl>_calc_data_offset[30:0])
       rx_apulse_offset_sign[pl] = csr_read(ptp_rx_lane<pl>_calc_data_offset[31])
       rx_apulse_wdelay[pl] = csr_read(ptp_rx_lane<pl>_calc_data_wiredelay[19:0])
       rx_apulse_time[pl]   = csr_read(ptp_rx_lane<pl>_calc_data_time[27:0])
      }
    • 10GE/25GEでFECなしのバリアント
      rx_bitslip_cnt       = csr_read(bitslip_cnt.bitslip_cnt[6:0])
      rx_dlpulse_alignment = csr_read(bitslip_cnt.dlpulse_alignment)
  5. RXリファレンス・レーンを決定します。

    単一レーンの10Gおよび25Gイーサネット・モードの場合は、ステップ5b、5c、および5dをスキップします。これらのバリアントには、次を使用します。

    rx_ref_pl = 0
    rx_ref_fl = 0
    rx_ref_vl = 0
    1. 非同期パルスを基準として、同期パルス (アライメント・マーカー (AM)) のオフセットを決定します。
      • FECバリアント
        for (fl = 0; fl < FL; fl++) {
        if (rx_xcvr_if_pulse_adj_sign[fl]){
        	 rx_spulse_offset[fl] = rx_xcvr_if_pulse_adj[fl] * UI * pl_fl_map
        	 rx_spulse_offset_sign[fl] = 1'b1;
        	} else
             {
        	 if ((rx_xcvr_if_pulse_adj[fl] 
           + rx_xcvr_if_pulse_adj[fl–(fl%pl_fl_map)][4:0]) 
           > rx_xcvr_if_pulse_adj[fl–(fl%pl_fl_map)]) 
        {
         rx_spulse_offset[fl] =
           (rx_xcvr_if_pulse_adj[fl] 
          – rx_xcvr_if_pulse_adj[fl–(fl%pl_fl_map)] 
          + rx_xcvr_if_pulse_adj[fl–(fl%pl_fl_map)][4:0]) * UI 14 * pl_fl_map
        
         rx_spulse_offset_sign[fl] = 1’b0;
        } else 
        {
         rx_spulse_offset[fl] = 
           (rx_xcvr_if_pulse_adj[fl–(fl%pl_fl_map)] 
          – rx_xcvr_if_pulse_adj[fl] 
          – rx_xcvr_if_pulse_adj[fl–(fl%pl_fl_map)][4:0]) * UI 14 * pl_fl_map
         rx_spulse_offset_sign[fl] = 1’b1;
        }
        }
        }
      • 50GE/100GEでFECなしのバリアント
        for (vl = 0; vl < VL; vl++) {
           rx_spulse_post_am[vl]     = <Refer to RX Virtual Lane Offset Calculation for No FEC Variants>
           rx_spulse_offset[vl]      = (AM_INTERVAL – rx_spulse_post_am[vl]) * UI 14
           rx_spulse_offset_sign[vl] = 1’b0;
        }
        FECなしのバリアントのRX仮想レーンオフセットの計算 で計算したオフセットでは、PCSの内部AMから各仮想レーンの同期パルスまでのビット距離を測定します。同期パルスから次のAMまでのビット距離を求めるには、AMの間隔からこの計算値を減算します。
        バリアント シミュレーションにおけるAMの間隔 ハードウェアにおけるAMの間隔
        50GE-2 2,560 * 66 = 168,960 32,768 * 66 = 2,162,688
        100GE-4 2,560 * 66 = 168,960 81,920 * 66 = 5,406,720
      • 10GE/25GEでFECなしのバリアント
        rx_spulse_offset[0] = (rx_bitslip_cnt + rx_dlpulse_alignment*33)*UI 14
        rx_spulse_offset_sign[0] = 1’b0;
    2. 非同期パルス時間のロールオーバーを検出します。

      rx_apulse_time[pl] 信号は、各物理レーンの非同期パルス時間を28ビット形式で表します。ビット [27:16] は非同期パルス時間をナノ秒 (ns) で表し、ビット [15:0] は非同期パルス時間の小数ナノ秒部 (fns) を表します。

      ロールオーバーには2つのタイプがあります。
      1. 値が28'hFFF_FFFFに達した際のビット27からビット28への自然なロールオーバー。ロールオーバー前のビット [27:24] は4'hFです。
      2. TODが10億nsまたは16進値で48'h3B9A_CA00_0000に達した際の10億ロールオーバー。ロールオーバー前のビット [27:24] は4'h9です。
      Given rx_apulse_time_max is largest rx_apulse_time from all physical lanes,
      for (pl = 0; pl < PL; pl++){
        if (rx_apulse_time_max - rx_apulse_time[pl] > 29'h01F4_0000){
          if (rx_apulse_time_max[27:24] == 4'hF) {
            rx_apulse_time[pl] = rx_apulse_time[pl] + 29'h1000_0000
          } else {
            rx_apulse_time[pl] = rx_apulse_time[pl] + 29'h0A00_0000
          }
        }
      }
    3. RX PMAパラレル・データ・インターフェイスでのRXアライメント・マーカー (AM) の実際の時間を計算します。
      // fl to pl map
      pl = fl to pl map(f) = (fl-(fl%pl_fl_map))/pl_fl_map
      // vl to pl map
      <See PL in RX Virtual Lane Offset Calculation for No FEC Variants>
      • FECバリアント
        for (fl = 0; fl < FL; fl++) {
        local_pl = fl_to_pl_map(fl)
        rx_am_actual_time[fl]= (rx_apulse_time[local_pl])
           + (rx_apulse_offset_sign[local_pl] ? 
              –rx_apulse_offset[local_pl] : rx_apulse_offset[local_pl])
              – (rx_apulse_wdelay[local_pl])
           + (rx_spulse_offset_sign[fl] ? 
              -rx_spulse_offset[fl] : rx_spulse_offset[fl]))
        }
      • FECなしのバリアント
        for (vl = 0; vl < VL; vl++) {
        local_pl = vl_to_pl_map(vl)
        rx_am_actual_time[vl] = (rx_apulse_time[local_pl]) 
           + (rx_apulse_offset_sign[local_pl] ? 
              –rx_apulse_offset[local_pl] : rx_apulse_offset[local_pl])
            – (rx_apulse_wdelay[local_pl])
           + (rx_spulse_offset_sign[vl] ? 
              -rx_spulse_offset[vl] : rx_spulse_offset[vl])
        }
    4. RXリファレンス・レーンを決定します。
      • FECバリアント
        rx_am_actual_time[rx_ref_fl] is maximum value out of rx_am_actual_time[FL-1:0]
        rx_ref_pl = fl_to_pl_map(rx_ref_fl)
        
        where rx_am_actual_time[fl] is max(rx_am_actual_time[FL-1:0])
      • FECなしのバリアント
        rx_am_actual_time[rx_ref_vl] is maximum value out of rx_am_actual_time[VL-1:0]
        rx_ref_pl = vl_to_pl_map(rx_ref_vl)
        
        where rx_am_actual_time[vl] is max(rx_am_actual_time[VL-1:0])
  6. RXオフセットを計算します。
    1. RX TAM調整を計算します。
      • FECバリアント
        rx_tam_adjust_sim = 
           (rx_const_delay_sign ? –rx_const_delay : rx_const_delay) 
         + (rx_apulse_offset_sign[rx_ref_pl] ? 
             –rx_apulse_offset[rx_ref_pl] : rx_apulse_offset[rx_ref_pl]
         – (rx_apulse_wdelay[rx_ref_pl])
         + (rx_spulse_offset_sign[rx_ref_fl] ? 
             -rx_spulse_offset[rx_ref_fl] : rx_spulse_offset[rx_ref_fl])
      • FECなしのバリアント
        rx_tam_adjust_sim = 
           (rx_const_delay_sign ? –rx_const_delay : rx_const_delay) 
         + (rx_apulse_offset_sign[rx_ref_pl] ? 
             –rx_apulse_offset[rx_ref_pl] : rx_apulse_offset[rx_ref_pl])
         – (rx_apulse_wdelay[rx_ref_pl])
         + (rx_spulse_offset_sign[rx_ref_vl] ? 
            -rx_spulse_offset[rx_ref_vl] : rx_spulse_offset[rx_ref_vl])
      ハードウェアの実行でPTPの Timestamp accuracy modeAdvanced に設定している場合
      rx_tam_adjust = (rx_tam_adjust_sim) 
       + (rx_routing_adj_sign[rx_ref_pl] ? – rx_routing_adj[rx_ref_pl] 
                                           : rx_routing_adj[rx_ref_pl])
      配線遅延調整の情報に関しては、Advancedタイムスタンプ精度モードにおけるルーティング遅延調整 を参照してください。
      他のすべてのケース
      rx_tam_adjust = rx_tam_adjust_sim

      TAM調整値を32ビットの2の補数に変換します。

      rx_tam_adjust_2c = rx_tam_adjust
      where rx_tam_adjust is a 32-bit 2's complement number
    2. RX追加レイテンシーを計算します。
      RX PMA遅延の単位をUIからナノ秒に変換します。
      rx_pma_delay_ns = rx_pma_delay_ui * UI 14
      RXの追加レイテンシーは負の調整です。負の調整を示すには、最上位レジスタービットを1に設定します。追加レイテンシーをすべて合計します。
      rx_extra_latency[31] = 1
      rx_extra_latency[30:0] = rx_pma_delay_ns + rx_external_phy_delay
    3. RX仮想レーンのオフセットを計算します。
      重要: このステップは、10Gおよび25Gのイーサネット・データレートには適用されません。これらのレートでは、このステップをスキップします。

      決定したリファレンス仮想レーンを使用し、仮想レーンの順序とオフセット値 の説明に従いRX仮想レーンのオフセット値を割り当てます。

      • FEC KP-FECまたはFEC LL-FECバリアント
        for (vl = 0; vl < VL; vl++) {
           rx_vl_offset[vl] = [vl - (vl % PL)] / PL * 68 * UI 14
        }
      • FEC KR-FECバリアント
        for (vl = 0; vl < VL; vl++) {
           rx_vl_offset[vl] = [vl - (vl % PL)] / PL * 66 * UI 14
        }
      • FECなし100Gイーサネット・レート・バリアント
        for (vl = 0; vl < VL; vl++) {
           rx_vl_offset[vl] = 2 * UI 14
        }
      • FECなし50Gイーサネット・レート・バリアント
        for (vl = 0; vl < VL; vl++) {
           rx_vl_offset[vl] = 0.5 * UI 14
        }
  7. 決定したRXリファレンス・レーンをIPに書き込みます。
    重要: このステップは、10Gおよび25Gのイーサネット・データレートには適用されません。これらのレートでは、このステップをスキップします。
    csr_write(ptp_ref_lane.rx_ref_lane, rx_ref_pl)
  8. 計算したRXオフセットをIPに書き込みます。
    1. RX仮想レーンのオフセットを書き込みます。
      重要: このステップは、10Gおよび25Gのイーサネット・データレートには適用されません。これらのレートでは、このステップをスキップします。
      for (vl = 0; vl < VL; vl++) {
         csr_write(rx_ptp_vl_offset_<vl>, rx_vl_offset[vl])
      }
    2. RX追加レイテンシーを書き込みます。
      csr_write(rx_ptp_extra_latency, rx_extra_latency)
    3. RX TAM調整を書き込みます。
      csr_write(ptp_rx_tam_adjust, rx_tam_adjust_2c)
  9. ソフトPTPにRXクライアント・フロー・コンフィグレーションが完了したことを通知します。
    csr_write(ptp_rx_user_cfg_status.rx_user_cfg_done, 1'b1)
  10. UI値の測定を続けます。RX UI調整 のセクションに示されているステップ1から7に従ってください。

    シミュレーションまたはハードウェアを0ppmの設定で実行する場合は、この測定をスキップし、UI調整 で定義されている0ppmのUI値をプログラムします。

  11. RX PTPの準備ができるまで待機します。
    ステータスは、次のいずれかで監視することができます。
    • 出力ポート
      o_rx_ptp_ready = 1'b1
    • CSRを介したポーリング
      csr_read(ptp_status.rx_ptp_ready) = 1’b1
  12. RX PTPが起動して動作します。
    1. RX UI値を調整します。

      RX UIの調整を定期的に行い、システムの基準となるTime-of-Dayから時間カウンターがドリフトしないようにします。RX UI調整 で示されているステップ1から8に従ってください。

      注: シミュレーションでは、UI測定には長い時間がかかります。したがって、インテルでは、シミュレーションでこのステップをスキップし、0ppmの値をプログラムすることを推奨しています。詳細は、UI値とPMA遅延 を参照してください。
14 UIの形式は他の変数の形式とは異なります。UIでは、{4ビットns、28ビットns小数部} の形式を使用します。このフローで定義される他の変数は、{N ビットns、16ビットns小数部} の形式を使用します。この N は、計算の最大値を格納する最大数です。計算にUI形式を使用する場合は、結果の小数ナノ秒部 (fns) を16ビットの形式に変換する必要があります。