JOVANA
Library Glossary Getting Started Three Levels Fields How it works Mission
Join the mission
All guides

讓它跑得夠快:時序與約束

晶片的速度不是一種感覺,而是一筆以皮秒為單位的預算,你要嘛塞得進去,要嘛超支。本指南介紹決定你的設計能不能跑起來的三個角色:設定時脈上限的關鍵路徑、把「夠快了嗎?」變成非過即敗的裕量數值,以及靜態時序分析——這件工具一次性窮舉校驗你設計裡的每一條路徑,卻從不執行任何一項測試。讀完之後,你就能像看銀行對帳單一樣看一份時序報告:時間花到哪去了,我有沒有透支?

時脈設定預算

每一顆同步晶片都隨著一個時脈前進——一個方波,比方說每秒跳動十億次。把每個有效邊緣想成發令槍和截止線合而為一:在一個邊緣上,你的正反器把新資料發射到線上;到了緊接著的下一個邊緣,下游的正反器就抓取已經到達的東西。邏輯需要做的每一件事——它經過的每一個閘——都必須在一個時脈週期之內完成。那個視窗就是你的全部預算。

所以時脈週期設定了上限。一個 1 GHz 的時脈給你每一級1 奈秒的預算——也就是 1000 皮秒。想跑得更快?把週期縮短。但你沒法把它縮到比你那一堆最慢的邏輯真正需要穩定下來的時間還短。時脈只能快到你最慢的那條路徑所允許的程度。這種張力——把時脈往上推,但不能越過邏輯能完成的極限——就是整個時序遊戲的核心。

關鍵路徑

想像資料從一個暫存器流向下一個,穿過一叢組合邏輯——加法器、多工器、一疊疊邏輯閘。每個閘翻轉要花幾皮秒,每根線充電也要花時間。把從發射正反器到捕獲正反器這一條路上的延遲全加起來,你就得到了那條路徑的總傳播時間。你的設計裡可以有數以百萬計的這種路徑。

關鍵路徑就是最慢的那一條——裕量最差(最負)的路徑,也就是相對於發射正反器與捕獲正反器之間可用時間而言延遲最長的那一條。它之所以要緊,是因為它獨自決定了你的速度上限:時脈週期至少得和那條路徑所需的一樣長,否則資料還沒到,下一拍就來捕獲了。晶片只能和它最慢的那條路徑一樣快——就像一支車隊只能以它最慢那輛卡車的速度行進。

// Long combinational chain between two registers = a candidate critical path
always @(posedge clk) begin
  sum_q <= a + b + c + d;  // the adder tree here must settle within ONE period
end
在兩個時脈暫存器之間堆太多邏輯,那一段就會變成你的關鍵路徑。把工作拆到更多管線級裡,能縮短每一跳。

規模化的建立/保持 → STA

正反器對資料*什麼時候*到達很挑剔。資料必須在捕獲時脈邊緣之前穩定那麼一小段時間——這就是建立要求——並在邊緣之後也保持穩定一小段時間——這就是保持要求。錯過建立,資料到得太晚,沒法被可靠地捕獲;錯過保持,資料在邊緣之後變得太早,正反器還沒來得及安全鎖存舊的值。無論哪種,捕獲到的位元都不可靠——它可能陷入亞穩態。(完整圖景見建立與保持時間。)

現在把這件事乘上數百萬個正反器、數百萬條路徑。你根本不可能靠跑模擬來抓出每一個違規——你得在每一時刻餵進每一種輸入組合,那是毫無希望地不切實際。這正是靜態時序分析,也就是 STA,改變局面的地方。

STA 校驗時序完全不需要任何激勵。它不執行你的設計;它建構一張涵蓋每一條正反器到正反器路徑的圖,把每條路上的閘延遲和線延遲加起來,再拿這個總和去對照目的端的建立和保持要求。沒有測試向量,沒有波形——只是在這張延遲圖上做算術。正因為它是窮舉的數學而不是抽樣的模擬,STA 校驗每一條路徑,每一次都校驗,絕不會因為你忘了測某一條而漏掉它。(建立按慢角校驗,保持按快角校驗——製程角稍後再說。)

