做出一個乾淨的時脈
幾乎你見過的每一顆數位晶片,都跟著一個 時脈 在前進——那是一列穩定的方波,一遍又一遍地說著*現在*,一秒鐘說上十億次。麻煩在於:這個*現在*是從哪裡來的。石英晶振便宜、穩定又準確,但它只能在很低的頻率振盪——往往只有幾十兆赫茲。你的 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)則是它的近親,用一條延遲線、而不是一個振盪器來對齊相位。每一次都是同一個原理:一個鎖定到相位上的迴路。