
做低功耗設(shè)計和時鐘樹收斂的兄弟基本都被門控時鐘“教育”過。同樣一條時鐘路徑加上一個門控單元換成AND、OR、NAND、NOR甚至XORPrimeTime跑出來的檢查結(jié)果可能千差萬別。很多人只記住了AND門控的寫法一碰到XOR門控就懵工具要么報unconstrained要么檢查方向完全反了。這篇文章用實際項目和命令把5種門控電路在PrimeTime里的檢查策略差異說明白順便把XOR這類“非標(biāo)準(zhǔn)門控”的處理方案拆開講透。1. 先從門控電路說起為什么同樣一條路徑工具會“區(qū)別對待”1.1 門控時鐘的本質(zhì)讓時鐘“按需跳動”門控時鐘在數(shù)字IC里太常見了尤其在低功耗設(shè)計里模塊空閑時直接把時鐘掐掉動態(tài)功耗能降一截。實現(xiàn)上無非兩種路子一種是直接用組合邏輯搭門控常見的就是AND門、OR門、NAND門、NOR門甚至有人會用XOR門做動態(tài)極性控制另一種是用專用的集成電路門控單元ICG內(nèi)部一般是“鎖存器與門”結(jié)構(gòu)用庫單元實現(xiàn)時序上更安全。組合邏輯門控最大的問題是毛刺glitch。使能信號如果剛好在時鐘有效沿附近跳變輸出時鐘可能出現(xiàn)極窄的脈沖后級觸發(fā)器采出什么誰也不敢保證。所以工具在時序分析時會專門給門控單元插入一類檢查叫做時鐘門控檢查clock gating check目的就是約束使能信號相對于時鐘邊沿的建立時間和保持時間。這就是標(biāo)題里說的“檢查策略”的核心。1.2 PrimeTime里的“檢查”到底查什么PrimeTime做時鐘門控檢查本質(zhì)上是沿著門控單元的兩個輸入端口分別追蹤一個端口接時鐘另一個端口接使能信號。工具需要知道門控輸出在什么時候允許時鐘通過什么時候屏蔽時鐘才能判斷該在哪個沿檢查使能信號相對時鐘的穩(wěn)定關(guān)系。這里有個關(guān)鍵概念門控單元的“有效時鐘極性”。對AND門來說輸出YCLK EN時鐘高電平有效使能高電平有效邏輯很清楚工具自動推斷出來的結(jié)論是“在時鐘上升沿附近檢查EN”。但對OR門、NAND門、XOR門情況就變了。OR門的輸出YCLK | EN低電平使能有效XOR門輸出YCLK ^ EN使能信號不同值時輸出時鐘的極性直接翻轉(zhuǎn)。這種非單調(diào)邏輯PrimeTime的默認(rèn)推斷機制經(jīng)常會“抓瞎”所以就需要人工指定策略。2. 五種門控電路的檢查策略差異2.1 AND門控教科書式的默認(rèn)檢查AND門控是最標(biāo)準(zhǔn)的組合門控結(jié)構(gòu)。時鐘接CLK輸入使能接EN輸入輸出YCLK ENEN為高時時鐘通過EN為低時時鐘屏蔽。PrimeTime對這種結(jié)構(gòu)的自動識別成功率很高因為AND門的布爾函數(shù)是單調(diào)的工具能直接得出有效沿和檢查沿。實際項目中如果用的是庫里的ICG單元檢查約束通常會在庫里定義好不需要手動設(shè)置。但如果是自己搭的AND門控就要顯式調(diào)用命令set_clock_gating_check -setup 0.2 -hold 0.1 [get_pins u_gate_inst/Y]這條命令的意思是在門控輸出Y對應(yīng)的檢查沿上要求使能信號相對于該沿至少有0.2ns的建立時間和0.1ns的保持時間。這里要注意setup和hold的單位是ns具體數(shù)值要根據(jù)工藝庫和時鐘頻率來定不要照抄。AND門控最常見的問題反而是前端RTL寫法導(dǎo)致的毛刺。如果使能信號由組合邏輯產(chǎn)生并且沒有經(jīng)過鎖存器直接去門控時鐘那無論在PrimeTime里怎么設(shè)檢查物理上都很危險。所以做后端的人拿到這類設(shè)計第一反應(yīng)是看門控使能是否足夠干凈。2.2 OR門控使能極性與檢查邊沿的轉(zhuǎn)換OR門控的邏輯是輸出YCLK | ENEN為低時時鐘通過EN為高時強制拉高屏蔽時鐘。這種門控通常用在需要低電平使能的場景但相比AND門控少得多因為大多數(shù)時鐘門控標(biāo)準(zhǔn)單元都是高有效使能。在PrimeTime里OR門控的自動識別依賴庫單元屬性的正確描述。如果單元庫沒有給OR門標(biāo)注clock gating template工具可能直接把它當(dāng)成普通組合邏輯根本不會插入時鐘門控檢查這是最隱蔽的一種坑因為時序報告不會報錯但設(shè)計其實缺了一道重要約束。我自己遇到過一次一個分頻模塊里用OR門做時鐘使能仿真沒問題但跑到STA發(fā)現(xiàn)時鐘門口沒有任何檢查。查了半天最后定位到庫文件里那個OR單元缺少clock_gating_integrated_cell相關(guān)屬性。解決辦法是用LIB文件編輯器補全屬性或者在約束里手動標(biāo)記。如果確認(rèn)OR門控結(jié)構(gòu)沒問題可以用report_clock_gating_check看看工具是否識別成功沒有的話建議先給這個單元添加時鐘門控屬性優(yōu)先級最高的做法還是后端實現(xiàn)階段直接換成標(biāo)準(zhǔn)ICG省心且安全。2.3 NAND與NOR極性翻轉(zhuǎn)帶來的“坑”NAND門和NOR門自帶反相器輸出時鐘相位和輸入時鐘相反。NAND門Y~(CLK EN)等價于AND門后加反相器NOR門Y~(CLK | EN)等價于OR門后加反相器。輸出反相帶來的直接影響是后續(xù)所有觸發(fā)器的采樣時鐘沿從上升沿變成下降沿如果原來用的是上升沿。PrimeTime在推斷NAND/NOR門控的時鐘門控檢查時需要額外考慮極性翻轉(zhuǎn)。比如NAND門輸出時鐘的低電平對應(yīng)原始時鐘的高電平工具會沿著邏輯反向推導(dǎo)把檢查沿從上升沿翻到下降沿。這個推導(dǎo)過程依賴工具對“時鐘極性傳播”的理解如果中間還有其他組合邏輯阻擋推導(dǎo)可能失敗。在這種情況下最需要的命令是set_clock_sense用來顯式告訴工具某個pin上時鐘的極性關(guān)系set_clock_sense -negative -pins [get_pins u_nand_out/Y]這里-negative表示該pin的輸出時鐘與輸入時鐘反相。當(dāng)PrimeTime知道輸出時鐘反相后后續(xù)的時鐘門控檢查就會用正確的下降沿去約束。NAND/NOR門控還有個容易踩的坑是建立時間和保持時間的檢查位置。由于輸出反相原始時鐘的上升沿對應(yīng)NAND輸出時鐘的下降沿如果后級寄存器是上升沿采樣那NAND輸出時鐘到達(dá)寄存器時數(shù)據(jù)建立關(guān)系會重新調(diào)整很多人會在這里繞暈。最佳實踐是不要自己推直接用PrimeTime的時序報告把-delay_type max和-delay_type min分別拉出來看建立和保持看工具到底把檢查沿標(biāo)在了哪里。2.4 XOR門控讓工具“抓狂”的特殊分子XOR門控要單獨拿出來講因為它在檢查策略上是完全不同的玩法。邏輯表達(dá)式Y(jié)A^B假設(shè)時鐘接A使能接B。當(dāng)B0時YA時鐘正常通過當(dāng)B1時Y~A輸出時鐘極性直接翻轉(zhuǎn)。這意味著同一個XOR門可以同時具備正門控和反相門控兩種行為PrimeTime默認(rèn)根本沒法確定唯一的檢查沿。實際項目里XOR門控常用于可配置時鐘極性、動態(tài)時鐘相位調(diào)整這些場景。比如一個接口模塊需要在發(fā)送和接收兩個模式之間切換時鐘極性有人圖省事直接拿XOR門來實現(xiàn)后端就開始頭疼了。處理XOR門控推薦以下三種方案。方案一用set_case_analysis固定控制端。如果XOR的選擇信號在某一配置下是固定的直接告訴工具這個值工具就能把XOR等效成一個Buffer或反相器set_case_analysis 0 [get_pins u_xor_inst/sel] set_clock_sense -positive -pins [get_pins u_xor_inst/Y]set_case_analysis 0讓工具知道sel固定為0此時YA時鐘極性不變再用set_clock_sense顯式聲明Y輸出與輸入同相消除歧義。這種做法的局限是只能覆蓋單種配置如果設(shè)計需要在兩種模式下都做收斂就要分別跑兩次約束。方案二把XOR建模成時鐘MUX。當(dāng)sel是動態(tài)信號運行時會在0和1之間切換更穩(wěn)妥的做法是把XOR的時序行為改寫成二選一MUX模型sel作為選擇端兩條數(shù)據(jù)通道分別是原時鐘和反相時鐘。這樣PrimeTime能正確分析兩種路徑但需要額外處理sel與時鐘的異步關(guān)系復(fù)雜度會上升不少。方案三直接放棄XOR做門控在后端把邏輯替換成標(biāo)準(zhǔn)ICG前面用普通邏輯控制ICG的TE端。這是最穩(wěn)妥的路子我實際項目里遇到XOR門控且時序緊張時都是直接讓前端修改設(shè)計換成ICG不僅PrimeTime檢查簡單物理實現(xiàn)上的毛刺風(fēng)險也小得多。2.5 五種門控的檢查策略對比表門類型輸出邏輯使能有效電平時鐘通過條件工具默認(rèn)檢查邊沿自動識別難度常見風(fēng)險ANDCLK EN高EN1時鐘上升沿低毛刺、使能信號不干凈ORCLK | EN低EN0時鐘下降沿或按需推斷中庫屬性缺失導(dǎo)致不識別NAND~(CLK EN)高/反相輸出EN1且輸出反相檢查沿隨極性翻轉(zhuǎn)中后續(xù)采樣沿變化NOR~(CLK | EN)低/反相輸出EN0且輸出反相檢查沿隨極性翻轉(zhuǎn)中與NAND類似約束易錯XORCLK ^ EN動態(tài)sel決定同相/反相無法默認(rèn)確定高檢查缺失、檢查沿錯誤這張表建議保存后端review時序約束時經(jīng)常用得上。前四種門控只要邏輯庫屬性完整工具自動推斷基本能搞定XOR幾乎一定需要人工介入。3. 實操在PrimeTime中把這些策略配置起來3.1 從網(wǎng)表到約束如何讓工具正確識別門控拿到一個帶門控時鐘的網(wǎng)表先別急著寫約束第一步應(yīng)該是用PrimeTime的命令確認(rèn)工具到底識別了哪些門控單元。最直接的是看報告report_clock_gating_check -verbose -delay_type max這個命令會輸出所有被識別為時鐘門控的單元以及各自的setup/hold檢查結(jié)果。如果某個你認(rèn)為是門控的地方?jīng)]出現(xiàn)在報告里說明工具沒有把它當(dāng)作時鐘門控后續(xù)檢查自然無從談起。另一種快速定位方法是用check_timing它會列出所有沒有被約束到位的時序檢查包括缺失的時鐘門控檢查。我記得有一次在一個多時鐘域模塊里check_timing報出幾十條時鐘門控檢查缺失最后定位下來全是OR門控單元缺屬性導(dǎo)致的。3.2 set_clock_gating_check的完整參數(shù)解讀set_clock_gating_check是配置門控檢查的核心命令參數(shù)不多但每個都挺關(guān)鍵set_clock_gating_check -setup 0.2 -hold 0.05 -rise -fall [get_pins u_cell/Y]-setup和-hold指定檢查的時間裕量單位是ns。-rise表示檢查門控輸出上升沿對應(yīng)的時刻-fall對應(yīng)下降沿。當(dāng)下需要特別注意如果門控單元的輸出時鐘極性不確定-rise和-fall兩個選項同時使用時意味著對上升沿和下降沿都執(zhí)行檢查這在某些場景下會過于悲觀甚至產(chǎn)生偽violation。還有一個隱藏參數(shù)是-clock_gating_cell它不是標(biāo)準(zhǔn)命令參數(shù)但在某些流程里可以通過它來指定某類單元強制作為時鐘門控處理。多數(shù)時候不用管它但如果你用的庫單元命名草率工具又死活不認(rèn)可以去查一下EDA腳本里有沒有類似的適配方式。關(guān)于數(shù)值選取門控檢查的setup/hold應(yīng)該參考標(biāo)準(zhǔn)單元庫中時鐘門控單元的時序弧。如果庫里沒有定義可以先跑一版默認(rèn)檢查看violation集中在哪些路徑上再反向調(diào)整。3.3 用report_clock_gating_check排查潛在問題報告輸出通常分三列門控單元pin、檢查類型setup或hold、檢查裕量??吹揭粋€violation時不要急著去改約束先確認(rèn)檢查沿選對了沒有。以XOR門控為例我實測過這樣一個場景sel信號沒有加case分析PrimeTime默認(rèn)把XOR當(dāng)成普通邏輯并沒有生成時鐘門控檢查但report_clock_gating_check也不會報錯只是不列出這個單元。這個“靜默缺失”是最難排查的。后來我把XOR的輸出pin單獨抓出來看report_timing -from [get_pins u_xor_inst/A] -to [get_pins u_xor_inst/Y] -delay_type max發(fā)現(xiàn)工具把XOR的A到Y(jié)路徑當(dāng)成普通數(shù)據(jù)路徑分析壓根沒插入門控檢查。這說明前端的XOR門控寫法在STA里完全沒有被保護(hù)如果sel在時鐘沿附近跳變時序上可能完全失控。3.4 XOR門控完整配置示例在一個無線通信模塊里見過這樣的結(jié)構(gòu)系統(tǒng)需要動態(tài)調(diào)整輸出時鐘極性前級用了一個XOR門控sel信號來自配置寄存器。初始配置sel0但運行半年后可能切到sel1。這種場景按下面的流程處理最穩(wěn)。第一步先加case analysis讓當(dāng)前跑的這一版工具知道sel值set_case_analysis 0 [get_pins u_xor_inst/sel]第二步顯式指定XOR輸出時鐘極性set_clock_sense -positive -pins [get_pins u_xor_inst/Y]這里-positive表示Y的輸出時鐘與輸入時鐘同相。做完這兩步PrimeTime就會把XOR當(dāng)作一個等效Buffer時鐘門控檢查會在正確沿上生成。但如果要驗證sel1的配置需要把case analysis改成1同時把set_clock_sense改成-negative重新跑一遍STA。兩輪結(jié)果都要確認(rèn)無violation才算把這個XOR門控徹底搞定。這種“雙模式驗證”的思路同樣適用于其他非標(biāo)準(zhǔn)門控。凡是門控單元行為會隨某個控制信號改變的都要按極值配置分別跑檢查不能只跑一個case就收工。4. 常見問題與排查技巧實錄4.1 問題現(xiàn)象速查表現(xiàn)象可能原因排查手段report_clock_gating_check完全沒輸出沒有識別到門控結(jié)構(gòu)檢查庫單元屬性、檢查網(wǎng)表中門控連接門控檢查缺失但不報錯OR/NOR門庫屬性缺失或XOR非單調(diào)用check_timing掃描缺失檢查檢查沿方向不對時鐘極性推斷錯誤用set_clock_sense顯式指定正/負(fù)極性setup/hold同時violation檢查沿選錯導(dǎo)致錯誤約束分別看max/min報告確認(rèn)沿位置XOR門控檢查時好時壞sel未固定工具推斷不穩(wěn)定加set_case_analysis分別跑兩種配置門控檢查比例極低大量自定義組合門控考慮替換為ICG單元或?qū)懩_本批量檢查4.2 XOR門控誤報與漏報的處理心得XOR門控的麻煩在于它可能同時導(dǎo)致誤報和漏報。漏報很好理解工具認(rèn)不出它是門控根本不檢查。誤報則是另外一回事某些情況下工具把XOR的某一輸入當(dāng)時鐘把另一輸入當(dāng)使能但由于XOR的非單調(diào)性工具選錯了檢查沿結(jié)果在錯誤的邊沿上檢查使能信號導(dǎo)致一堆假violation。判斷是誤報還是真問題最直接的辦法是回到仿真。拿一條典型的violation路徑把XOR控制信號和時鐘信號的波形拉出來看如果控制信號在實際工作頻率下根本不會在時鐘沿附近變化往往是約束問題而不是電路問題。但要注意STA是靜態(tài)分析任何可能的切換都會被分析即使實際不會發(fā)生也需要約束到位否則物理實現(xiàn)時工具會過度悲觀。我目前的經(jīng)驗是XOR門控不應(yīng)該交給工具自動推斷一定要手動顯式約束。手動約束雖然麻煩但至少結(jié)果可預(yù)期兩條配置分別跑完心里有底。4.3 系統(tǒng)性驗證門控檢查完備性的技巧門控檢查很容易漏特別是block規(guī)模大、門控單元成百上千時一個個看根本看不完。我自己寫了一個Tcl腳本每次做STA前自動掃描所有門控單元并檢查是否存在對應(yīng)的clock gating check。腳本邏輯很簡單先把所有可能接時鐘的門控單元pin抓出來再利用get_timing_arcs查看是否存在setup/hold時序弧如果沒有就打印warning。這樣一輪下來所有缺失檢查的門控單元都能暴露出來。如果你還沒建這套腳本建議盡快補上排查效率能提升一個量級。另一個技巧是充分利用lib文件里的clock_gating_setup_time和clock_gating_hold_time屬性。只要庫單元標(biāo)注了這些屬性PrimeTime會自動繼承對應(yīng)的檢查值不需要在SDC里重復(fù)設(shè)置。我見過很多項目約束腳本里set_clock_gating_check設(shè)了一大堆其實庫單元早就寫好了雙向約束疊加反而把時序卡得太緊。5. 寫在最后的幾句經(jīng)驗我現(xiàn)在接到任何一個帶門控時鐘的block第一件事就是跑一遍report_clock_gating_check把unconstrained和缺失列出來。這個動作可以直接看出設(shè)計里埋了哪些雷比看幾千行SDC高效得多。前四種門控只要庫沒問題基本都能自動化通過XOR門控則是永恒的“人工介入點”。如果你還在用XOR做時鐘門控我個人建議盡快改成ICG或MUX結(jié)構(gòu)哪怕前端多改幾行RTL后端省下來的時間和風(fēng)險是完全值得的。