Fタイル・イーサネット・インテル® FPGAハードIPユーザーガイド

ID 683023
日付 3/28/2022
Public
ドキュメント目次

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

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

次のフローで示している擬似コードは、概念的な説明を目的としています。決定的なソフトウェア・ルーチンについては、デザイン例を参照してください。

  1. 電源投入または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. パルス調整を計算します。
      for (fl = 0; fl < FL; fl++) {
         rx_xcvr_if_pulse_adj[fl] = rx_fec_cw_pos[fl]
      } 
    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. RXロー・オフセット・データをIPから読み出します。
    • すべてのバリアントで次を実行します。
      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. 同期パルス(Alignment Marker (AM)) オフセットを決定します。 このとき、非同期パルスを参照します。
      • FECバリアントの場合は、次を実行します。
        for (fl = 0; fl < FL; fl++) {
        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]) * UI13 * 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]) * UI13 * 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]) * UI13
           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)*UI13
        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アライメント・マーカーの実際の時間を計算します。
      // 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モードAdvancedに設定して使用する場合は、次を実行します。
      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 Timestamp Accuracyモードの配線遅延調整 を参照してください。
      他のすべての場合は、次を実行します。
      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 * UI13  
      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 * UI13
        } 
      • FEC KR-FECバリアントの場合は、次を実行します。
        for (vl = 0; vl < VL; vl++) {
           rx_vl_offset[vl] = [vl - (vl % PL)] / PL * 66 * UI13
        } 
      • FECなしの100Gイーサネット・レート・バリアントの場合は、次を実行します。
        for (vl = 0; vl < VL; vl++) {
           rx_vl_offset[vl] = 2 * UI13
        } 
      • FECなし50Gイーサネット・レート・バリアントの場合は、次を実行します。
        for (vl = 0; vl < VL; vl++) {
           rx_vl_offset[vl] = 0.5 * UI13
        } 
  7. 決定したRXリファレンス・レーンをIPに書き込みます。
    重要: この手順は、10Gおよび25Gイーサネット・データレートには適用されません。指定したレートでは、このステップをスキップしてください。
    csr_write(ptp_ref_lane.rx_ref_lane, rx_ref_pl) 
  8. 計算したRXオフセットをIPに書き込みます。
    重要: この手順は、10Gおよび25Gイーサネット・データレートには適用されません。このステップは、指定したレートではスキップしてください。
    1. TX仮想レーンオフセットを書き込みます。
      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. TX TAM調整を書き込みます。
      csr_write(ptp_rx_tam_adjust, rx_tam_adjust_2c) 
  9. フロー・コンフィグレーションを使用するソフトPTPに完了したことを通知します。
    csr_write(ptp_rx_user_cfg_status.rx_user_cfg_done, 1'b1) 
  10. UI値の測定を継続します。RX UI調整 のセクションに記載されている手順に従ってください。

    シミュレーションまたはハードウェア実行に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の調整を時々行って、タイムカウンターがシステムのゴールデンタイムからドリフトすることを防ぎます。RX UI調整 の説明にある手順に従ってください。

      注: UI測定は、シミュレーションでは長時間かかるプロセスです。したがって、シミュレーションの場合は、このステップをスキップして、0ppmの値をプログラムすることをお勧めします。詳細については、UI値とPMA遅延 を参照してください。
13 UIフォーマットは、他の変数のフォーマットとは異なります。UIは、{4ビットns、28ビット小数ns} フォーマットを使用します。このフローで定義されている他の変数では、{N-ビットns、16ビット小数ns} フォーマットを使用します。ここで N は、計算の最大値を格納する最大数です。UIフォーマットを使用して計算する場合は、結果を16ビット小数nsフォーマットに変換してください。