故事是這樣的,最近小弟在公司接了一個專案,使用的製程只有 3 層金屬,跟之前使用過的如 .18 有 5 層金屬、90 nm 有 9 層、40 nm 有 10 層(嚴格來說也只有九層)相差甚遠,也因此造成一堆 innovus layout 上的問題, 值得寫篇文好好記錄一下。

為什麼要用這麼少層的金屬!

因為1P3M是個好製程 就一個字:錢。
晶片製程多一層金屬就是多兩片光罩(Via 一片,一層金屬一片),加光罩就是要加錢;就我查找的消息, 1P4M 比 1P3M 還要貴了 30% 左右。

如果用我有限的知識去猜測,平面型的 MOSFET 主要的光罩數如下:

  • MOSFET 區域製作 Gate 一層
  • 製作 Source Drain 一層或兩層,看 source drain 要不要分開做
  • 製作 contact 一層
  • 一層金屬即兩層光罩,走線一層、Via (穿孔) 一層
  • 最上層金屬只有一層沒有 Via

因此 1P3M 大概是 (3,4)+2+2+1 共 (8,9) 層;1P4M 則是加兩層共 (10,11) 層,估算成本會多 22-25% 左右。

在 synthesis 要準備什麼?

在高運算密度的設計,要用這麼少層的金屬,會建議在 synthesis 先把 input 超過 4 的 logic cell 全部禁用,例如 OAI22、NOR4、AND4 等。
為什麼要做這件事呢?因為邏輯元件的密度一般做得很高,input 4 以上的 cell 在單位面積內的接點數量太多了,會造成 APR 在繞線時繞不出來。
如果不做特別設定,就要把 utilization rate 設到比較小,面積會直接噴掉(因為面積是 U rate 的倒數,U rate 愈小會愈敏感)。

解法如這篇手把手教你如何在Innovus中解决local congestion问题 所示:

  1. innovus 在 place 的時候就先注意到 congestion 的問題,這次我沒試過,不確定效果如何
  2. 在 innovus 針對這些高密度 cell 設定 padding 值,預留多一些空間給它們
  3. 如這次建議的,直接在 synthesis 階段就不使用這些 cell

反正用方法 2 還是要再設定一次不如用方法 3 從一開始就不要用,這樣做代價是面積會上升,大概增加了 8%。

實際作法是先去看 standard cell 的文件,把需要禁用的 cell 挑出來,再來在 dc_shell 中輸入:

