Xilinx 使用 Vivado 实现 TDC:基于 Verilog 的高精度时间数字转换器设计
在激光雷达系统中,飞行时间(ToF)测量的精度直接决定了距离分辨能力。一个典型的挑战是:如何在不使用昂贵专用芯片的前提下,实现皮秒级的时间间隔测量?随着FPGA架构的进步,尤其是Xilinx 7系列及UltraScale器件中SLICE结构的高度一致性,这个问题有了新的答案——利用FPGA内部的进位链(Carry Chain)构建全数字TDC(Time-to-Digital Converter),不仅成本低、集成度高,还能达到50~100 ps的分辨率。
这种方案的核心思想并不复杂:把两个事件之间极短的时间差,'展开'成一条由微小延迟单元串联而成的物理路径,再通过锁存这条路径上的状态来'读出'时间值。听起来像是用尺子量时间,而这条'尺子'的最小刻度就是每个延迟单元的传播延迟。
要理解这一机制,得先看清楚FPGA里藏着什么'宝藏'。在Xilinx Artix-7或Kintex-7这类主流器件中,每一个CLB(Configurable Logic Block)都包含多个SLICE,而每个SLICE内嵌了一个名为 CARRY4 的原语。它的本职工作是在加法器中快速传递进位信号,但由于其硅级布局高度优化,各级之间的延迟非常稳定且均匀——这正是构建高精度延迟链的理想材料。
相比用LUT(查找表)搭建的延迟线, CARRY4 具有更低的单元间偏差和更强的抗工艺波动能力。更重要的是,它不需要额外功耗就能维持稳定的延迟特性,非常适合长期运行的精密测量系统。典型条件下,单个 CARRY4 级联段的延迟约为70 ps,这意味着仅需几十个这样的单元,就能实现几纳秒范围内的精细时间采样。
我们来看一段关键代码,它是整个TDC的灵魂所在:
// carry_chain_delay.v —— 利用 CARRY4 构建等效延迟链 module carry_chain_delay ( input clk, input start, output wire[TDL_LENGTH-1:0] taps ); (* DONT_TOUCH = "TRUE" *) reg [TDL_LENGTH-1:0] dly_reg = 0; assign taps = dly_reg; generate genvar i; for (i = 0; i < TDL_LENGTH; i = i + 1) begin : carry_gen CARRY4 carry_inst ( .CO(), .CYINIT(i == 0 ? start : 1'b0), .DI(4'h0), .S({4{1'b0}}), .O() ); defparam carry_gen.carry_inst.CYBIT_OP = "O"; end endgenerate always @(posedge clk) begin dly_reg[0] <= start; for (int j = 1; j < TDL_LENGTH; j = j + 1) dly_reg[j] <= dly_reg; end endmodule

