沒有附節拍器的鼓手
想像一位爵士鼓手為地球另一端的樂團錄了一段鼓。有禮貌的作法是隨鼓附上一條穩定的節拍器點擊聲,讓大家同步演奏。但這鼓手很摳,而線路又很貴,於是他只送了鼓聲。樂團的任務就是從這些敲擊中*感受*節奏——鎖定那個拍子並跟著打,即使鼓手忽快忽慢。這正是 SerDes 接收端面對的難題。發送端把一串序列化的位元送進一對差動線,卻沒有附上任何一條時脈線。
在第三關你見過眼圖——把每個位元週期疊在一起所形成的那個發光菱形。眼圖告訴你有一段時間視窗,也就是眼開度,在那裡訊號明確地為高或為低。要正確回復資料,接收端必須在眼睛正中央進行取樣,因為那裡電壓裕度最寬、時序裕度最寬容。一旦錯過中心,你就滑向邊緣——線跡交叉、眼睛被夾合,一與零就成了擲銅板。整個時脈與資料回復的藝術,就是讓每一個位元的判決時刻,都落在那個菱形的正中間。
一個追逐邊緣的迴路
你要怎麼造一個電路,去跟著一個它從未聽過的拍子打?你建一個迴授迴路,並交給它三項工作:*猜*一個時脈、*量*這個猜測錯了多少、再*修正*它——永無止境。這其實就是一個換了頂帽子的鎖相迴路(PLL)。其核心是一顆壓控振盪器(VCO)——一種你可以用控制電壓把頻率往上或往下推的振盪器。VCO 產生接收端對時脈的最佳猜測。一個相位偵測器把進來的資料邊緣與這個回復時脈的邊緣相比,回答一個問題:*我取樣得太早,還是太晚?*
偵測器的裁決——太早或太晚——經由迴路濾波器平滑成一個控制電壓,送進 VCO。若取樣偏早,迴路就把 VCO 稍微放慢,讓它的邊緣往資料邊緣方向漂回去;若偏晚,就加快。如此一圈又一圈,一微秒內數以百萬次的修正,直到回復時脈的邊緣*恰好*落在離資料邊緣半個位元的位置——也就是說,取樣時刻正好落在眼睛的死中央。當這一切穩定下來,我們就說迴路鎖定了。
data in ──────────►┌──────────────┐
(transitions) │ PHASE │ early / late
┌─────►│ DETECTOR │──────┐
│ └──────────────┘ ▼
│ ┌─────────────┐
│ │ LOOP FILTER │ (charge pump
│ │ (R + C) │ + capacitor)
│ └─────┬───────┘
│ │ control voltage
│ ┌─────▼───────┐
recovered clk └──────────────────────┤ VCO │
(to samplers) feedback └─────────────┘
Lock condition: recovered-clock edge sits 1/2 bit
after each data edge ⇒ sampler fires at eye center.Bang-Bang 對線性:兩種「太早還太晚?」的問法
相位偵測器有兩大家族,差別在於你問的是偏離了*多少*,還是只問偏向*哪一邊*。線性偵測器(經典的 Hogge)輸出一個脈衝,其寬度與相位誤差成正比——這是離中心距離的真正類比量測。它資訊豐富,但需要細膩的類比設計。另一個家族,在現代多 Gb 連結中佔主導地位,是 bang-bang(Alexander)偵測器。它每個位元取三個樣本——一個在資料中央、兩個在邊緣——只問一個二元問題:時脈邊緣比資料邊緣先到還是後到?太早或太晚,中間沒有灰色地帶。
Alexander (bang-bang) sampling, 3 phases per bit:
e0 d e1
│ │ │
────┴────╳────┴────╳────┴──── data with two edges
▲ edge ▲ edge ▲
edge-smp data-smp edge-smp
Decision rule (per transition):
if e0 != d -> clock is LATE (edge sample already flipped)
if d != e1 -> clock is EARLY (flips before next edge)
if no transition -> HOLD (no info this bit)
Output is just +1 / -1 / 0 — a quantized, noisy nudge.為什麼一個粗糙的一位元答案會勝出?因為在 56 GBd 下,造一個穩健、能說「偏左還偏右」的比較器,遠比造一個能說「偏左 1.8 皮秒」的類比電路容易得多。代價是抖動(dither):即使完美置中,bang-bang 迴路仍會以一個量化步階左右來回獵尋,自己產生一點點稱為 dither jitter 的抖動。設計者讓每一步修正極小來馴服它——這就是數位版的「輕點方向盤而非猛打」。
迴路頻寬:統御一切的那一顆旋鈕
現在來談 CDR 中最深刻的概念。迴路該*多快*去追逐資料?把迴路頻寬調高,回復時脈就會跟上進來邊緣的每一次擺動——當發送端時脈真的在遊走時這很好,但也很糟,因為它會忠實地複製高頻雜訊,把取樣點拖離中心。把頻寬調低,迴路就沉穩、能漂亮地抑制快速抖動——但它反應遲鈍,若訊源頻率緩慢漂移,迴路就跟不上,眼睛會從取樣器底下走掉。迴路頻寬是唯一一顆在追蹤與抖動抑制之間權衡的旋鈕,天下沒有白吃的午餐。
看清這件事最乾淨的方式:CDR 對抖動而言是一個高通濾波器。比迴路頻寬慢的抖動,迴路會*追蹤*它——時脈隨資料一起動,所以那種抖動無害。比迴路頻寬快的抖動,迴路會*抑制*它——它來不及反應,時脈按兵不動,於是那種抖動就直接吃進眼圖裡你的時序裕度。像 PCIe 與 OIF-CEI 這類規範把這個轉角釘得很死,常把 CDR 頻寬定在約位元率的 1/1667(並要求一個明確的斜率,例如二階、40 dB/decade),好讓不同廠商的發送端與接收端,對於「哪些抖動是連結的問題、哪些是晶片的問題」達成精確共識。
Jitter transfer of a CDR (how much input jitter reaches the clock):
gain │
1.0 ─┤━━━━━━━━━━━━━━━● ← slow jitter: clock TRACKS it
│ ╲ (passes through, harmless)
│ ╲
│ ╲ -40 dB/dec
0.1 ─┤ ╲
│ ╲___ ← fast jitter: clock REJECTS it
│ ╲ (blocked, hits eye margin)
└────────────────┸────────────► jitter frequency
f_loop
(loop bandwidth)
Mirror view — JITTER TOLERANCE (how much input jitter the
link survives): HIGH at low freq (tracked away), drops to a
flat floor at high freq set by the eye opening.抖動容忍度,並把它接回 BER
工程師用一個叫抖動容忍度的酷刑測試來認證接收端:刻意在進來的資料上、一個頻率接一個頻率地注入正弦抖動,把振幅一路加大,直到連結開始出錯,記下那個極限。把這些極限畫出來,就得到規範要求的抖動容忍度遮罩。它的形狀很說明問題:在低頻,你可以灌進*巨量*抖動——好幾個單位間隔之多——因為 CDR 直接追蹤它、時脈跟著走。當抖動頻率爬升越過迴路頻寬,容忍度便急遽下墜,最後攤平到一個地板,那地板由ISI與等化處理完之後、眼睛裡還剩多少時序空間所決定。
- 回復頻率。 開機時迴路根本不知道位元率。它先鎖定 VCO 的頻率,通常借助一個乾淨的參考時脈與頻率偵測器——這是*擷取(acquisition)*階段。
- 擷取相位。 把控制權交給相位偵測器。迴路把取樣時脈一步步挪動,直到它的邊緣落在離資料邊緣半個位元處——取樣器此刻便在眼睛中央觸發。
- 永遠追蹤。 在訊源漂移(溫度、電源、展頻時脈)時維持鎖定。迴路頻寬決定你追隨那漂移有多積極。
- 放置取樣點。 每一位元,回復的時脈在眼睛中央觸發取樣器/判決器;這一連串判決就是回復出的資料。
這裡就是把整條連結綁在一起的回報。SerDes 的品質指標是它的位元錯誤率(BER)——常常嚴苛到 10⁻¹² 或更好,一兆位元才錯一個。BER 取決於取樣時刻離那充滿雜訊與抖動的眼緣有多遠。一個鎖在真正中心、頻寬調得既能追蹤真實漂移又能抑制高頻抖動的 CDR,會把取樣器保持在眼睛最肥的部位,把 BER 壓下去。一個沒對準中心的 CDR——頻寬太小(漂移把眼睛走掉)或太大(把抖動複製回來)——會把取樣點推向眼緣,BER 隨之爆炸。等化打開眼睛;CDR 確保你從它的正中央看過去。 兩者都做對,一條被打得遍體鱗傷、損耗嚴重的通道,依然能載著一兆個乾淨的位元。
把迴路寫在紙上
為了讓「迴路頻寬」不那麼玄,這裡是一個數位 bang-bang CDR 的行為層草稿——你在投片之前會先用它來建模。注意餵給相位的兩條路徑:一條快速的比例項(立即的微調)與一條緩慢的積分項(累積的頻率偏移)。它們的相對權重*就是*迴路頻寬與阻尼;調這兩個數字,是 CDR 設計中影響最深遠的單一決定。
// Behavioral bang-bang CDR — one sample (data) per bit.
// phase is in fractions of a unit interval (UI); 0.5 == eye center.
float Kp = 1.0/256; // proportional gain -> loop BANDWIDTH
float Ki = 1.0/65536; // integral gain -> tracks frequency drift
float phase = 0.5; // sampling position within the bit
float freq = 0.0; // accumulated frequency offset (the 'memory')
void on_each_bit(int edge_smp, int data_smp, int prev_data) {
if (prev_data == data_smp) return; // no transition: HOLD, no info
// Alexander rule: edge sample vs the two data bits it sits between
int bb = (edge_smp == prev_data) ? +1 // sampling EARLY -> slow down
: -1; // sampling LATE -> speed up
freq += Ki * bb; // integral path (slow, frequency)
phase += Kp * bb + freq; // proportional + integral
if (phase >= 1.0) phase -= 1.0; // wrap within one UI
if (phase < 0.0) phase += 1.0;
// 'phase' now drives the interpolated sampling clock toward eye center.
}
// Bigger Kp -> wider loop bandwidth -> tracks more, rejects less jitter.
// Smaller Kp -> narrower bandwidth -> calm, but slow to chase drift.這寥寥幾行藏著一個優美的真相:同一個比例—積分結構,統御著定速巡航的汽車、恆溫器,以及一個鎖定電台的PLL。CDR 不過就是那個放諸四海皆準的迴授迴路,把它對準一條資料流的邊緣,要求它每秒鐘謙卑地做一件事一千億次——找到節拍,並在它的正中央取樣。