read_lib typical.lib
read_db typical.db
set lib_cells [get_lib_cells $lib/*]
foreach_in_collection lib_cell $lib_cells {
  echo "[get_attr $lib_cell full_name]"
}

read_lib 或是 read_db 可以二選一,要搞到這麼麻煩是因為 get_lib_cells 通常絕對長到螢幕寫不下的程度。

之後就把對應的 cell 設定 don’t use。

set_dont_use [get_lib_cells $lib/XXX]
set_dont_use [get_lib_cells $lib/YYY]

禁用時也可以用 wildcard *,但請自己注意會不會禁用到不想禁用的 cell。

就我這次測試的經驗,大約整理成下表,可見得禁用 cell 對 1P3M 提升 Utilization rate 十分有助益, 對 1P4M 來說就沒特別需要禁用 cells 了。

使用設定 APR 結果
1P3M 不禁用 cells utilization rate 0.4 才能繞出
1P3M 禁用 cells utilization rate 0.64 可以繞出
1P4M 不禁用 cells utilization rate 0.77 可以繞出

另外可以注意一下 DFF 這種時序元件是不用禁用的,其一當然是 DFF 不像邏輯電路,複雜邏輯沒提供就用簡單邏輯去組; 其二 DFF 通常面積都滿大的,就算有五支腳還是能讓走線密度壓低。

以上大致是 design compiler 需要做的設定,我倒想到一個很有趣的應用;如果我把所有的 logic cell 除了 NAND 全部禁掉,是不是可以讓 design compiler 一秒幫我完成 Nand2Tetris XDD。

APR Density

下面記錄一下我在 innovus layout 的時候大概用了哪些設定,不過因為 APR 相關的文章還沒寫,可能會讓人有些看不懂。

Utilization rate 業界有時叫這個 U rate,一般建議就是 0.7 往上,這次嘗試的極限大略如下:

  • 3M 製程,目前嘗試到 0.64 左右
  • 4M 製程,目前嘗試到 0.77 左右

多一層金屬走線晶片密度也可以做得更高,但也不是無限度的,畢竟限制晶片面積的不是只有走線,還有 clock tree, reset tree 等用的 buffer,一般可能佔到晶片面積的 10% 左右,Utilization Rate 太高了連 buffer 都塞進不去。

上面說的只是 utilization rate,但 utilization rate 只是一個非常全域的數字,它就是你現在全部的 standard cell 跟面積的比值。
密度問題則比較區域性,如果沒多加限制,innovus 會在 place 的時候儘量的把相近的 cell 擠在一塊,普通狀況下還好,在 1P3M 的時候就會造成非常擠的區塊繞線無法繞出。
Congestion 則是指繞線的密度,在 3M 時繞線是最常把我擋下來的原因,下面會看到我用超大的篇幅在討論這個問題。

目前在 congestion 相關的文章,我推薦這篇congestion 报告解读 ;另外 Cadence 自己的官方文章 Mitigating Congestion, CTS, OCV and Other Challenges using Cadence Tools and Support ,也提供一些相關的知識。

參考了網路上的文章,PR工具中到底应该如何控制density和congestion ,以下是試過有效果的選項,寫在 place 與進行 ECO 之前:

set_db place_global_max_density 0.80
set_db opt_max_density 0.80
set_db place_global_uniform_density true

前兩個好理解,就是 place 和做最佳化的時候不要讓密度太高;第二個則是讓 global density 儘量平均一點,散開到整個 layout 之中。

這些選項我覺得算見藥三分毒,有它的危險性在,例如指令的的數字 0.8 就是在我初始 utilization rate 使用 0.7 的條件下設置的。
第二次壓面積把高度再壓扁 50 um,innovus 執行第一次 ECO design 的時候就造成問題,基本密度已經來到 0.8 左右, 無論 innovus 再怎麼移動 cell 都會造成 density 超過 0.8,等於是給了 innovus 一個完全做不到的條件。

如果在 ECO 時看到一堆錯誤訊息,不用懷疑 Ctrl+C 直接給他按下去給它個痛快,重來一次吧。

Congestion

使用以下兩個指令取得 hotspot 和 overflow 的資料

report_congestion -hotspot
report_congestion -overflow

這次成功下線的 layout,hotspot 如下:

[hotspot] +------------+---------------+---------------+
[hotspot] |            |   max hotspot | total hotspot |
[hotspot] +------------+---------------+---------------+
[hotspot] | normalized |   	3082.49    |   	5123.15    |
[hotspot] +------------+---------------+---------------+
Local HotSpot Analysis: normalized max congestion hotspot area = 3082.49, 
normalized total congestion hotspot area = 5123.15 
(area is in unit of 4 std-cell row bins)

至少我用這個 hotspot 來做還是做得出來,但我縮小 vertical space 50 um 之後,max hotspot 3421.38, normalized hotspot 4777.11 的 layout,最後反而是 route 不出來的。
就結論來說,Max hotspot 比 normalized 的更為要緊,可能熱點熱到一個程度,就真的是繞也繞不出來。

1P3M 中 congestion 是最嚴重的問題,即便不如上文中有 hard macro 和 routing blockage ,在最後階段的 routing 仍然可能出現 metal short 和 DRC error。

本次有嘗試使用下列選項,讓它在 place 時多關注一下 congestion,但不確定有多少效用

set_db place_global_cong_effort high

Routing Error

在 1P3M 遇到最多的狀況就是 Routing Error,因為金屬層少,在 Routing 的時候繞不過去就跳一大把 metal short; 上述的大略經驗,max_density 逼近 0.8 幾乎就繞不出來了。
為了應對這種狀況,基本上我會建議在 innovus routing 的時候,使用 congestion first 的 routing,不要管 Timing routing。
這裡的前提自然是我們的 design 不太要求 Timing,Clock 不快的 design,但說實話,如果是高速的設計會用這麼低階的製程嗎?

但無論如何,1P3M 下 Routing 完看到一堆錯誤是再自然不過的事了,如果 Error 數量壓在 10,000 之下,也許還有轉寰的餘地,我目前的記錄是從開始 routing 的時候,還有 7,000 個錯誤,最後透過各種方法壓縮到 0 個 routing error。
一般來說,只有這麼少數幾層在處理 routing 其實很快,選項也只有 M1 走一點點無關緊要的線,M2 走直的 M3 走橫的,就算有 Routing 錯誤在 iteration 時也會很快被解掉。

但還是有例外的,如果錯誤真的爆炸多(我覺得破萬幾乎就沒機會了),或者 layout 上出現了完全解不掉的條件,iteration 一次可能需要 30 分鐘,放著跑一個晚上都跑不完。
會建議在壓縮面積,而使用高密度 layout 的時候(特別是金屬層又這麼少),routing 先設定其中止條件為 5-10 次左右 iteration,這樣 routing 就算錯誤沒全解,也大概可以在 2-3 小時後自然停下來,觀察一下結果如何。
否則 layout 上一堆解不掉的錯,再怎麼 iteration 也沒有用,徒然浪費一堆時間; 這時除非真的有人拿槍指著你說做不出來就死刑,不然還是建議回去 floorplan 多給一些面積比較實在。

除此之外,我下面有幾點心得,估且聽聽作個參考,有些真的是奇淫技巧,我是覺得非到必要不要使用,當然 1P3M 這種超極限製程本來就不是天天遇到,如果你真的就是得在這個指定面積下,把錯誤縮到 0 ,那就試試看吧。

1. 先不管 error,先往後走 Post route 流程

建議可以先跑 post route ECO 修正 timing error,一般的 routing 沒有權力去動放好的 cell, 但修正 timing error 的 optimizer 或多或少可以,也許在移動 cell 時不經意的就把走線問題解掉了。
另外就算你現下就先把錯誤解掉,後續解 timing issue 時移動 cell 又引入新的錯誤要解,所以還不如一開始就先做。

2. 相信 innovus 之術,讓 Route 瘋狂跑

如果你的 error 看起來還可以解,而且一次 iteration 還在 5-10 分鐘等級,那就讓 innovus 瘋狂的跑起來吧。

設定個 30-40 次的 Route,比 default 的終止條件跑更多次,強迫 innovus 去解,我試過 40 次的 iteration ,從上千錯誤壓縮到 33 個 violation,以效率來說的確算是不錯的;而且如果 Error 數確實壓下來了,愈後面的 iteration 會愈來愈快,效率會愈來愈好。

個人不建議超過 50 次,第一個是很浪費時間,第二個是如果能解掉大概 50 次差不多也要有解了,50 次內無解那 50 次外大概也無解。

3. 搬動極度難繞線的 cell

我遇到的狀況是 cell 裡面有一個 C 字型、M1 層的 block 包住接點,接點要往左接線,偏偏 cell 又剛好被放在 M2 垂直的 Power Stripe 下,訊號一出接點沒法直接往上接 M2 M3,走 M1 又會撞在 cell 的 block,試了很多次 iteration 都無解。
後來看了右上角不遠處有一個空位,在圖形介面上就把它搬過去了;搬過去之後再多跑幾次 iteration 就過了。

當然,這招也有風險,建議只在個位數 error 的時候做這件事,我有一次搬完之後錯誤反而更多也更解不掉。
另外因為有搬動 cell,因此搬完之後 Post-route 的 setup/hold time 分析及 ECO 是一定要做的。

4. 直接刪掉有問題的走線

另一個發現是 innovus route 完之後,還有解不掉的 Error,在 routing 結束後,可能因為演算法沒有一個跳脫既有走線的機制,無論指定多少次 iteration 都無解。
試過有效的解法是把出問題的走線刪掉,幫助 innovus 跳脫思考框架,意外的就能消除掉解不掉的 error 了。

具體的做法是在線上點右鍵選 Copy Name,用快捷鍵 “d” delete net 把該 net 刪除,再重新做 ECO Route。
同上,如果刪掉的線裡有比較重要的線,如 CTS, FE 開頭的,意指 Clock Tree 的走線,刪完重繞之後一樣要再進行一次 Timing 分析。

Routing Error 總結

innovus 不太出錯的,所以如果 Routing 完還有錯誤,請先檢視是不是有完全解不掉的條件; 之前我第一次做的時候(五層金屬),沒設好 blocking layer 把 M2 ring 蓋在 standard cells 上,導致完全解不掉的錯。
在 1P3M 的時候,如果錯誤還很多,我會先用 ECO route,終止條件設高一點讓它多跑幾次,先把數字壓低; 收斂到個位數錯誤後,再來使用搬動 cell 和刪除線路的辦法。

另外有個值得注意的經驗,在 1P4M 的條件下因為多了一層金屬,Routing Error 都可以直接解掉,Cell 的密度高到讓 Routing 出問題之前,Setup time/hold time 一定已經先出問題了;這八成也是為什麼 innovus 有個 ThreeLayerMode,會在小於 4 層金屬的狀況下自行啟動。

Timing Issue 怎麼辦?

這次遇到 CTS 做完沒有 Timing issue,Routing 完配上真正走線卻出現 timing issue,因為 Routing 後考慮了走線真正的負載。
解法是在 CTS 做完之後多加一輪的 ECO,既然 Routing 後會出現 Timing issue,那就把這個 slack 值設定為 ECO 的 target。

例如 Routing 後資料慢了 0.3 ns,就在 ECO target 把 slack 從 0 設到 +0.3,多留一些時間給 Routing 就能避免這個問題了。

set_db opt_setup_target_slack 0.3

如何應對 innovus 不修正 Antenna Rule?

這次在 layout 也有遇過一個問題,是 innovus 不知為何不修正 routing 時遇到的 Antenna error,明明 innovus 自己檢測到 5 個 antenna error,在 route 時就是只報 warning 但不修。
這個問題在 Clock tree 上特別嚴重,可能因為 clock tree 不是 Routing 時處理的對象,因此在 Routing 步驟才 check Antenna 的狀況下就不會修正 Clock tree 的問題了。

網路上是有人提供 script 的解法数字IC后端实现干货| ICC2和Innovus自动化修复Antenna Violation的方法及Golden脚本
但我這次是用一個比較簡單暴力的方法:跟上面一樣,把整條違反 antenna rule 的 path 刪掉再重新 ECO route, innovus 就願意修正了。

這只能說:

Cadence 你加油好嗎。

題外話 innovus stylus

這次製作 1P3M layout 的過程中,為了解 bug 而查了許多人的設定,發現到 innovus 新加的 -stylus 模式根本是天翻地覆,像在 density 那章節,現下 -stylus 的設定是:

set_db place_global_max_density 0.80
set_db opt_max_density 0.80
set_db place_global_uniform_density true

參考文章 說的卻都是:

setPlaceMode -place_global_max_density 0.80
setPlaceMode -place_global_uniform_density true
setOptMode -max_density 0.80

指令命名方式直接從 lower camel case 變成 snake_case ,導致網路上一堆文件都要小翻譯或試誤之後才能用,真不知道是受了什麼刺激。

結論

以上就是我這次參與 1P3M layout 遇到經驗的總結,嘗試了只有少量金屬的製程,想想過去動輒 1P5M 1P9M,也真是夠奢侈,什麼都不用擔心,回想起來那時候的 APR 顯然不是精雕細琢的完美成果。
果然還是逼迫自己挑戰極限,才會發現 APR 要顧的東西也是一堆,有很多眉角在裡面要顧。

僅以此文向所有 APR 工程師致敬。