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

擺放一百萬個單元

平面規劃把房間佈置好之後,工具就得把成十萬、有時上百萬個微小的邏輯單元一一塞進去——而每個單元落在哪裡,決定了你的晶片是否夠快、能不能繞線、甚至能不能造得出來。本指南帶你從最初的粗略撒點,一路走到乾淨、合法的佈局,並教你像看氣象預報一樣去讀懂一張壅塞圖。先講直覺,把幾何形狀用文字描繪出來,再配上恰好夠用、驅動工具運轉的那幾個數字。

從平面規劃到單元的汪洋

上一篇指南裡你搭好了平面規劃——你定下晶片的外形輪廓,把大塊(記憶體、類比孤島)停放就位,並畫出了供電網的環與條帶。把它想像成一間空蕩蕩的開放式辦公室:牆立起來了,電梯和供電管道也鋪好了,可一張桌子都還沒擺。佈局這一步要做的,就是把桌子搬進來——而且數量*多得很*。

這些桌子就是標準單元:那些小巧、事先設計好的邏輯積木(一個 AND 閘、一個正反器、一個緩衝器),由你的合成工具產出。每個單元都做成同樣的高度,於是它們能像書架上的書一樣卡進一條條水平的列;但寬度會隨它承載的邏輯多寡而不同。一個實際的區塊可以容納幾十萬到幾百萬個這樣的單元。佈局要為它們之中的每一個決定 (x, y) 安身之處。

而且佈局並非憑空進行——它必須為後面繞線階段要走的線留出空間,繞開平面規劃預留的阻擋區,並尊重標準單元必須對齊的那些列。一旦做錯,無論流程的其餘部分多麼巧妙,晶片都會無法繞線或時序失敗。這正是佈局位於前段、且至關重要的原因。

全域佈局與詳細佈局

工具不會一口氣把一百萬個單元放到它們的最終位置——這個問題太龐大了,沒法精確求解。它轉而分兩遍來做,先粗後細,就像你會先決定每件家具放進*哪個房間*,然後再把每把椅子推到位。

全域佈局是粗略的那一遍。它幾乎把單元當成流體來處理:把它們鋪展到整片區域上,大致平衡密度、並把有連接關係的單元拉到一起,最佳化的是一個把總線長和擁擠程度揉在一起的成本函數。在這個階段,單元可以坐在*任何地方*——它們可以重疊,也還不必和列對齊。目標是一個整體上良好的排布,而不是一個可製造的排布。

詳細佈局是精細的那一遍。它接過那團粗略的雲,把每個單元輕推到一個真實、合法的安身處——卡進某一列、對齊到佈局網格、彼此不重疊——同時盡量少擾動全域的格局。它做的是局部清理:交換相鄰單元、讓單元沿列滑動、填補空隙。可以把全域佈局想成是在劃分街區,而詳細佈局則是把每輛車端端正正地停進車位線之間。

密度與壅塞

有兩個詞聽起來很像,含義卻大不相同,把它們搞混是新手的經典陷阱。密度(或使用率)講的是*地面空間*——可用面積裡有多少被單元填滿了。壅塞講的是*線*——有多少連接想穿過某個區域,對比那裡實際容得下多少繞線軌道。兩者完全可以一個高、一個不高。

使用率是個簡單而老實的數字:可佈局面積裡被單元佔用的那一部分。

utilization = (total cell area) / (placeable row area)

# e.g. 0.72  ->  72% full, ~28% left as breathing room
# typical placement target ~0.60-0.80 depending on the design
使用率不過就是「房間有多滿」。塞得太緊,就沒有餘地留給緩衝器、時脈單元,以及後面繞線要硬擠進去的那些線了。

微妙之處在這裡:一個區域可能只是適中地滿,卻已經無可救藥地壅塞了,因為一團連接密集的單元正好落在那兒,想穿過那塊小格子的線,遠多於能承載它們的金屬軌道數。這就好比一個停了七成滿的停車場(沒問題),和一個所有車都想同時擠出去的唯一出口(徹底堵死)之間的差別。佈局兩者都盯著,因為後面的繞線只有在線真的塞得下時才能成功。

由時序驅動的佈局

到目前為止我們談的都是空間和線。但佈局還是懂時序的——這可以說是它最重要的本職。記住,訊號沿一條線傳播是需要時間的,線越長意味著延遲越大。於是工具會讀取時序約束,盡量把處在緊張路徑上的單元在物理上挨近放,縮短它們之間的連線。

