在 FPGA 设计中,时钟生成通常遵循一条铁律:永远不要使用逻辑生成的时钟。然而,当面对音频编解码器需要的 49.152MHz 时钟、视频像素时钟或 GPS 同步时钟等任意频率需求时,工程师不得不打破这条规则。本文基于 ZipCPU 的实践经验,梳理一套从时钟分频到抖动抑制的完整工程实现方案。
分数时钟分频的基础原理
传统的时钟分频器只能实现整数分频,而分数时钟分频器通过累加器结构突破了这一限制。核心逻辑使用一个 N 位计数器,每个时钟周期累加一个步进值:
always @(posedge i_clk)
{ck_stb, counter} <= counter + STEP_VALUE;
当计数器溢出时,ck_stb 信号产生一个单周期脉冲。通过调整步进值,理论上可以实现任意频率的分频。对于 32 位计数器,频率分辨率达到系统时钟除以 2 的 32 次方 —— 在 100MHz 系统时钟下约为 23 毫赫兹。
然而,基础分数分频存在明显的相位噪声问题。由于每个周期只能输出一个离散值,时钟边沿会在理想位置的 ±1 个系统时钟周期范围内抖动。这种抖动对于敏感的音频或视频接口可能是致命的。
多相上采样与 OSERDES 优化
为抑制相位噪声,采用 8 相上采样策略。通过维护 8 个相位错开的计数器,每个计数器偏移 1/8 个步进值,可以获得 8 倍的时间分辨率:
counter[1] <= counter[0] + r_delay;
counter[2] <= counter[0] + {r_delay[(BW-2):0], 1'b0};
// ... 依此类推
counter[0] <= counter[0] + {r_delay[(BW-4):0], 3'h0};
各计数器的最高位被收集为一个 8 位数据字,送入 Xilinx 的 OSERDESE2 原语进行 8:1 串行化输出。OSERDESE2 配置为 DDR 模式,支持最高 950MHz 的数据速率,相比 SDR 模式的 600MHz 上限提供了更大的设计裕量。
关键实现细节包括:数据位序的确定(D1 最先输出)、CLKDIV 与 CLK 的 4 倍频关系、以及通过 IOBUF 将输出引脚配置为双向模式并强制输出使能,确保信号能够回环进入 PLL。
外部 PLL 的抖动抑制与时钟清理
上采样后的时钟仍存在残余抖动,需要通过片外 PLL 进行清理。以 Xilinx 7 系列为例,使用 PLLE2_BASE 原语配置反馈环路:
- CLKFBOUT_MULT 设为 32,将 40MHz 输入倍频至 800MHz
- CLKOUT0_DIVIDE 设为 16,输出 50MHz 时钟
- BANDWIDTH 选择 LOW 以获得更好的抖动抑制
PLL 的锁定信号可作为时钟质量的二进制指示器。对于低于 PLL 锁定范围的极低频时钟,可绕过 PLL 直接将引脚输入通过 BUFG 缓冲进入时钟网络,但此时抖动抑制效果会显著下降。
时钟域跨越与约束设置
逻辑生成时钟的最大风险在于时钟偏斜和工具链识别问题。解决方案要求生成的时钟必须通过时钟 capable 引脚重新进入 FPGA,强制工具将其识别为外部时钟并分配至全局时钟骨干网络。
时序约束需设置为时钟可能达到的最高频率。例如,若生成时钟范围从 1kHz 到 200MHz,则约束应设为 200MHz。这确保了工具在最坏情况下仍能保证时序收敛。
时钟域跨越 (CDC) 是另一个关键考量。生成时钟域与源时钟域之间的数据传输必须使用标准的 CDC 技术,如双触发器同步器或异步 FIFO。
工程实现检查清单
参数设计阶段
- 确定目标频率范围及分辨率要求(建议 32 位计数器)
- 计算步进值:STEP = (目标频率 / 系统时钟) × 2^BW
- 验证 OSERDES 数据速率不超过器件规格(DDR 模式≤950MHz)
RTL 实现阶段
- 实现 8 相计数器,使用移位加法替代乘法(×3、×5、×7)
- 配置 OSERDESE2 为 MASTER 模式、DDR 数据率、8 位宽度
- 确保 D1-D8 位序与物理示波器验证一致
- 添加 IOBUF 实现输出回环
时钟网络阶段
- 配置 PLLE2_BASE 参数,确保 VCO 在有效范围(800-1600MHz)
- 使用 BUFG 将清理后的时钟引入全局时钟网络
- 实现 PLL 锁定检测逻辑(建议 5 级移位寄存器去抖)
验证阶段
- 使用时序分析仪验证时钟抖动(RMS / 峰峰值)
- 验证跨时钟域数据传输的正确性
- 测试频率边界条件(最低 / 最高频率锁定)
风险与限制
该方案的主要风险包括:分数分频固有的相位噪声无法完全消除;极低频时钟可能超出 PLL 锁定范围;工具链对逻辑时钟的时序分析可能过于乐观。建议在关键应用中使用专用时钟生成芯片作为替代方案。
参考来源
- ZipCPU, "Breaking all the rules to create an arbitrary clock signal", 2019
- ZipCPU, "Controlling Timing within an FPGA", 2017
内容声明:本文无广告投放、无付费植入。
如有事实性问题,欢迎发送勘误至 i@hotdrydog.com。