PTP Timestamping

Summary

The PTP engine maintains a high-resolution free-running clock synchronized to a PTP grandmaster via ARM software corrections. It provides IEEE 1588 PTP time output (seconds + nanoseconds) and derives 90 kHz RTP timestamps for the video pipeline. The FPGA counter runs at 156.25 MHz using fixed-point arithmetic for sub-nanosecond accuracy. Time corrections from the LinuxPTP stack on the Zynq ARM are applied via AXI registers.

Current State

  • RTL module ptp_engine is complete with free-running counter, absolute set, and offset adjustment.
  • RTP timestamp generation at 90 kHz rate verified in simulation (576 ticks per 1M cycles).
  • Frame timestamp capture via frame_rtp_ts validated.
  • Second rollover tested with RTP continuity verification.
  • LinuxPTP configuration script ready for SMPTE ST 2059 profile (domain 127, slave-only mode).
  • PTP accuracy depends on software-assisted approach; sub-microsecond accuracy depends on system load. Phase 2 plans hardware-only PTP timestamping.

Key Files

Technical Details

Fixed-Point Nanosecond Counter

The counter uses 10 fractional bits for sub-nanosecond precision:

  • Increment per 156.25 MHz cycle: 6.4 ns = 6553.6 in Q32.10, rounded to 6554
  • Rounding error: approximately 0.006% (corrected by PTP servo)
  • Seconds rollover: when fractional ns >= 1,000,000,000 << 10, subtract and increment seconds

RTP Timestamp Derivation

The 90 kHz RTP timestamp is derived from a nanosecond accumulator:

  • Tick interval: 1/90000 s = 11111.111 ns, using integer 11111 ns
  • Each cycle adds the integer nanosecond delta (6 or 7 ns due to fractional accumulation)
  • When accumulator >= 11111, subtract and increment RTP counter
  • Verified: ~576 ticks per 1,000,000 cycles (6.4 ms / 11.111 us = 576)

Frame Timestamp Capture

frame_rtp_ts latches the current rtp_count on the frame_start pulse. The pulse arrives from the pixel clock domain via a toggle synchronizer (3-stage) in ipbridge_top. The captured timestamp is used by the RTP packetizer for all packets within that frame.

Time Adjustment Interface

The PTP protocol stack writes corrections via four AXI registers:

  • adj_valid - Pulse to apply adjustment
  • adj_sec[47:0] - Seconds value
  • adj_nsec[31:0] - Nanoseconds value (signed for offset mode)
  • adj_set - 1 = absolute set (overwrite), 0 = signed offset adjustment

Absolute set recomputes the RTP counter from the new time. Offset adjustment handles nanosecond overflow/underflow with second borrow/carry.

LinuxPTP Configuration (ptp_config.sh)

The script configures ptp4l and phc2sys for SMPTE ST 2059-2:

  • Domain 127, transport-specific flag 0x1
  • Layer 2 transport, E2E delay mechanism
  • Hardware timestamping via /dev/ptp0
  • Slave-only mode (priority1=128, priority2=255, clockClass=255)
  • Sync interval: logSyncInterval=-3 (8 syncs/second)
  • Step threshold: 1.0s first adjustment, 20us subsequent
  • phc2sys synchronizes system clock to PTP hardware clock

Lock detection: considers PTP locked when offset from master < 1000 ns.

Sources

  • rtl/ptp_engine.sv
  • sim/tb_ptp_engine.sv
  • sw/ptp_config.sh
  • docs/phase1-test-plan.md