这一篇在干嘛?
板子上晶振给你的时钟通常只有一个固定频率,比如 50MHz,但你的逻辑可能需要 120MHz、25MHz,甚至要好几路不同频率、不同相位的时钟。这活儿就归 PLL(Phase Locked Loop,锁相环)管。这一篇带你把 EG4S20 里的 PLL 从原理到配置走一遍,看完你就能自己”造”时钟了。
PLL 是什么,藏在芯片哪个角落
EG4S20 属于安路 EAGLE 系列,里面的 PLL 硬核 IP 模块叫 EG_PHY_PLL。EAGLE 系列 FPGA 一共内嵌了 4 个多功能锁相环(PLL0~PLL3),分布在器件的四个角上。每个 PLL 都能干这几件事:
- 时钟分频(把高频变低)和倍频(把低频变高);
- 让输入时钟和反馈时钟对准相位;
- 输出多相位时钟,还支持动态相位调整和 PLL 动态参数配置。
先看整体架构,重点是 PLL 的时钟从哪来、到哪去:

参考时钟输入(也就是 PLL 的”原料”)有四种来源:
- GCLK PIN(专用全局时钟管脚)
- 时钟网络 BUFG
- 互连 PIB
- 内部振荡器 OSC
反馈时钟输入(PLL 用来”对表”的信号)有四种来源:时钟网络 BUFG、互连 PIB、PLL 内部反馈时钟,以及分频时钟 C0~C4。
另外,PLL 还有专门的输出,可以直驱芯片的专用时钟输出管脚,从而获得更好的抖动性能——也就是说 PLL 的 C0 可以直接”出厂”到 IO 管脚上给外部芯片供时钟。
它能帮你做什么:特性一览
把 EAGLE PLL 的硬指标列成一张表,后面算频率全靠它:
| 特性 | EAGLE PLL |
|---|---|
| 输入时钟频率范围 | 10~500 MHz |
| VCO 频率范围 | 300~1200 MHz |
| 输出端口数 | 5 个(C0~C4,各端口相位独立可选) |
| 参考时钟分频系数(M) | 1~128 |
| 反馈时钟分频系数(N) | 1~128 |
| 输出时钟分频系数(C0~C4) | 1~128 |
| 相移分辨率 | 45°/N(相对 VCO) |
| 用户动态相移控制 | 支持 |
| 锁定状态输出 | Lock |
| 专用时钟输出管脚 | 支持 |
技巧
记住两个”硬杠杠”:输入必须在 10
500MHz 之间,VCO 必须落在 3001200MHz 之间。配置 TD 里的 PLL 时如果报错,十有八九是这两个范围没满足。
频率怎么算:M、N、C 三个旋钮
把 PLL 想象成一条三级流水线,每级有一个”分频旋钮”:
- M(参考分频):输入时钟先除以 M,得到鉴相器的工作频率;
- N(反馈倍频):VCO 再乘上去,满足
f_VCO = f_in × N / M; - C0~C4(输出分频):VCO 信号分出 5 路,每路各自除以一个 C 值,得到最终输出
f_out = f_VCO / C。
举个完整的例子:假设板子晶振是 50MHz,想要一路 120MHz、一路 50MHz、一路 240MHz。
- 先凑 VCO:取 M=1、N=24,则 f_VCO = 50 × 24 / 1 = 1200MHz,正好压在 300~1200MHz 的上限上,合法;
- 再分输出:C0 = 1200/120 = 10 → 输出 120MHz;C1 = 1200/50 = 24 → 输出 50MHz;C2 = 1200/240 = 5 → 输出 240MHz。
坑在这里
VCO 频率不能”超频”。比如 50MHz 输入想直接 ×30 到 1500MHz 就不合法,哪怕输出端再分频回去也不行——配置工具会拒绝或者结果不可靠。算系数时永远先检查 VCO 落没落在 300~1200MHz,再看输出。另外 M、N、C 每个的取值范围都是 1~128,别把 C 算成 0 或小数。
四种反馈模式:时钟”对表”的方式
EAGLE 系列 PLL 支持 4 种反馈模式,每一种都支持分频、倍频和相移。区别在于 PLL 拿什么当反馈、补偿哪段线路的延迟。
a) 源同步模式(Source Synchronous Mode):靠相移功能调节时钟相位,让”数据从端口到 IOB 输入寄存器的延迟”和”时钟从输入端口到 IOB 寄存器的延迟”相等(前提是数据和时钟输入端口模式相同)。做 DDR 这类数据和时钟一起进来的接口时最常用。

