做出一个干净的时钟
几乎你见过的每一颗数字芯片,都跟着一个 时钟 在前进——那是一列稳定的方波,一遍又一遍地说着*现在*,一秒钟说上十亿次。麻烦在于:这个*现在*是从哪里来的。石英晶振便宜、稳定又准确,但它只能在很低的频率振荡——往往只有几十兆赫兹。你的 CPU 想要吉赫兹;你的 USB 模块又想要另一个数;你的摄像头接口想要的,则完全是第三个数。你没法直接从货架上买一颗 3 GHz 的晶振,而且你也不会想在板子上撒一打晶振。
所以这件事的本质是倍频:拿一个又慢又可靠的参考,产出一个被锁定到它身上的快时钟——长期准确度一模一样,但频率随你挑。你可以把晶振想成走廊里那座又慢又可靠的落地钟,而把 PLL 想成一只走得飞快的手表,它不停地微调自己,好与那座落地钟踩在同一个节拍上。这只手表滴答得快得多,可一个小时下来却从不漂移,因为它一直回过头去对照那个又慢又诚实的参考。
压控振荡器
每一个 PLL 的核心,都是一个你能用电压去*操纵*其转速的振荡器。这就是 VCO:给它一个低的控制 电压,它就振荡得慢;把电压抬高,它就加速。它是这个环路的油门——一个旋钮,就定下了输出频率。
一个电路怎么把电压变成频率呢?片上最常见的招数是环形振荡器:把一串反相器接成一个环,级数取奇数,这样环路永远稳定不下来,被逼着一直翻转。每一级反相器都要花一点时间去给下一级的 电容 充放电,而这段延时就定下了周期。控制电压所做的,无非是调整每一级拿到多少 电流 去驱动那个电容——电流越大,充电越快,延时越短,频率越高。LC 振荡器(一个电感加一个电压可调的电容)做的是同一件事,但抖动小得多,这正是它在最苛刻的时钟场合更受青睐的原因。
* VCO behaviour, idealized as a linear tuning law: * f_out = f_0 + K_vco * V_ctrl * K_vco = VCO gain, in Hz per volt (the "sensitivity" of the gas pedal) * * The loop actually cares about PHASE, the integral of frequency: * phase(t) = 2*pi * integral( f_out dt ) * -> a VCO is an INTEGRATOR from control voltage to output phase.
把环路锁住:PLL
用一句话讲清整个思路:PLL 就是把 负反馈 用到了相位上,而不是电压上。如果你读过反馈那一篇,这里一切都能照搬——你只是换了一个要比较的量而已。它不再是"把输出电压和参考做比较,再纠正差值",PLL 说的是"把输出*相位*和参考相位做比较,再纠正差值"。
这个环路是由五个模块围成的一个环:一个鉴相器,量出两个时钟相差多远;一个电荷泵和环路滤波器,把这个测量结果变成一个平滑的控制电压;一个 [[voltage-controlled-oscillator|VCO]],把电压变成一个快时钟;还有一个 ÷N 分频器,把 VCO 的输出再放慢下来,好让它能和那个慢参考公平地比较。这个分频器,正是倍频的秘密所在。反馈只逼着*分频后*的时钟去匹配参考;于是全速的 VCO 输出,最后就跑得快了 N 倍。
* In lock, the divided clock equals the reference, in both frequency and phase: * f_out / N = f_ref -> f_out = N * f_ref * * Example: a 50 MHz crystal, divider N = 24 * f_out = 24 * 50 MHz = 1.2 GHz * Change N (in a register) and you re-tune the chip's clock with no new hardware.
鉴相器、电荷泵与滤波器
慢慢地走一遍这条纠正通路,因为 PLL 的成败正是在这里决定的。鉴频鉴相器(PFD) 把参考边沿和分频后的 VCO 边沿做比较,然后给出两个输出之一:如果 VCO 落后了(太慢),就发 *UP*;如果它超前了(太快),就发 *DOWN*。这些脉冲的宽度,正好编码了两个时钟差了多远。
接着,这些数字的 UP/DOWN 脉冲去驱动一个电荷泵:UP 往一个 电容 上倒进一包电荷,DOWN 取走一包。这个电容就是环路的记忆——它的电压是每一次纠正的累计总账,而这个电压恰好就是 VCO 的控制旋钮。这就是环路滤波器。它的任务,是把那一顿一顿、断断续续的电荷包,抹平成一个安稳、近乎直流的电压,因为那条线上剩下的任何纹波,都会被 K_vco 乘上去,直接变成 抖动。
- 参考边沿和分频后的 VCO 边沿到达鉴频鉴相器;哪个早、哪个晚,就决定发出 UP 还是 DOWN 脉冲,而脉冲的宽度就是相位误差。
- 电荷泵把这些脉冲转换成往环路滤波器电容上加入或取走的电荷。
- 环路滤波器(一个电容加一个小电阻,有时还更多)把这些电荷积分成一个缓慢变化的控制电压,并把每个周期的纹波抹平。
- VCO 把那个控制电压变成一个频率;分频器再把它放慢下来反馈回去,闭合这个环路,从而把相位误差逼向零。
抖动:时域里的噪声
在放大器里,噪声表现为你的信号之上那些多余的*电压*抖动。而在时钟里,信号*就是*边沿的时间位置——所以噪声表现为边沿来得早了一点或晚了一点。这种时间上的不确定性,就是[[jitter|抖动]],它不过是同一种物理噪声——你在噪声那一篇里见过的热噪声和闪烁噪声——在时域里的另一副面孔。抖动之于时钟,就如同电压噪声之于模拟信号:那是一道你无法许愿抹去、只能去管理的底线。
想象一个本该每隔正好一秒响一下的节拍器,实际上却在 0.998、1.003、0.999 秒响。它的平均值完美无缺,可没有哪一下单独的滴答是靠得住的。对一条数据链路来说,一个迟到的边沿,可能在错误的时刻去采样一个比特,把一个 0 翻成 1;抖动直接吃掉你的时序预算,并且封住了这条链路能跑多快的上限。
* .tran simulation is how jitter is actually measured in SPICE:
.tran 1p 2u ; 1 ps step, 2 us window
* Capture each clock edge's crossing time, then post-process:
* period jitter = stdev of (T_k - T_{k-1}) cycle-to-cycle variation
* RMS jitter = stdev of edge times vs an ideal grid
* Or view it in the frequency domain with a phase-noise (.ac/.noise) run,
* where the SAME noise appears as dBc/Hz skirts beside the carrier.PLL 都活在哪里
一旦你看出了这个套路,PLL 就到处都是。每一颗现代 SoC 里都有好几个:一个把晶振倍频到 CPU 的时钟,其余的则为内存、USB、PCIe、显示和射频各自生出时钟——每个模块都想要自己的速率,而它们全都派生自同一个诚实的参考。改一个分频寄存器,同一块硅片就重新调到一个新频率,手机正是这样在负载下把时钟拉高、又在省电时把它压低的。
PLL 能做的不止倍频。配上一个反馈分频器*再加*一个输入分频器,你就得到一个小数分频频率合成器——它是每一台收音机的心脏,想跳到哪个信道就跳到哪个信道。把 VCO 拿掉、改成喂进收来的数据,同一个环路就变成一个时钟数据恢复(CDR)电路,从一条串行数据流里把藏着的时钟提取出来。而延迟锁定环(DLL)则是它的近亲,用一条延迟线、而不是一个振荡器来对齐相位。每一次都是同一个原理:一个锁定到相位上的环路。