【电路笔记 通信】IEEE 1588精密时间协议(PTP):时间戳格式+精确到ns的时间表示与处理

时间戳格式

项目 IEEE 1588 Truncated NTP 64‑bit
Epoch 1970‑01‑01 TAI 1900‑01‑01 UTC
秒字段 32‑bit 秒 32‑bit 秒
小数部分 32‑bit 纳秒(0--10⁹‑1) 32‑bit 秒分数(1/2³² s)
闰秒 不考虑(TAI) 考虑(UTC,由 NTP)
精度 纳秒 ~233 ps(理论)
常见场景 硬件/PTP/NSH NTP / 传统网络协议
字段 位数 说明
secondsField(整秒部分) 32 bit(4 字节) 自 PTP Epoch(1970-01-01 00:00:00 TAI)起的秒数,无闰秒
nanosecondsField(纳秒部分) 32 bit(4 字节) 0 ~ 999,999,999 ns,表示不足一秒的小数部分
bash 复制代码
 The two timestamp formats that can be used in the timestamp field
   are:

   o  IEEE 1588 Truncated Timestamp Format: the format of this field
      uses the 64 least significant bits of the IEEE 1588-2008 Precision
      Time Protocol format [IEEE1588].  This truncated format consists
      of a 32-bit seconds field followed by a 32-bit nanoseconds field.
      As defined in [IEEE1588], the timestamp specifies the number of
      seconds elapsed since 1 January 1970 00:00:00 according to the
      International Atomic Time (TAI).

Mizrahi, et al.         Expires February 21, 2018               [Page 4]
Internet-Draft                NSH Timestamp                  August 2017


       0                   1                   2                   3
       0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
      |                            Seconds                            |
      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
      |                           Nanoseconds                         |
      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

        Figure 2: IEEE 1588 Truncated Timestamp Format [IEEE1588].

   o  NTP 64-bit Timestamp Format: this format consists of a 32-bit
      seconds field followed by a 32-bit fractional second field.  As
      defined in [RFC5905], the timestamp specifies the number of
      seconds elapsed since 1 January 1900 00:00:00 according to the
      Coordinated Universal Time (UTC).


       0                   1                   2                   3
       0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
      |                            Seconds                            |
      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
      |                            Fraction                           |
      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

              Figure 3: NTP [RFC5905] 64-bit Timestamp Format
- https://datatracker.ietf.org/doc/html/draft-mymb-sfc-nsh-allocation-timestamp-02?

精确到ns的时间表示与处理

verilog 复制代码
// 基本数据结构(推荐)
reg [31:0] sec;   // 秒(低32位)
reg [31:0] nsec;  // 纳秒(0--999_999_999) 经过了多少个ns

自增

  • 时间递增维护(最常见):每周期加固定纳秒(如 8 ns)
verilog 复制代码
always @(posedge clk) begin
    if (nsec >= 32'd1_000_000_000 - 32'd8) begin   // 进位条件是 `>= 1e9`,不是 `==`防止亚稳态和边界 bug
        nsec <= nsec + 32'd8 - 32'd1_000_000_000;
        sec  <= sec + 1'b1;
    end else begin
        nsec <= nsec + 32'd8;
    end
end

相减(使用高频mcu处理比较容易)

  • 两个PTP时间戳相减(Δt)
  • 在同一 ToD(Time of Day)源、单调递增计数器、无软件干预,可以假设 a_sec ≥ b_sec,甚至可以 assert(a_sec >= b_sec),不需要显式处理 a_sec < b_sec 的情况。
verilog 复制代码
// ts_a >= ts_b
reg [31:0] delta_sec;
reg [31:0] delta_nsec;

always @(*) begin
    if (a_nsec >= b_nsec) begin
        delta_sec  = a_sec - b_sec;
        delta_nsec = a_nsec - b_nsec;
    end else begin
        delta_sec  = a_sec - b_sec - 1'b1;
        delta_nsec = a_nsec + 32'd1_000_000_000 - b_nsec;
    end
end
减法中考虑a_sec < b_sec的情况
  • 有符号数(正确姿势)
  • 二进制补码(Two's Complement)是计算机内部表示和存储有符号整数的标准方法。它将符号位与数值位统一处理,使加减法硬件电路大大简化。正数的补码就是其本身,负数的补码则是将其原码除符号位外按位取反,末位再加 1。
verilog 复制代码
reg signed [31:0] a, b;
wire signed [31:0] diff;

assign diff = a - b;
  • 采用有符号数+标志位:
verilog 复制代码
reg [31:0] a_sec, a_nsec;
reg [31:0] b_sec, b_nsec;

reg valid;
reg [31:0] delta_sec;
reg [31:0] delta_nsec;

always @(*) begin
    if (a_sec < b_sec ||
       (a_sec == b_sec && a_nsec < b_nsec)) begin  // 小数减大数 → valid = 0
        valid = 1'b0;
        delta_sec  = 32'd0;
        delta_nsec = 32'd0;
    end else begin
        valid = 1'b1;
        if (a_nsec >= b_nsec) begin
            delta_sec  = a_sec - b_sec;
            delta_nsec = a_nsec - b_nsec;
        end else begin
            delta_sec  = a_sec - b_sec - 1'b1;
            delta_nsec = a_nsec + 32'd1_000_000_000 - b_nsec;
        end
    end
end
相关推荐
LuminousCPP6 小时前
数据结构-二叉树(六):BFS层序遍历与完全二叉树判断|复用链式队列 + (N_0=N_2+1) 性质证明
c语言·数据结构·笔记·算法·二叉树·宽度优先
一条破秋裤8 小时前
STM32 学习笔记:PWM 驱动 LED 呼吸灯与舵机代码
笔记·stm32·学习
kyrie_sakura10 小时前
python学习笔记11 -- 进程和线程
笔记·python·学习
自小吃多10 小时前
PCB Editor软件差分对添加与设置笔记
笔记·嵌入式硬件
Capricorn198811 小时前
防编造架构实战:对比 Gemini Notebook 解析知芽 Notebook Skill 的工程实现
人工智能·笔记·elasticsearch·架构·知识图谱·论文笔记
Shell运维手记12 小时前
Linux mdadm 软 RAID + LVM 完整综合笔记
linux·运维·笔记·5g
疯狂打码的少年12 小时前
【数据库技术】SQL数据查询(SELECT基本语法)
数据库·笔记·sql·oracle
Made in Haven71212 小时前
HTML课程笔记补2
前端·笔记·html
夕除13 小时前
redis--010
笔记·分布式·学习
ouynagda13 小时前
HTTP协议与Socket网络编程笔记
网络·笔记·http