E-Tile Hard IP User Guide: E-Tile Hard IP for Ethernet and E-Tile CPRI PHY Intel® FPGA IPs

ID 683468
Date 7/23/2024
Public
Document Table of Contents

2.9.2.10. 100G PTP RX User Flow

In this section, the acronym PL and VL stands for Physical Lane and Virtual Lane respectively.
  1. Wait until RX raw offset data are ready.
    The status could be monitored via:
    • Polling via CSR:
      csr_read (mlptp_status[1]) = 1’b1
  2. Read RX raw offset data from IP:
    • All variants:
      rx_const_delay = csr_read (mlptp_rx_const_delay[30:0])
      rx_const_delay_sign = csr_read (mlptp_rx_const_delay[31])
      
      for (pl = 0; pl < PL; pl++) {
      rx_apulse_offset[pl] = csr_read (mlptp_rx_l<3-0>_offset[30:0])
      rx_apulse_offset_sign[pl = csr_read (mlptp_rx_l<3-0>_offset[31])
      rx_apulse_wdelay[pl] = csr_read (mlptp_rx_l<3-0>_wire_dly[19:0])
      rx_apulse_time[pl] = csr_read (mlptp_rx_l<3-0>_time[19:0])
      }
      
    • FEC variants:
      rx_fec_cw_pos_lane0 = csr_read (Hard FEC, RSFEC_CW_POS_RX[0][14:0])
      
      for (pl = 0; pl < PL; pl++) {
      	rx_fec_ln_mapping[pl] = csr_read (Hard FEC, RSFEC_LN_MAPPING_RX[pl][6:0])
      	rx_fec_ln_skew[pl] = csr_read (Hard FEC, RSFEC_LN_SKEW_RX[pl][6:0])
      }
      
      rx_fec_lane0_pl_map = pl, where rx_fec_ln_mapping[pl] = 0
      

      For more information on RS-FEC registers, refer to the E-Tile Transceiver PHY User Guide.

  3. Determine RX reference lane:
    1. Determine sync pulse (Alignment Marker) offsets with reference to async pulse:
      • FEC variants:
        for (pl = 0; pl < PL; pl++) {
        	rx_spulse_offset[pl] = ((rx_fec_ln_skew[rx_fec_lane0_pl_map] - rx_fec_ln_skew[pl]) * 80 + rx_fec_cw_pos_lane0[4:0]) * UI
        }
        
      • No FEC variants:
        for (vl = 0; vl < VL; vl++) {
        	rx_spulse_offset[vl] = < Refer to section: 100G RX Virtual Lane Offset Calculation for No FEC Variants >
    2. Detect if asynchronous pulse time rollover, and adjust accordingly:
      Expectation: Skew between async pulses < 256ns
      
      rx_ap_time_rollover = ((max(rx_apulse_time[PL-1:0]) – min(rx_apulse_time[PL-1:0])) > 256ns) ? 1 : 0
      rx_ap_time_seconds_rollover = (rx_ap_time_rollover && (29’h10000000 – max(rx_apulse_time[PL-1:0])) > 256ns) ? 1 : 0
      for (pl = 0; pl < PL; pl++) {
      rx_apulse_time_adj[pl] = rx_ap_time_seconds_rollover && (rx_apulse_time[pl] < 256ns) ? rx_apulse_time[pl] + {13’h0A00, 16’h0000} : rx_ap_time_rollover && (rx_apulse_time[pl] < 256ns) ? rx_apulse_time[pl] + {13’h1000, 16’h0000} : rx_apulse_time[pl]
      }
      
    3. Calculate the actual time of RX Alignment Marker at RX PMA parallel data interface:
      • FEC variants: Skip this step.
      • No FEC variants:
        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[vl])
        }
        
    4. Determine RX reference lane:
      • FEC variants:
        rx_ref_pl = pl
        
        where rx_fec_ln_skew[pl] is min(rx_fec_ln_skew[PL-1:0])
      • No FEC variants:
        rx_ref_vl = vl
        
        where rx_am_actual_time[vl] is max(rx_am_actual_time[VL-1:0])
        
        rx_ref_pl = vl_to_pl_map(rx_ref_vl)
  4. Calculate RX offsets:
    1. Calculate RX TAM adjust:
      • FEC variants:
        rx_tam_adjust = (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[rx_ref_pl])
        
      • No FEC variants:
        rx_tam_adjust = (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[rx_ref_vl])
        
    2. Calculate RX extra latency:
      Convert unit of RX PMA delay from UI to nanoseconds:
      rx_pma_delay_ns = rx_pma_delay_ui * UI
      Total up all extra latency together:
      rx_extra_latency = –rx_pma_delay_ns – rx_external_phy_delay + rx_tam_adjust
    3. Calculate RX virtual lane offsets:
      for (vl = 0; vl < VL; vl++) {
      	if (remote_vl(vl) == 0 to 3)	
      		 rx_vl_offset[vl]  = (2 – 330) * UI
      	else
      		 rx_vl_offset[vl]  = 2 * UI
      }
  5. Write the determined RX reference lane into IP:
    csr_write (mlptp_rx_ref_lane, rx_ref_pl)
  6. Write the calculated RX offsets to IP:
    1. Write RX virtual lane offsets:
      for (vl = 0; vl < VL; vl++) {
      	csr_write (vl<19-0>_offset_cfg_<0/1>,  rx_vl_offset[vl] )
      }
      
    2. Write RX extra latency:
      csr_write (rx_ptp_extra_latency, rx_extra_latency)
  7. UI value measurement. Follow the steps mentioned in section 100G UI Adjustment.
    Note: As UI measurement is a long process in simulation. Therefore, for simulation, Altera recommends to skip this step and program 0 ppm value.
  8. Notify soft PTP that user flow configuration is completed:
    csr_write (mlptp_rx_user_cfg, 1’b1)
  9. Wait until RX PTP is ready.
    The status could be monitored via:
    • Output port:
      o_rx_ptp_ready = 1’b1
      or
    • Polling via CSR:
      csr_read (mlptp_status[3]) = 1’b1
  10. RX PTP is up and running.
    1. Adjust RX UI value. You must perform RX UI adjustment of IP from time to time to prevent time counter drift from golden time-of-day in the system. Follow the steps mentioned in section 100G UI Adjustment.
      Note: UI measurement is a long process in simulation. Therefore, for simulation, Altera recommends to skip this step and program 0 ppm value.