b) 无补偿模式(No Compensation Mode):PLL 不补偿时钟网络延迟,采用内部自反馈,好处是能降低输出抖动。此模式下 PLL 输出的各路内部时钟之间相位对齐,但 PLL 时钟输出可以超前或滞后于输入时钟。
c) 普通模式(Normal Mode):PLL 会补偿 GCLK 网络延迟,保证内部寄存器看到的时钟相位和时钟管脚上的相位一致。这是最”直觉”的模式——管脚上来的是什么相位,里面寄存器收到的就是什么相位。

d) 零延迟缓冲模式(Zero Delay Buffer Mode):让时钟输出管脚的相位和 PLL 参考时钟输入管脚对齐,相当于把 PLL 当成一个”零延迟的时钟缓冲器”。注意它是在普通模式的基础上实现的,而且要求输入时钟与输出时钟使用同一种 I/O 标准,才能保证输入与输出管脚上的时钟真正对齐。
怎么选
不确定就用普通模式打底;在乎抖动(比如给高速收发器或 ADC 供时钟)试试无补偿模式;做源同步接口(数据和时钟成对进来)用源同步模式;需要把时钟原样转发给另一颗芯片用零延迟缓冲模式。
动态相移:跑起来以后还能微调相位
PLL 的分频系数、反馈模式这些属于静态配置——你在软件里设好、生成码流、上电下载,之后就不能改了。但 EAGLE 还支持动态相移:芯片跑着的时候,实时微调某一路输出的相位。
原理是对一个给定的计数器递增或递减,每次移动 1/8 个 VCO 周期的相位。控制信号有 5 个:
| 信号名称 | 描述 | 信号来源 | 信号目的地 |
|---|---|---|---|
| PSCLKSEL | 要进行动态移相的时钟选择信号,从 C0~C4 中选出一路或同时移相 | PIB 或 IO 引脚 | PLL reconfiguration 电路 |
| PSDOWN | 相移方向选择,1=向上(增),0=向下(减),在 PSCLK 上升沿采样 | PIB 或 IO 引脚 | PLL reconfiguration 电路 |
| PSSTEP | PSSTEP=1 时使能动态相移 | PIB 或 IO 引脚 | PLL reconfiguration 电路 |
| PSCLK | 动态相移时钟 | GCLK 或 IO 引脚 | PLL reconfiguration 电路 |
| PSDONE | 高电平表明相位调整结束,在 PSCLK 上升沿采样 | PLL reconfiguration 电路 | PIB 或 IO 引脚 |
选哪一路移相由 PSCLKSEL[2:0] 决定:
| PSCLKSEL[2:0] | PLL 输出选择 |
|---|---|
| 000(默认) | C[0] |
| 001 | C[1] |
| 010 | C[2] |
| 011 | C[3] |
| 100 | C[4] |
| 101 | C[4]~C[0](五路时钟同时调整) |
执行一次动态相移要按部就班走五步:
- 根据需要设置 PSDOWN 和 PSCLKSEL;
- 打开相位调整:PSSTEP 至少保持 4 个 PSCLK 周期,每一个 PSSTEP 脉冲移动一次相位;
- 关闭相位调整;
- 等待 PSDONE 变为高电平;
- 需要多次调整就重复步骤 1~4。
时序上的细节看这张图:

