紙上談兵 vs 矽上見真章
在數位前端課程裡,你檢查時序的方式,就像都市規劃師對著一張嶄新藍圖估算行車時間:每條路都筆直、平整,車流都跑在速限上。那時的導線是理想的——沒有電阻、沒有電容,訊號從一個閘瞬間蹦到下一個閘,毫無拖滯。對於入門來說,這種簡化是對的,也大致是你的工具在設計還沒佈局、還沒繞線之前所做的假設。可矽晶片不是藍圖,它是一座有真實道路的真實城市。
一旦你的設計被實實在在地造了出來——單元佈局好了,導線在層層堆疊的金屬層上繞線好了——每條導線都成了一個真實的、有形的東西,帶著兩個甩不掉的特性。它有電阻(R):金屬會阻擾電流的流動,就像一根細管掐住水流。它也有電容(C):導線和它的鄰居會儲存電荷,就像一只你必須先灌滿的水桶,遠端的電壓才會升起來。要把一條導線從 0 翻到 1,你不是在撥一個位元——你是在透過一根管子去灌滿一只水桶。這要花時間,而這段時間如今就是你延遲的一部分。
寄生參數萃取(R 與 C)
寄生參數萃取這一步,把你完成的佈局圖變成數字。萃取工具會讀取每一條已繞線導線的精確幾何形狀——它有多長、多寬、跑在哪一層金屬層上、離鄰居有多近——再算出每一段的電阻和電容。想像你拿著捲尺量遍城裡的每一條路,把每條路有多窄、多長都記下來;萃取要一次性對幾百萬段導線做這件事,而且依據的是實際建成的佈局圖,而不是估算。
結果會被寫進一個標準檔案,叫做 SPEF(標準寄生參數交換格式)。你可以把它看成你晶片繞線的竣工測繪:一張巨大的表格,寫著*這條網路有這麼多 R、這麼多 C,分布在這些線段上*。關鍵在於,這是繞線後的資料——它反映的是真正存在的導線,而不是工具在佈局時用的那個粗略估計。正是這份 SPEF,讓下一步變得貨真價實。
# Extraction consumes the routed layout + a parasitic model, emits SPEF
extract_parasitics \
-layout routed.def \
-tech rc_corner.techfile \
-output design.spef ;# R + C per net, fed into signoff STA
# A SPEF line, simplified: net 'clk_buf_out' carries ~12 fF of C and ~8 ohm of R
# *D_NET clk_buf_out 12.4 ;# total cap in femtofarads為什麼繞線後的時序才是真正的時序
現在,我們把那份 SPEF 餵回靜態時序分析。還記得前端課程裡那張 f_max 的圖景嗎?你能跑的最快時鐘大致是:
f_max = 1 / (t_clk-to-q + t_logic + t_setup - t_skew)
在前端課程裡,t_logic 只是路徑上的閘延遲,因為那時導線是理想的——瞬間傳導。現在你萃取了寄生參數,t_logic 也背上了真實的導線延遲:沿途每一次透過管子灌滿水桶。在先進節點上,導線那一部分可能佔主導。同一條路徑,在理想導線上看著還很寬裕,一旦把金屬算進來,就可能把預算撐爆。這不是意外;這正是關鍵所在。
這正是為什麼繞線後、考慮寄生參數的 STA 才是權威的時序檢查——是真正算數的那一個。基於估算導線的繞線前時序是有用的早期指引,就像開車前先在地圖上看一眼路線。可地圖並不知道路上的施工、坡道和車流。只有實際建成的數字,才能告訴你晶片到底能不能滿足它的時鐘。這之前的一切都是排練;[[timing-signoff|簽核]]才是正式演出。
製程角:PVT 與 MMMC
問題在這兒:產線上沒有兩顆晶片是一模一樣的,也沒有哪顆晶片只在單一環境裡運行。有三樣東西會變,合起來叫 PVT。製程(Process,P):製造的離散性讓電晶體做出來或快一點或慢一點——這就是*快*製程角和*慢*製程角。電壓(Voltage,V):供電會略微下垂或抬升;電壓越低,電晶體越慢。溫度(Temperature,T):溫度會改變電晶體開關的快慢。一個製程角,就是這幾樣的某一種特定的最壞組合——一個你的晶片必須挺過去的具名情景。
為什麼要查製程角,而不是只跑一次標稱值?因為你出貨的不是一顆晶片——而是幾百萬顆,進到滾燙的手機裡、冰冷的伺服器裡,落在體質好的矽片上、也落在勉強及格的矽片上。如果時序只在典型情況下收斂,那現場就會有相當一部分元件失效。所以你要查的是極端。這裡的關鍵洞見是:建立時間和保持時間會在*相反*的製程角失敗:
- 建立時間(資料到得太晚)在慢角最糟——慢製程、低電壓,再加上讓那條路徑最慢的那個溫度。如果資料在這裡都能趕到,那它在哪兒都能趕到。
- 保持時間(資料到得太早,搶在捕捉邊緣之前衝了過去)在快角最糟——快製程、高電壓。對保持時間來說,體質快的矽片才是*危險*的那一種,因為資料會一路狂奔,可能反超時鐘。
- 每個製程角都配上與之匹配的萃取 SPEF——慢角的建立時間檢查配慢 RC 導線,快角的保持時間檢查配快 RC 導線——這樣導線延遲才和電晶體速度保持一致。
一個製程角一個製程角地這麼查,又慢又容易出錯,所以簽核用的是 MMMC——多模式多製程角(Multi-Mode Multi-Corner)。*多製程角*就是上面那一攤 PVT 的分布。*多模式*指的是你晶片的不同工作模式——全速模式、低功耗模式、測試模式——每一種都有自己的時鐘設定和約束。MMMC 會在一次分析中,讓每一種模式都對上每一個相關的製程角,這樣一個對某個情景有幫助的修改,就沒法悄悄地把另一個情景弄壞。你簽核的不是一顆晶片;你簽核的是模式 × 製程角的整張網格。
# An MMMC setup pairs each timing 'view' with its corner + SPEF + constraints create_clock -name clk -period 1.0 [get_ports clk] ;# 1 ns => 1 GHz target # slow corner drives the SETUP check (data must still arrive in time here) create_view view_slow -corner ss_0p72v_125c -spef slow.spef -check setup # fast corner drives the HOLD check (data must NOT race ahead here) create_view view_fast -corner ff_0p88v_m40c -spef fast.spef -check hold
晶片內變異
製程角管的是晶片*之間*的變異。但變異也會發生在*同一顆晶片內部*:兩個一模一樣的單元並排放著,開關速度也不會完全一樣,原因在於摻雜、線條邊緣、局部發熱和供電上的微觀差異。這就是[[on-chip-variation|晶片內變異]],即 OCV。同一個時鐘邊緣,可能比鄰居早那麼一丁點抵達某個正反器,哪怕繞線看上去是對稱的。給整片晶圓只挑一個製程角的數字,就會無視這一點——而假裝晶片上每個單元都一模一樣,恰恰是那種會讓晶片從晶圓廠壞著回來的樂觀。
對策是降額(de-rating):刻意地、悲觀地去調整延遲,讓分析假設的是那個倒楣的情況。對建立時間檢查,你把資料路徑調得比標稱值慢一點,把捕捉時鐘路徑調得快一點——從兩頭一起擠壓預算。對保持時間檢查,你把它反過來:發射路徑跑得快,捕捉時鐘跑得慢,把任何競爭都暴露出來。你同時對兩邊都施加這份懷疑,這樣這條路徑就必須挺過最壞的、合乎情理的失配,而不只是平均情況。
# Classic OCV: de-rate late paths slower, early paths faster (worst-case both ways) set_timing_derate -late 1.05 ;# late paths run +5% slower than nominal set_timing_derate -early 0.95 ;# early paths run -5% faster than nominal
裕量,簽核定案
在萃取、所有製程角、所有模式以及 OCV 降額都做完之後,每一項時序檢查最終仍會收攏到你在前端課程裡見過的那一個數字——只不過這一次,它是掙來的。裕量,就是訊號*被要求到達*的時刻與它*實際到達*的時刻之間的餘量:
slack = required - arrival ;# must be >= 0 to sign off # slack > 0 : pass, with margin to spare # slack = 0 : exactly on the deadline # slack < 0 : FAIL — the path violates timing at this corner
簽核的規則既不留情面又很簡單:在每一條路徑、每一種模式、每一個製程角、加上 OCV 之後,建立時間和保持時間的裕量都必須 ≥ 0。這張網格裡只要哪兒出現一個負數,晶片就沒簽核通過。最差的那一個裕量是 WNS(最差負裕量);所有失敗路徑加總起來是 TNS(總負裕量)。WNS 告訴你最差那條路徑有多糟;TNS 告訴你到底有*多少*條路徑在受傷。兩個你都要看。
收斂閉環與 ECO
萬一簽核查出了負裕量怎麼辦?你不會從頭把整個佈局繞線重做一遍——到了這個階段,佈局圖大體上已經乾淨、已經DRC正確了,你也不想去驚動那成千上萬條已經通過的路徑。你要做的,是一處微小而精準的改動:一個 [[engineering-change-order|ECO]](工程變更單,Engineering Change Order)。ECO 是對網表和佈局圖的一次最小限度的修改,它在修好違例的同時,盡可能少地碰到其它東西——就像連夜補好一條裂開的路,而不是把整座城市重建。
典型的 ECO 手法:把一個單元換成更快(驅動能力更強)的型號,把建立時間的裕量贏回來;或者插入一個延遲緩衝器,靠拖慢一條太心急的路徑,來修掉保持時間的違例。工具會在出問題的單元附近找到空位,只對它擾動到的那幾條網路重新繞線。然後——而這正是讓它成為一個*閉環*的地方——你要針對改動過的部分重新萃取寄生參數,並重跑簽核 STA,因為你的修改自己也帶來了新的導線、新的 RC。只有重新萃取之後,那些數字才是真的。
- 跑一遍完整的簽核 STA——萃取的寄生參數、所有模式、所有製程角、加上 OCV——把每一條帶負裕量的路徑都收集起來(按 WNS 從最差的排起)。
- 產生一個針對這些違例的 ECO:為建立時間調整單元尺寸或更換單元,為保持時間插入延遲緩衝器,並挑選那些不會弄壞已通過路徑的修法。
- 把這個 ECO 套用到網表和佈局圖上,只對改動過的單元和網路做佈局和繞線。
- 對受影響的部分重新萃取寄生參數——這次修改挪動了金屬,RC 也就變了——再寫出一份新的 SPEF。
- 重跑簽核 STA。確認被針對的那些路徑現在通過了,而且這次修改沒有把鄰近的某條路徑推成負的。
- 如此反覆,直到在每一種模式、每一個製程角下,建立時間和保持時間的 WNS 都 ≥ 0。此時時序就收斂了——設計便可以朝著實體驗證和流片(tapeout)推進。