最要緊的那條路徑就是關鍵路徑:兩個暫存器之間最慢的那條通路,也是富餘裕度最少的一條。如果佈局讓一條關鍵路徑上的單元漂得很遠,單單線延遲就能撐爆你的時序預算——而且後續再怎麼最佳化也無法完全挽回。於是工具會給這些單元一種磁吸般的吸引力,在仍然兼顧密度和壅塞的前提下,把它們拉緊。

下面就是工具在佈局時要對標的時序目標——一個時脈週期,它必須把每一條暫存器到暫存器的路徑都塞進這個週期之內:

# Clock the design is placed to honor (vendor-neutral SDC)
create_clock -name CLK -period 1.25 [get_ports clk]   ;# 800 MHz

# A signal launched at one register must arrive at the next
# WITHIN one period (minus setup) — placement keeps the cells
# on each path close so wire delay does not eat that budget.
時脈週期就是截止期限。佈局會縮短最緊張那些路徑上的連線,讓訊號仍能及時從一個正反器趕到下一個。

合法化

經過全域佈局和詳細佈局之後,單元*差不多*都各就各位了——但仍有少數可能重疊了一絲絲、偏離網格一星半點,或者跨在兩列的邊界上。合法化就是那道收尾整理的工序,把佈局弄得嚴格*合法*:每個單元都卡進某一列、對齊到製造網格、緊貼著鄰居放好,既不重疊,也沒有非法的空隙。

想像一堆胡亂塞上書架的書,有的歪著,有的探出了邊緣。合法化就是那位圖書館員,把每一本都推到端端正正地立在架子上、書脊對齊、彼此不疊。關鍵在於,它會盡量讓每個單元移動*最小*的距離來擺正它——因為它每挪動一個單元都會改變線長,可能擾亂前面幾遍辛辛苦苦才達成的時序。

  1. 跑全域佈局:把單元鋪展開以平衡密度、並把有連接關係的單元拉到一起,允許重疊和偏離網格的位置——這是粗稿。
  2. 跑詳細佈局:把單元輕推到各列上、形成乾淨的局部排布,在不擾動全域格局的前提下精修線長和壅塞。
  3. 做合法化:把每個單元卡到合法的列與網格位置上、互不重疊,每個都移動最小距離,讓時序和壅塞盡量貼近前幾遍得到的結果。
  4. 在如今已合法的佈局上重新核查時序和壅塞;若某個區域變差了,工具可以在交給時脈樹合成和繞線之前,對那裡做局部的重佈局和重合法化。

讀懂一張壅塞圖

在工具的圖形介面裡打開一份佈局、叫出一張壅塞圖,你會看到一幅活脫脫像是蓋在晶片上的氣象雷達圖。整片晶粒被切成一格格的小磚片,每片磚片按其繞線的擁擠程度被染上顏色——具體來說,是按需求與供給之比:有多少線想穿過那片磚片,對比有多少金屬軌道可供承載。

# Per-tile congestion (the number behind each color)
overflow = wires_demanded - tracks_available

#   overflow <= 0   ->  cool (blue/green): wires fit, healthy
#   overflow  > 0   ->  hot  (yellow/red): more wires than tracks -> trouble
每一片有色磚片不過就是需求減去供給。冷色表示線塞得下;暖色表示太多線想擠過太少的軌道。

所以你就像看熱度一樣去讀它:大片的藍色和綠色是平靜、健康、可繞線的——線寬寬鬆鬆就放得下。黃色是開始緊張了。怒氣沖沖的紅色和橙色斑塊則是熱點,那裡繞線很可能會失敗,因為想穿過的線多過能容納它們的軌道。一份好的佈局看上去大體是冷色而均勻的;一片紅海,或是幾處兇狠的斑塊,就是你還沒開始繞線之前的一記警告。

是什麼造成了一團紅?往往是一團連接密集的邏輯被塞得太緊、是許多線不得不從一個硬核巨集單元旁擠著漏過去的地方,或是平面規劃在某個角落把繞線空間餓瘦了。解法呼應著前面幾節:讓工具把那片磚片裡的單元鋪開以降低局部密度、添加或調整佈局阻擋區把單元引開,或者當某個巨集單元卡住了一整條通道時,回頭重做平面規劃。