PSSTEP 在 PSCLK 上升沿被锁存,必须至少保持 4 个 PSCLK 周期的高电平;PSCLK 采样到 PSSTEP 后再过 2 个周期,PSDONE 拉低并保持 2 个周期,然后 PSDONE 由低变高——之后还要再等至少 4 个 PSCLK 周期才能开始下一次移相。所以手册明确说:完成一次动态相移至少需要 8 个 PSCLK 周期。
坑在这里
动态相移过程中,被调节的那路时钟可能会产生毛刺(glitch)。如果这路时钟带着重要的逻辑,移相期间的状态可能不可靠,设计时要预留处理(比如移相期间暂停采样,或移完相后复位下游逻辑)。另外 PSCLKSEL、PSSTEP、PSDOWN 必须先被 PSCLK 同步过后再送给 PLL,别用异步信号直接怼上去。
端口速查表
例化 PLL 模块时会碰到这些端口,含义如下:
| 名称 | 输入/输出 | 位宽/bit | 描述 |
|---|---|---|---|
| clkc | OUT | 7 | PLL 时钟输出 |
| extlock | OUT | 1 | PLL 锁定输出,高有效 |
| stdby | IN | 1 | standby 使能,仅在 STDBY_ENABLE = “ENABLE” 时有效,1=暂停,0=不暂停 |
| refclk | IN | 1 | PLL 参考时钟 |
| fbclk | IN | 1 | 反馈时钟 |
| reset | IN | 1 | 复位,高有效 |
| psdone | OUT | 1 | 动态相位移位完成 |
| psclk | IN | 1 | 动态相位移位时钟 |
| psdown | IN | 1 | 动态相移方式,增加或减少 |
| psstep | IN | 1 | 动态相移脉冲数 |
| psclksel | IN | 3 | 动态相移选择某一路输出进行相移 |
技巧
extlock(锁定信号)一定要接出来用。PLL 上电后需要一小段时间才能锁定到输入时钟,锁定之前输出时钟的频率和相位都不可信——用 extlock 做下游逻辑的复位释放条件是标准操作。
在 TD 里一步步生成 PLL
理论讲完,动手。An路的 TD 软件里自带 IP 生成器,跟着点就行。
第 1 步:TD 界面下点击 Tools → IP Generator → Creat a new IP core,在 IP core 界面里选择 PLL:

第 2 步:进入 PLL 配置界面,根据实际情况配置输入时钟频率、反馈模式、输入设置及动态设置等:

第 3 步:选择 PLL 带宽。手册建议直接使用默认选项,没有特殊需求别乱动:
第 4 步:根据需求选择 PLL 输出管脚的个数、频率和偏移相位——前面算好的 C0~C4 频率就在这一页填:

第 5 步:点击 OK 完成全部配置,然后在你的顶层代码里例化调用生成的 PLL 文件即可。TD 工具会自动帮你算好 M、N、C 的系数——你只管填输入频率和想要的输出频率。
使用建议与避坑清单
最佳实践
- 先稳后锁:等输入信号稳定之后,再给 PLL 复位,这样才能保证输出时钟信号的频率和相位正确;
- 盯紧 lock:使用中要关注 PLL 的 lock 信号(extlock)是否为高,为高才说明 PLL 已锁定、输出可信;
- VCO 优先:算频率时先把 VCO 凑进 300
1200MHz,再分配 C0C4 的分频;- 带宽用默认:TD 里 PLL 带宽选择建议保持默认,除非你明确知道自己在调什么。
自测
自测
- 板子晶振是 25MHz,想得到一路 100MHz 输出。如果取 M=1,N 应该取多少?此时 VCO 频率是多少,C 分频系数又是多少?VCO 是否合法?
- 动态相移时,PSSTEP 信号至少要保持几个 PSCLK 周期的高电平?完成一次动态相移至少需要多少个 PSCLK 周期?为什么移相期间下游逻辑要小心?