2. Zynq时钟生成与分配机制

Zynq 器件的时钟体系可以理解为“两级生成、一张分配网、若干交叉点”。PS(Processing System)内部有独立的 PLL 组,负责把外部参考时钟合成 CPU、DDR、外设等所需频率;PL(Programmable Logic)侧则依靠 MMCM 与 PLL 对输入时钟做倍频、分频和相位调整,再通过时钟缓冲网络分配到各逻辑区域。理解这套机制的关键,不是记住某个具体频率,而是弄清“时钟从哪来、经过谁、变成什么、送到哪、在哪里跨域”。

PS 侧:PLL 生成与时钟域划分

PS 的时钟源通常来自外部晶振,经 PS_CLK 引脚进入后,先经过 PLL 参考路径。Zynq-7000 的 PS 一般包含 ARM PLL、DDR PLL、IO PLL 三类核心 PLL,分别服务 CPU 与互连、DDR 控制器、外设与 IO。每个 PLL 的输出并不是直接送到终点,而是先进入一组分频器,再分配给 CPU_6x4x、CPU_3x2x、CPU_2x、DDR_3x、DDR_2x、UART、SD、SPI、QSPI、GigE 等时钟分支。因此 PS 内部本身就存在多个时钟域,例如 CPU 域、DDR 域、低速外设域,它们之间通过 AXI 互连、异步 FIFO 或同步器完成跨域。

以常见的示例配置为例:外部 PS_CLK 取 33.333 MHz,ARM PLL 目标 1333 MHz,经分频后 CPU 运行在 666.667 MHz,DDR 运行在 533.333 MHz,IO PLL 输出 1000 MHz 再分出 200 MHz 给部分外设。这些数值只是教学示例,实际应以器件手册和 Vivado 时钟配置界面为准。需要强调的是,PS 侧一旦锁定失败,CPU、DDR 或外设可能完全无法启动,因此 PLL 的锁定状态(LOCK)和参考时钟是否存在,是上电后最先要确认的信号。

PL 侧:MMCM/PLL 与时钟分配

PL 侧的时钟来源主要有三类:外部时钟引脚输入、PS 通过 FCLK 输出给 PL 的时钟、以及 GT 收发器恢复出的时钟。这些时钟进入 PL 后,通常先接入 BUFG、BUFH、BUFR 等时钟缓冲资源,再送入 MMCM 或 PLL。MMCM 比 PLL 多提供精细相位调整和更多输出分支,适合需要多个相位、多个频率的场合;PLL 则更偏向简单的倍频与抖动过滤。两者内部都包含鉴相器、电荷泵、环路滤波器、VCO 和输出分频器,核心关系是:

Fvco = Fref × M / D
Fout = Fvco / O
其中 M 为倍频系数,D 为输入分频,O 为输出分频

例如输入 100 MHz,取 D=1、M=10,则 VCO 为 1000 MHz;若某输出 O=8,则该路输出 125 MHz。VCO 频率必须落在器件允许范围内,否则 MMCM 无法锁定。PL 侧时钟分配还要注意 BUFG 数量有限,高扇出时钟应优先走全局缓冲;区域时钟可用 BUFH 或 BUFR,但跨区域能力较弱。若把高速时钟接到普通布线资源上,会出现明显偏斜和抖动,时序报告中的时钟不确定性也会变差。

时钟使能与分频:不是所有“慢时钟”都要真的分频

在 PL 设计中,降低逻辑速率有两种常见做法:一是用 MMCM 输出一个真正低频时钟,二是保持原时钟,用时钟使能(Clock Enable)按周期选通。前者会引入新的时钟域,后者仍处于同一时钟域,只是部分周期不工作。对于低速控制逻辑,时钟使能往往更省资源、更少跨域问题;对于需要独立频率的接口,则必须用 MMCM/PLL 生成真实时钟。分频器可以用计数器实现,例如 100 MHz 下计数到 49 翻转,得到 1 MHz 方波,但要注意占空比和复位初值。

判断原则:如果两个模块之间只是“偶尔通信”,优先考虑同一时钟加使能;如果两者有独立频率要求或需要相位关系,才生成新时钟并明确跨域处理。

时钟域交叉点识别方法

CDC 验证的第一步不是写同步器,而是找出所有跨域点。推荐按“时钟源—时钟域—跨域信号”三层梳理:先列出设计中所有时钟名称及其频率、相位关系;再把每个寄存器按驱动时钟归类;最后检查每个寄存器的输入是否来自不同时钟域。常见跨域点包括:PS 到 PL 的 FCLK 与 PL 内部时钟之间、PL 内部不同 MMCM 输出之间、以及 PL 与 PS 通过 AXI 交互的接口。识别时可用 Vivado 的 Report Clock Interaction 查看时钟对之间的路径,再结合代码中的跨域信号名、异步 FIFO 实例、双触发器同步器进行交叉核对。

Zynq 时钟生成、分配与跨域点识别 PS 侧 PS_CLK 33.333M ARM PLL DDR PLL / IO PLL 分频器组:CPU / DDR / 外设 PS 内部多时钟域 PL 侧 外部时钟引脚 或 FCLK / GT 恢复 BUFG / BUFH 时钟缓冲网络 MMCM / PLL 倍频·分频·移相 输出 多路时钟 时钟使能 / 计数器分频:同域降速,不新增时钟域 跨域点:FCLK↔PL、MMCM 输出之间、AXI 接口 FCLK 时钟域交叉点识别流程 ① 列出所有时钟 名称 / 频率 / 相位 ② 寄存器按时钟归类 驱动时钟 / 复位域 ③ 检查输入来源 是否来自异域 ④ 标记跨域点 同步器 / FIFO / 握手 ⑤ 验证 时序报告 工具辅助:Vivado Report Clock Interaction 查看时钟对路径;代码中搜索跨域信号名、异步 FIFO、双触发器同步器 判断依据:路径是否被时序约束覆盖、是否存在亚稳态传播风险、同步器是否完整

从识别到处理:跨域点确认后的动作

识别出跨域点后,要按信号性质选择处理方式。单比特控制信号通常用两级触发器同步,并加 ASYNC_REG 属性;多比特数据总线应使用异步 FIFO 或握手协议,不能简单打两拍;脉冲信号可先展宽再同步,或使用脉冲同步器。对于 PS 与 PL 之间的 AXI 接口,若两侧时钟不同,应使用 AXI 异步桥或独立时钟的 AXI Interconnect,并在约束中声明时钟关系。验证阶段,除了看 Report Clock Interaction,还应检查时序报告中的跨时钟路径是否被正确约束,避免工具把异步路径当成同步路径分析。

常见误区:把 MMCM 输出的两个不同频率时钟直接当作“同源同步”使用。它们虽然来自同一 VCO,但频率不同、相位关系固定但周期不对齐,仍属于跨域,必须按 CDC 处理。

小结与检查要点

PS PLL 负责系统级频率合成,PL MMCM/PLL 负责逻辑侧精细时钟生成,时钟使能与分频用于同域降速,CDC 识别则贯穿整个设计。实际项目中,建议在综合前就完成时钟清单和跨域点清单,而不是等时序违例后再回头找。一个可执行的检查顺序是:确认所有时钟源和频率、确认每个寄存器的驱动时钟、确认跨域信号是否都有同步或 FIFO、确认约束是否覆盖跨时钟路径、最后用 Report Clock Interaction 和时序报告交叉验证。这样,时钟生成与分配就不再是零散配置,而是一条从源到域、从域到点的完整链路。