裕量:非過即敗

STA 是這樣把每條路徑化成一個判決的。對一次建立檢查,它算兩個數:到達時間(訊號實際出現在捕獲正反器的時刻)和要求時間(它*被允許*出現、同時仍滿足建立的最晚時刻)。兩者之差就是這條路徑的裕量

裕量 = 要求 − 到達 正裕量意味著訊號到達時還有餘裕——通過,而那個數告訴你你有多少餘量。零裕量意味著它正好壓在截止線上——剛剛好滿足。負裕量意味著它到得太晚——失敗。−50 ps 的裕量是說這條路徑超出預算 50 皮秒;晶片在這個時脈速度下跑不可靠。整個設計裡最差(最小)的那個裕量叫 WNS——最差負裕量——它就是那個讓你一眼看出自己過沒過的數。(保持檢查用的是同一個裕量思路,只不過那裡*太快*到達才是危險,所以算式翻轉:保持裕量 = 到達 − 要求。)

現在我們可以勾勒出速度上限了。把建立預算拆成它的各個部分,你能跑的最快時脈大致是:

f_max = 1 / (t_clk-to-q + t_logic + t_setup - t_skew)
最高頻率 = 1 除以關鍵路徑預算。t_clk-to-q 是發射正反器的時脈到輸出延遲,t_logic 是組合延遲,t_setup 是捕獲正反器的建立要求,t_skew 是時脈到達的偏差——當捕獲時脈晚到時它相減,因為那等於給了這條路徑額外的時間。把那些延遲項縮小,上限就抬高。

時脈偏斜與真正的預算

到目前為止,我們一直假裝時脈邊緣在完全相同的瞬間打到每一個正反器。它並不會。時脈在晶片上沿著真實的導線、穿過真實的緩衝器傳播,所以它到達某些正反器要早那麼一丁點,到達另一些則晚那麼一丁點。發射正反器的時脈與捕獲正反器的時脈之間這個到達時間的差,就是時脈偏斜——也就是上面公式裡的 `t_skew` 項。

偏斜是把雙面刃。如果捕獲時脈相對發射時脈晚到,它會慷慨地給你的資料一點額外的到達時間——偏斜幫了你的建立檢查。但同樣這個遲到的捕獲邊緣會從你的保持餘量裡偷走一塊,因為現在新資料有更長的時間衝向一個還沒鎖存的正反器。救了建立的偏斜可能毀掉保持——這也是為什麼保持違規有時更難纏:把時脈放慢解決不了它們,因為保持是一場同一邊緣上的競賽,跟時脈週期無關。

收斂時序

收斂時序」是從業者對那場苦工的說法:把每一條路徑的裕量都趕到零或為正——任何地方都沒有負裕量,建立和保持都乾乾淨淨,跨越所有工作製程角(高溫、低溫、快矽、慢矽,以及電壓的極端)。在時序收斂之前,這個設計不應該流片;一顆通不過時序的晶片,就是一顆有可能在高速下算出錯誤答案的晶片。

  1. 跑 STA,找出最差負裕量(WNS)——失敗得最厲害的那條路徑。
  2. 攻擊那條關鍵路徑:簡化邏輯、換上更快的標準單元、調整閘的尺寸,或加緩衝器去驅動長線。
  3. 如果邏輯確實塞不進一個週期,就把它拆到更多管線級裡,讓每一跳少幹一點活。
  4. 再跑一遍 STA——修好最差的那條,通常會把*一條新的*路徑頂上關鍵位置。重複。
  5. 循環下去,直到建立*和*保持在每一個製程角下 WNS ≥ 0。這時時序就收斂了。

拉遠來看,這個循環始終是同一個:時脈交給你一筆預算,關鍵路徑花掉其中最多的,STA 拿著截止線去稽核每一條路徑,而裕量就是那張收據。讓裕量在每個地方都非負,晶片就能跑。這就是一口氣說完的時序收斂。