字后端PPPR電源規(guī)劃實戰(zhàn):從IR Drop根源到Innovus腳本詳解)
做了這么多年數(shù)字后端每次看到IR Drop違例列表里那一長串紅色心里都會咯噔一下。其實大部分IR Drop問題根源不在最后分析那一步而在最開始電源規(guī)劃沒做扎實——也就是PPPRPre-Placement Power Routing階段偷了懶。PPPR說白了就是布局之前先把電源網(wǎng)絡(luò)骨架搭好很多新手容易把它理解成“跑個腳本加幾條Stripe就完事”實際操作中這活兒其實是個策略活既要管住功耗還得給信號繞線留夠空間稍有不慎后患無窮。這次我把Innovus里做PPPR的完整思路、腳本和調(diào)參經(jīng)驗一起整理出來腳本可以直接抄去改參數(shù)用。無論你是剛接手后端流程的工程師還是準備把PPPR納入現(xiàn)有flow的團隊這篇文章都能幫你少踩幾個坑。1. 先說清楚PPPR和IR Drop到底是什么關(guān)系很多朋友把PPPR當作一個簡單的“加電源環(huán)、加電源條”動作實際上PPPR要解決的是“芯片在物理上拿到電”這件事。IR Drop的本質(zhì)是電流流過電源網(wǎng)絡(luò)時在金屬電阻上產(chǎn)生了壓降離供電點遠的cell實際電壓低于標準值cell延遲變慢時序就崩了。這個原理可以拿高樓供水來打比方水泵在樓頂越往下水壓越大越往上水流越小。芯片里也一樣power stripe太窄、間距太大遠端cell拿到的電壓就會打折扣。PPPR干的事情就是在擺放邏輯單元之前先規(guī)劃好哪幾層金屬走電源、走多寬、隔多遠確保整個芯片范圍內(nèi)每個標準單元都能“喝到水”。PPPR在Innovus里的位置很明確floorplan做完、標準單元還沒擺放之前。這個階段你手中已經(jīng)是帶macro擺放的floorplan可以評估功耗密度和熱點區(qū)域趁早把power mesh的架構(gòu)敲定。如果拖到place之后才發(fā)現(xiàn)電源網(wǎng)絡(luò)不行改起來成本成倍上漲而且很多地方根本沒空間再改。它能解決的問題主要有三個一是保證steady state時全芯片電壓降在可接受范圍二是給后續(xù)dynamic IR分析打一個靠譜的基礎(chǔ)三是在早期就把電源網(wǎng)絡(luò)和信號繞線資源的矛盾暴露出來避免后期大改。適合誰看準備入門后端物理實現(xiàn)的同學以及正在被IR Drop反復折磨、想系統(tǒng)梳理PPPR流程的工程師。2. 動手之前三個關(guān)鍵決策要想清楚2.1 電壓域劃分一張圖還是多張圖PPPR第一步不是畫線而是搞清楚你的芯片到底要通幾路電。單電壓域設(shè)計只有VDD和VSS最簡單直接全芯片統(tǒng)一打stripe就行。多電壓域設(shè)計就麻煩不少比如SoC里常見的1.0V核心邏輯加1.8V IO兩套PG網(wǎng)絡(luò)互相獨立PPPR時要分別創(chuàng)建voltage domain不同域之間的stripe不能混用邊界處還要處理隔離和電平轉(zhuǎn)換單元的供電連接。我見過團隊在domain邊界處理上栽過跟頭兩個電壓域挨得太近addStripe的時候沒設(shè)好boundary結(jié)果一路電串到了另一路IR分析出來一片亂。所以在動手前先把SPEC里的power domain map拿過來確認每個domain的bounding box和對應(yīng)PG網(wǎng)絡(luò)這一步偷懶后面全是債。2.2 PG網(wǎng)絡(luò)的“主通道”選哪層選層取決于工藝節(jié)點和金屬層資源。常規(guī)做法是高層厚金屬做全局stripe因為電阻小、電流承載能力強中低層金屬做標準單元的Follow Pin和一個局部短連接。到先進工藝有些設(shè)計連Backside Power Delivery都開始用了電源直接走晶圓背面PPPR思路又會不一樣但基本原理沒變——用最寬的金屬、最短的距離把電送進去。選層的矛盾點在于高層金屬同時也是長距離信號繞線的主力stripe鋪多了信號沒地方走線。我一般先用M7/M8做一條主stripe驗證可行性再根據(jù)IR結(jié)果決定要不要加密。別一上來就把所有高層金屬全給電源留給鐘線和高速數(shù)據(jù)一些空間否則后面CTS和route階段你會發(fā)現(xiàn)根本繞不動。2.3 IR Drop目標值怎么定做PPPR之前要明確“做到什么程度算合格”。通常靜態(tài)IR約束在3% VDD以內(nèi)動態(tài)IR約束在10% VDD以內(nèi)具體數(shù)值看芯片類型和代工廠建議手機芯片比服務(wù)器芯片要嚴格因為動態(tài)功耗波動大。目標值決定了stripe密度和寬度目標越嚴stripe就越寬、越密繞線資源消耗越大所以要找一個平衡點。實際操作里我會把IR目標和繞線資源一起權(quán)衡。比如PPA要求很緊的模塊我不追求全局最嚴IR而是重點區(qū)域重點加固普通區(qū)域滿足基本約束就行。這種“局部特供”策略在高端設(shè)計里非常常見省下來的就是實實在在的面積和繞線資源。3. 完整PPPR腳本逐段拆解3.1 腳本整體框架與變量設(shè)置給大家的這套腳本是基于Innovus Tcl接口寫的核心命令包括globalNetConnect、addRing、addStripe、addFollowPin、sroute這幾板斧。腳本我實際跑過芯片級和模塊級都能用但是金屬層、寬度、間距這些參數(shù)必須根據(jù)自己的PDK改不能直接照搬。# # PPPR Master Script for Innovus # Author: Backend Engineer # Usage: # 1. load design (LEF/DEF/Netlist) # 2. source $PPPR_HOME/pppr.tcl # # ---------- User Config ---------- set DESIGN_NAME chip_top set VDD_NET VDD set VSS_NET VSS set CORE_IR_TARGET 0.03 # Global Stripe Parameters set STRIPE_LAYER_TOP M8 set STRIPE_LAYER_BOT M7 set STRIPE_WIDTH 0.6 set STRIPE_SPACING 0.6 set STRIPE_PITCH 40.0 set RING_LAYER_H M7 set RING_LAYER_V M6 set RING_WIDTH 1.2 set RING_SPACING 0.5 set RING_OFFSET 1.0 set FOLLOW_PIN_LAYER M1 # Decap / Welltap set DECAP_RATIO 0.05 set WELLTAP_DISTANCE 20.0 # ------------------------------------------- # ---------- Initial Check ---------- if {![file exists $DESIGN_NAME.def]} { puts Error: $DESIGN_NAME.def not found! return -code error } loadDesign $DESIGN_NAME.enc.dat這段腳本開頭把所有可調(diào)參數(shù)集中在一個區(qū)域方便后面對不同方案做批量掃描。PDK不同M1能不能做Follow Pin、高層金屬用什么寬度合適參數(shù)都會變。我習慣把參數(shù)獨立成vars文件這樣每次換工藝節(jié)點只要改一個文件不用在腳本里翻來翻去。3.2 第一步全局電源連接PPPR的第一步是把設(shè)計里每個標準單元的VDD/VSS引腳邏輯上和全局PG網(wǎng)絡(luò)連起來。注意這時候物理連線還沒發(fā)生只是建立了一種“應(yīng)該連到同一網(wǎng)絡(luò)”的關(guān)系真正的金屬線后面才畫。# ---------- Global Net Connect ---------- globalNetConnect $VDD_NET -type pgpin -pin $VDD_NET -inst * -override globalNetConnect $VSS_NET -type pgpin -pin $VSS_NET -inst * -override globalNetConnect $VDD_NET -type tiehi -inst * -override globalNetConnect $VSS_NET -type tielo -inst * -override這里重點說一下-override這個選項。為什么加它因為設(shè)計里可能存在一些多電源domain或者isolated cell在綜合階段或upf定義時PG連接可能已經(jīng)部分指定了沒有-override的話Innovus遇到已連接的網(wǎng)絡(luò)會跳過容易產(chǎn)生“某些單元沒被連上PG網(wǎng)絡(luò)”的隱患。加了它等于強制把規(guī)則刷新一遍保證所有instance都背著VDD/VSS標簽。tiehi和tielo也不能忘。標準單元內(nèi)部有些輸入固定接高或接低比如掃描使能、測試模式信號這些引腳需要真正連到PG網(wǎng)絡(luò)而不是跑信號線。很多新手只設(shè)pgpin漏了tiehi/tielo結(jié)果DRC風平浪靜一跑IR分析一堆floating引腳冒出來。3.3 第二步創(chuàng)建PG電壓屬性globalNetConnect把網(wǎng)絡(luò)關(guān)系綁定了但Innovus還不知道VDD是幾伏電壓所以下一步要用createPG告訴工具每個PG網(wǎng)絡(luò)的電壓值。有了電壓屬性后面IR分析工具才能計算IR Drop沒有電壓配置功耗分析工具直接用默認值會算出完全錯誤的結(jié)果。# ---------- Create PG ---------- createPG -net $VDD_NET -voltage 1.00 createPG -net $VSS_NET -voltage 0.00多電壓域設(shè)計就多寫幾行比如createPG -net VDD_1V0 -voltage 1.00 createPG -net VDD_1V8 -voltage 1.80 createPG -net VSS -voltage 0.00這里要特別提醒電壓值必須和UPF、SDC里的電壓信息保持一致一旦對不上后端的功耗分析、時序分析會橫豎都對不上賬。我在項目里吃過一次虧SDC里寫的是0.8V內(nèi)核電壓createPG寫了個0.85V結(jié)果IR分析報出來的droop比例看上去不高換算成絕對電壓偏了5%后面查了半天才發(fā)現(xiàn)是這種低級不一致造成的。3.4 第三步電源環(huán)和電源條這是PPPR的主體工作也是參數(shù)最多、最容易翻車的地方。# ---------- Add Ring ---------- addRing -nets $VDD_NET $VSS_NET \ -around core \ -layer {top $RING_LAYER_H bottom $RING_LAYER_H left $RING_LAYER_V right $RING_LAYER_V} \ -width $RING_WIDTH \ -spacing $RING_SPACING \ -offset $RING_OFFSET # ---------- Add Stripe ---------- addStripe -nets $VDD_NET $VSS_NET \ -layer $STRIPE_LAYER_TOP -direction horizontal \ -width $STRIPE_WIDTH -spacing $STRIPE_SPACING \ -set_to_set_distance $STRIPE_PITCH \ -max_same_color_joglength 4 addStripe -nets $VDD_NET $VSS_NET \ -layer $STRIPE_LAYER_BOT -direction vertical \ -width $STRIPE_WIDTH -spacing $STRIPE_SPACING \ -set_to_set_distance $STRIPE_PITCH \ -max_same_color_joglength 4先說addRing。電源環(huán)的作用是把芯片核心區(qū)域的四周圍一圈厚金屬相當于給整個core區(qū)域一個外圍供電干線。層選擇上至少要有兩層金屬交叉橫向一層、縱向一層這樣環(huán)形路徑在轉(zhuǎn)角處不會斷。width取多少我是從供電需求估算的整個block峰值電流除以金屬單位寬度的電流承載能力再留出30%的裕量。比如一個100mA電流的block高層金屬1um寬大約能安全走1mA到2mA跟工藝和溫升有關(guān)那環(huán)形總寬度至少得有50um分攤到電源和地兩條環(huán)每條25um。如果ring設(shè)得太窄相當于供水總管的管徑不夠末端水壓肯定上不去。再說addStripe。Stripe是貫穿core內(nèi)部的電源條真正給內(nèi)部cell供電的就靠這些條。set_to_set_distance是條與條之間的中心距這個值直接決定IR Drop好壞。間距小電阻小IR好但繞線資源被占得多間距大省資源IR容易超。經(jīng)驗法則是第一階段先用20~40um試跑一輪再根據(jù)IR結(jié)果加密或減稀不要一上來就貪。還有一個關(guān)鍵操作是橫向和縱向兩層stripe都要打形成網(wǎng)格狀結(jié)構(gòu)。為什么因為只走單方向供電路徑長IR壓降會顯著增加??v橫交錯相當于給電流多修了幾條路電流可以從多個方向匯入整體壓降成倍改善。很多剛?cè)腴T的朋友打完M8一條方向就覺得完事了分析出來的IR慘不忍睹其實就是網(wǎng)格沒做完整。3.5 第四步Follow Pin與標準單元供電Stripe是供電干線但標準單元的電源引腳在最底層的M1上怎么辦靠Follow Pin連接。Follow Pin就是在標準單元行的電源軌道上直接畫一根細長金屬把這一行所有cell的VDD/VSS串起來再通過via把Follow Pin引到上面的stripe。# ---------- Add Follow Pin ---------- addFollowPin -nets $VDD_NET $VSS_NET -layer $FOLLOW_PIN_LAYER這個命令會沿著每個標準單元row自動生成電源軌道。需要注意FOLLOW_PIN_LAYER一定要選標準單元PG rail所在的金屬層通常就是M1。如果選錯了層DRC不會立刻報錯但后續(xù)sroute會亂成一團via打不下去單元取不到電。打完Follow Pin之后Innovus里其實還有一個容易忽視的操作加via。Follow Pin在M1Stripe在M7/M8中間M2到M6層層都要靠via陣列打下去。via不夠電流只能擠在幾個點上IR照樣炸。addStripe的時候用默認設(shè)置Innovus會在Stripe和Follow Pin重疊區(qū)域自動加via但有些情況下via密度不夠此時可以在Stripe的交叉點手動加via array或者用addViasToPin把關(guān)鍵連接點補齊。3.6 第五步SRoute連接所有供電節(jié)點到這里電源網(wǎng)絡(luò)還是“概念圖”globalNetConnect建立了邏輯關(guān)系Ring和Stripe是物理走線Follow Pin是標準單元軌道。但三者之間還沒形成完整的通路。SRoute就是做這個最終縫合工作的命令——把Ring、Stripe、Follow Pin以及block的PG pin全部連起來。# ---------- SRoute ---------- sroute -nets $VDD_NET $VSS_NET \ -allowJogging 1 \ -allowLayerChange 1 \ -blockPinTarget 1 \ -corePinTarget 1allowLayerChange和allowJogging必須打開否則SRoute只走直線遇到跨層連接會直接失敗。blockPinTarget和corePinTarget意味著macro的電源引腳和core區(qū)域的引腳都要被連接如果這里沒開memory的電源腳就會漏掉IR分析的時候那片區(qū)域會艷紅一片。SRoute跑完P(guān)PPR主體工作基本結(jié)束回到腳本開頭看那一段收尾操作# ---------- Add Welltap Decap ---------- addWellTap -cell FILL0 -prefix WELLTAP -betweenDistance $WELLTAP_DISTANCE addDecap -cell DECAP_8T -prefix DECAP -ratio $DECAP_RATIOWellTap是給襯底和阱接電的防止latch-up。Decap是去耦電容用空閑面積填一些decap cell能有效抑制動態(tài)IR Drop的瞬時電壓塌陷。這兩個操作雖然不直接畫電源線但和IR Drop深度相關(guān)尤其是dynamic IR場景decap密度太少開關(guān)噪聲瞬間拉低電壓后果比靜態(tài)IR超一點還嚴重。我一般先在floorplan階段填5%~8%面積的decap然后根據(jù)IR分析結(jié)果調(diào)整不建議上來就堆滿decap堆太多影響面積和繞線密度。最后可以做一次檢查和存檔# ---------- Check Save ---------- check_pg_routing saveDesign $DESIGN_NAME.pppr.enc3.7 多電壓域腳本的常見變體如果設(shè)計里存在多個電壓域腳本就不會這么線性了得為每個domain單獨創(chuàng)建PG環(huán)和Stripe。習慣寫法是先建domain再單獨操作createVoltageDomain -name CORE -boundary {0 0 1000 1000} -primaryPowerDomain createVoltageDomain -name IO -boundary {1000 0 1200 1000}然后分別對CORE和IO添加Ring和Stripe加Stripe的時候用-selected或者先用addRing/addStripe -domain指定作用范圍。我不建議用-selected這種方式來試錯因為在Innovus里選中區(qū)域的操作容易受GUI影響腳本化的時候不可控。多電壓域的腳本一定要把domain名稱寫到addStripe參數(shù)里明確邊界查起來也方便。4. 做完P(guān)PPR怎么快速驗證IR Drop4.1 靜態(tài)和動態(tài)分析的區(qū)別腳本跑完別急著開香檳關(guān)鍵一步是驗證。有些團隊習慣等place和route全部結(jié)束后再做IR分析發(fā)現(xiàn)IR超過目標值再回來改PPPR那時候要重新跑一遍完整PR流程成本非常大。建議PPPR階段就做一輪快速靜態(tài)IR檢查早發(fā)現(xiàn)問題早改。常見的分析工具是Voltus或RedHawk。Innovus通常和Voltus深度集成用起來比較順手。靜態(tài)和動態(tài)分析本質(zhì)區(qū)別在輸入數(shù)據(jù)靜態(tài)分析默認給一個固定的翻轉(zhuǎn)率比如20%去估算全芯片的電流分布優(yōu)點是快缺點是不夠精確動態(tài)分析吃VCD波形或SPEF寄生參數(shù)能精確到時鐘沿翻轉(zhuǎn)瞬間的電壓塌陷精度高但流程重需要仿真數(shù)據(jù)。PPPR階段用靜態(tài)分析足夠數(shù)據(jù)格式也簡單輸入是DEFdatabase加上功耗估算文件通常從UPF/CPF或SAIF拿。動態(tài)分析等place之后再做拿著寄生參數(shù)算才不會被“預估值”誤導。4.2 Voltus快速驗證操作步驟在Innovus窗口里操作比較典型的流程是這樣先跑一次powerAnalysis工具抽象出電網(wǎng)結(jié)構(gòu)然后配置功耗輸入最后運行分析。下面給出一個最精簡可跑的靜態(tài)IR分析命令序列具體版本命令名可能會有差異但流程不變# ---------- Quick Static IR Check ---------- set_power_analysis_options -output_dir ir_check_output -report_format text,ascii set_dynamic_power_analysis_options -cycle_time 2.0 -toggle_rate 0.2 set_power_analysis_options -analysis_type static run_power_analysis -design $DESIGN_NAMEtoggle_rate 0.2是默認功耗估算意思是平均每個時鐘周期內(nèi)信號翻轉(zhuǎn)20%。如果你功耗模型清晰可以用更精確的值或者直接導入SAIF文件分析結(jié)果會更可信。跑完后重點看兩個指標一是最差I(lǐng)R Drop的壓降百分比是否在CORE_IR_TARGET以內(nèi)二是熱點位置在哪里是否集中在某些高功耗區(qū)域。如果報告里最差壓降在某個macro附近那大概率是Stripe密度不夠或者welltap/decap不夠回過去在對應(yīng)區(qū)域局部加密Stripe即可。4.3 IR Drop超限怎么辦發(fā)現(xiàn)超限后先判斷是全局性問題還是局部性問題。全局超限通常是Stripe整體密度不足或Ring寬度不夠這時候把addStripe的set_to_set_distance從40調(diào)到30或20重新跑局部超限則在一個區(qū)域附近手動加幾根短Stripe不要全局一起加密浪費資源。兩個常見補充手段也值得一說。第一在熱點區(qū)域的空閑地方填decap緩解動態(tài)IR第二把熱點周圍的標準單元電源軌道做加寬處理M1末端加寬或加寬Follow Pin的供電入口。這些手段都是手術(shù)刀式操作精確打擊效果比無腦全局鋪金屬要好得多。5. 實戰(zhàn)中的高頻坑和排查技巧速查5.1 高頻問題速查表我整理了一張自己在項目中反復遇到的PPPR問題對照表先列出來給大家參考現(xiàn)象直接原因排查方向大量標準單元PG引腳floatingglobalNetConnect漏配或沒加override檢查pgpin配置確認instance數(shù)量是否匹配IR Drop分析出來整片是紅色Stripe網(wǎng)格缺失或via密度不足檢查addStripe的橫縱方向是否都有via陣列是否有效SRoute報錯無法完成Ring/Stripe層選錯或重疊區(qū)域為零檢查Ring offset和Stripe layer是否在同一組金屬層特殊區(qū)域IR特別差macro附近Stripe密度不足或decap缺失局部加Stripe或decap不要全局動多電壓域邊界IR異常Domain邊界重疊或PG網(wǎng)絡(luò)被誤連檢查createVoltageDomain邊界和globalNetConnect作用范圍DRC報出大量WellTap違例WellTap間距過大或密度不足確認addWellTap的betweenDistance是否符合規(guī)則這類問題之所以高頻出現(xiàn)是因為PPPR錯誤往往不是立即報錯而是潛伏到后續(xù)IR分析或DRC階段才爆發(fā)。排查時用Innovus的GUI可視化PG網(wǎng)絡(luò)最直觀——Stripe和Ring是否閉合、Follow Pin是否和Stripe交叉點有via一看便知。5.2 那些文檔里不會寫清楚的經(jīng)驗經(jīng)驗一PPPR階段就要跑一遍快速IR別等route完 這是我最想強調(diào)的一點。Route完的IR分析當然精確但改起來成本太高。PPPR階段跑靜態(tài)IR雖然粗糙但趨勢判斷完全夠用。我在實際項目里形成一個習慣place之后馬上跑一輪臨時IR標記熱點區(qū)域然后回頭在PPPR腳本里把熱點區(qū)域單獨加固再重新跑place。兩輪下來最終route收出來的IR普遍很干凈。經(jīng)驗二Stripe參數(shù)用變量掃描別手改 把set_to_set_distance和width做成變量寫一個兩層循環(huán)批量試試不同組合的IR結(jié)果選一個在IR、面積、繞線擁擠度三方面都均衡的方案。這比來回手動改腳本快得多也更容易發(fā)現(xiàn)參數(shù)變化的趨勢。之前我團隊里一位工程師就是用這個辦法把全芯片IR從4.2%壓到2.7%只犧牲了不到1%的繞線資源。經(jīng)驗三ECO階段加buffer千萬別忘PG連接 Run到后期做功能性ECO或Timing ECO時有時候會直接手工在版圖上插buffer來修復時序。新插入的buffer如果沒走globalNetConnect那套流程它的PG引腳就是floating的跑到IR分析階段會突然冒出幾十個未連接引腳。很多人在這個位置卡了一整個下午查到最后發(fā)現(xiàn)是說“為什么PPPR都做了紅彤彤還是一片”的根源其實是后期ECO單元沒連電源。順手在ECO腳本末尾加一句globalNetConnect刷新就能避免這個問題。經(jīng)驗四留好轉(zhuǎn)角空間和信號通道 最后一個實用心得是不要把Stripe鋪得密不透風。一個網(wǎng)格均勻的電源網(wǎng)絡(luò)確實能壓住IR但如果所有可繞線層都被電源占滿信號繞線只能繞遠路時序反而變差。給clock和高速數(shù)據(jù)留些橫跨芯片的專用通道IR稍微差一點點但整體PPA可能反而更好。電源規(guī)劃和時序規(guī)劃是同一套資源上的博弈誰都想多占一點最后出來的方案一定是妥協(xié)的結(jié)果。我這些年在后端項目上最深的體會是PPPR這個階段看起來平淡無奇其實對整個芯片的收斂節(jié)奏影響極大。前期多花兩三個小時把電源網(wǎng)絡(luò)規(guī)劃扎實后期IR分析就能省出兩三天來回折騰的時間。腳本只是一個起點把網(wǎng)格密度、層選擇和decap比例配合好才是真正的功力所在。如果大家在實際項目里遇到其他奇怪的電源規(guī)劃問題也建議先回到這幾個基礎(chǔ)環(huán)節(jié)去排查大概率能少走不少彎路。