时钟生成单元设计:PLL配置与锁定过程、时钟分频与倍频、时钟门控技术
各位好,我是老张。今天咱们聊聊基带SoC里最核心的时钟生成单元。说实话,我入行那会儿,PLL还是个挺神秘的东西,现在虽然集成度高了,但该踩的坑一个都没少。时钟是芯片的“心跳”,心跳乱了,整个系统就崩了。所以这部分内容,我建议你认真看。
PLL配置与锁定过程
PLL,全称是锁相环。它的任务很简单:把外部一个低频、不太干净的参考时钟,变成内部高频、低抖动的时钟。但实现起来,门道不少。
PLL的基本结构,说白了就是四个模块:鉴频鉴相器(PFD)、电荷泵(CP)、环路滤波器(LF)和压控振荡器(VCO)。再加上一个反馈分频器。你想想看,这其实是个负反馈系统。PFD比较参考时钟和反馈时钟的相位差,输出一个误差信号。这个信号经过CP和LF变成电压,控制VCO的频率。VCO输出再分频后送回PFD。最终,当反馈时钟和参考时钟完全同步时,PLL就“锁定”了。
核心公式: Fvco = Fref × N
其中Fvco是VCO输出频率,Fref是参考频率,N是反馈分频比。
配置流程,我一般分三步走:
- 设置分频比:根据目标频率和参考频率,算出N值。比如参考是26MHz,想要1.3GHz,N就是50。
- 配置电荷泵电流和环路带宽:这步很关键。带宽太宽,抖动大;太窄,锁定慢。我个人习惯把带宽设在参考频率的1/10到1/20之间。
- 启动锁定过程:先软复位PLL,然后等待锁定指示信号拉高。
锁定过程,其实是个动态调整的过程。刚开始,VCO频率可能差得很远,PFD输出大电流,快速拉近频率。这叫“频率捕获”。等频率接近了,进入“相位捕获”,慢慢调整相位。最后,相位误差小到一定程度,锁定指示信号就拉高了。
避坑指南: 我曾经在一个项目中,发现PLL锁定指示信号拉高了,但系统还是跑不稳。后来查了半天,发现是锁定指示的阈值设得太宽了。相位误差虽然小于阈值,但依然很大,导致时钟抖动超标。所以,我建议你锁定后,再等一段时间(比如几百微秒),确认时钟稳定了再使用。
下面我画了一张PLL锁定过程的流程图,方便你理解:
时钟分频与倍频
PLL输出的是高频时钟,但芯片里不同模块需要的频率不一样。CPU要高频,外设要低频。这时候就需要分频和倍频了。
分频,就是把高频时钟变成低频时钟。最简单的分频器是计数器。比如要2分频,就数两个周期翻转一次。但要注意,分频后的时钟可能会有相位偏移。我在项目中遇到过,分频时钟和源时钟的边沿没对齐,导致跨时钟域同步出问题。所以,我建议你用同步分频器,或者用PLL内部提供的多相位输出。
倍频,一般用PLL本身来实现。但有时候,我们需要在PLL之外做倍频,比如用DLL(延迟锁相环)或者倍频器。不过,倍频器的设计难度比分频器大得多,容易引入抖动。我个人习惯,能用PLL解决的,绝不用外部倍频器。
| 方法 | 优点 | 缺点 | 适用场景 |
|---|---|---|---|
| 计数器分频 | 简单、面积小 | 相位可能偏移 | 对时序要求不高的模块 |
| 同步分频器 | 相位对齐 | 面积稍大 | 跨时钟域接口 |
| PLL倍频 | 低抖动、高精度 | 面积大、功耗高 | CPU、高速接口 |
| DLL倍频 | 低抖动、锁定快 | 倍频范围有限 | DDR接口 |
警告: 分频时钟不要直接用于门控时钟的使能信号!我曾经见过一个设计,用分频时钟的上升沿去使能另一个时钟域的逻辑,结果因为分频时钟的占空比不是50%,导致使能信号宽度不够,逻辑没被正确触发。正确的做法是,用源时钟的上升沿去采样使能信号,确保时序正确。
时钟门控技术
时钟门控,是降低动态功耗最有效的手段之一。说白了,就是当模块不工作时,把时钟关掉。但这里有个陷阱:时钟门控不能产生毛刺。
基本结构,就是一个与门或者或门,加上一个锁存器。为什么需要锁存器?因为如果直接用组合逻辑门控时钟,使能信号在时钟高电平期间变化,就会在时钟输出上产生毛刺。毛刺会导致寄存器误触发,逻辑出错。
正确的做法是:用锁存器把使能信号锁存在时钟的低电平期间。这样,使能信号只在时钟低电平时变化,时钟高电平时保持稳定。输出时钟就不会有毛刺了。
// 时钟门控单元 Verilog 代码示例
module clk_gate (
input wire clk_in, // 输入时钟
input wire en, // 使能信号
output wire clk_out // 门控后的时钟
);
reg en_latched;
always @(negedge clk_in) begin
en_latched <= en;
end
assign clk_out = clk_in & en_latched;
endmodule
门控策略,我一般分三级:
- 模块级门控:整个模块不工作时,关掉所有时钟。比如基带处理器的某个加速器,在空闲时直接关掉。
- 功能级门控:模块内部,某个功能单元不工作时,关掉对应的时钟。比如DMA控制器,在传输完成后关掉时钟。
- 寄存器级门控:用综合工具自动插入门控单元。这需要RTL代码写得规范,使能信号要明确。
避坑指南: 我曾经在一个低功耗项目中,为了省功耗,把门控做得太细了。结果每个时钟周期都要判断使能信号,导致动态功耗没降多少,静态功耗反而因为门控单元太多而增加了。所以,门控的粒度要适中。我建议你,先做模块级门控,再根据功耗分析结果,决定是否做更细粒度的门控。
嗯,时钟生成单元的设计,今天就聊到这儿。PLL的配置和锁定是基础,分频和倍频是手段,时钟门控是功耗优化的关键。这三者结合起来,才能构建一个稳定、高效、低功耗的时钟系统。下次见。