字芯片STA時(shí)鐘約束:從create_clock到set_clock_uncertainty的工程實(shí)踐)
1. 項(xiàng)目概述深入理解STA環(huán)境中的時(shí)鐘約束在數(shù)字芯片設(shè)計(jì)的后端流程里靜態(tài)時(shí)序分析Static Timing Analysis, STA是確保芯片能夠在指定頻率下穩(wěn)定工作的基石。而STA的起點(diǎn)和核心就是對(duì)時(shí)鐘的精確描述與約束。如果把整個(gè)芯片的時(shí)序路徑比作一個(gè)城市的交通網(wǎng)絡(luò)那么時(shí)鐘信號(hào)就是指揮所有車輛數(shù)據(jù)何時(shí)出發(fā)、何時(shí)到達(dá)的交通信號(hào)燈系統(tǒng)。一個(gè)定義不清、約束不準(zhǔn)的時(shí)鐘就像一套混亂的交通燈必然導(dǎo)致整個(gè)系統(tǒng)陷入擁堵建立時(shí)間違例或事故保持時(shí)間違例。因此“STA環(huán)境 - 時(shí)鐘”這個(gè)主題探討的就是如何為這個(gè)至關(guān)重要的“交通信號(hào)燈系統(tǒng)”制定一套完整、精確的規(guī)則手冊(cè)。在實(shí)際項(xiàng)目中我們使用SDCSynopsys Design Constraints這樣的約束語言來定義這些規(guī)則。對(duì)于時(shí)鐘最基本的命令就是create_clock它定義了時(shí)鐘的源頭、周期和波形。但僅僅定義周期是遠(yuǎn)遠(yuǎn)不夠的時(shí)鐘信號(hào)從源頭例如PLL輸出或端口傳播到芯片內(nèi)部各個(gè)寄存器時(shí)鐘引腳的過程中會(huì)經(jīng)歷線延遲、緩沖器延遲還會(huì)受到工藝、電壓、溫度PVT變化以及串?dāng)_噪聲的影響導(dǎo)致其邊沿到達(dá)時(shí)間存在不確定性。這就需要set_clock_latency和set_clock_uncertainty等命令來刻畫這些現(xiàn)實(shí)世界的非理想因素。理解并正確設(shè)置這些約束是搭建一個(gè)可靠、可預(yù)測(cè)的STA環(huán)境的第一步也是決定時(shí)序收斂效率與最終芯片性能的關(guān)鍵。2. 時(shí)鐘約束的核心要素深度解析2.1create_clock定義時(shí)鐘的“理想藍(lán)圖”create_clock命令是時(shí)鐘約束的根基它描繪了設(shè)計(jì)者期望的理想時(shí)鐘波形。其基本語法是create_clock -name clock_name -period period -waveform {rise_time fall_time} [get_ports source_port]。-period時(shí)鐘周期單位通常是納秒ns。這是最核心的參數(shù)直接決定了芯片的目標(biāo)工作頻率。例如-period 10對(duì)應(yīng)100MHz-period 5對(duì)應(yīng)200MHz。設(shè)定周期時(shí)必須綜合考慮工藝庫的性能、設(shè)計(jì)的復(fù)雜度以及功耗預(yù)算。一個(gè)過于激進(jìn)的周期會(huì)導(dǎo)致時(shí)序無法收斂而過于保守則會(huì)浪費(fèi)芯片性能。-waveform定義了時(shí)鐘信號(hào)在一個(gè)周期內(nèi)的上升沿和下降沿時(shí)間。默認(rèn)是{0, period/2}即占空比為50%的方波。對(duì)于非50%占空比的時(shí)鐘或者需要對(duì)齊特定邊沿的時(shí)鐘必須精確指定。例如-waveform {0 3}表示上升沿在0ns下降沿在3ns周期為10ns時(shí)占空比為30%。-name為創(chuàng)建的時(shí)鐘網(wǎng)絡(luò)命名。這個(gè)名字將在后續(xù)的所有時(shí)鐘相關(guān)約束如時(shí)鐘組、衍生時(shí)鐘、跨時(shí)鐘域約束中被引用因此命名應(yīng)清晰、有規(guī)律例如clk_core,clk_mem等。源對(duì)象通常用[get_ports port_name]指定時(shí)鐘從哪個(gè)輸入端口進(jìn)入芯片。對(duì)于內(nèi)部生成的時(shí)鐘如PLL輸出則使用[get_pins cell_pin]。注意create_clock定義的是“理想”時(shí)鐘源處的波形。它假設(shè)這個(gè)波形是完美的沒有延遲沒有抖動(dòng)。所有后續(xù)的延遲和不確定性約束都是在這個(gè)“理想源點(diǎn)”的基礎(chǔ)上疊加的。2.2set_clock_latency刻畫時(shí)鐘網(wǎng)絡(luò)的“固定行程時(shí)間”時(shí)鐘延遲Latency指的是時(shí)鐘信號(hào)從定義源source傳播到寄存器時(shí)鐘引腳clock pin所需的時(shí)間。它分為兩部分源延遲Source Latency指時(shí)鐘信號(hào)從實(shí)際的物理時(shí)鐘源如芯片外部晶振輸出腳到達(dá)芯片內(nèi)部時(shí)鐘定義點(diǎn)即create_clock指定的位置之間的延遲。這部分延遲在芯片內(nèi)部是不可控的屬于“系統(tǒng)級(jí)”延遲。在SDC中通常在設(shè)計(jì)早期用set_clock_latency -source進(jìn)行預(yù)估。網(wǎng)絡(luò)延遲Network Latency指時(shí)鐘信號(hào)從芯片內(nèi)部的時(shí)鐘定義點(diǎn)經(jīng)過時(shí)鐘樹綜合CTS生成的時(shí)鐘分布網(wǎng)絡(luò)到達(dá)各個(gè)寄存器時(shí)鐘引腳的延遲。在CTS之前這是一個(gè)預(yù)估的值在CTS之后工具會(huì)使用實(shí)際的布線延遲Propagated Delay來替代這個(gè)預(yù)估延遲。命令示例set_clock_latency -source 0.5 [get_clocks clk_core]設(shè)置源延遲為0.5ns。set_clock_latency 1.2 [get_clocks clk_core]設(shè)置網(wǎng)絡(luò)延遲為1.2ns。為什么需要區(qū)分在布局布線PnR工具進(jìn)行時(shí)鐘樹綜合時(shí)它只能優(yōu)化“網(wǎng)絡(luò)延遲”而無法改變“源延遲”。明確區(qū)分二者有助于工具更準(zhǔn)確地估算時(shí)鐘偏移Skew和進(jìn)行時(shí)序優(yōu)化。一個(gè)常見的實(shí)操心得是在綜合Synthesis階段根據(jù)設(shè)計(jì)規(guī)模和目標(biāo)頻率設(shè)置一個(gè)合理的網(wǎng)絡(luò)延遲預(yù)估例如周期時(shí)間的10%-20%以引導(dǎo)邏輯綜合工具進(jìn)行初步優(yōu)化。進(jìn)入布局后再用更精確的線負(fù)載模型Wire Load Model或物理信息來更新這個(gè)預(yù)估。2.3set_clock_uncertainty為時(shí)鐘邊沿加上“安全緩沖帶”時(shí)鐘不確定性Uncertainty是一個(gè)“安全余量”或“悲觀余量”它用來覆蓋所有導(dǎo)致時(shí)鐘邊沿?zé)o法精確到達(dá)的因素。主要包括時(shí)鐘抖動(dòng)Clock Jitter時(shí)鐘源自身周期到周期的短期變化。PLL數(shù)據(jù)手冊(cè)會(huì)給出這個(gè)值。時(shí)鐘偏移Clock Skew同一時(shí)鐘信號(hào)到達(dá)不同寄存器時(shí)鐘引腳的時(shí)間差。CTS的目標(biāo)就是最小化Skew但無法完全消除。其他噪聲影響如電源噪聲引起的時(shí)鐘波形畸變等。在SDC中set_clock_uncertainty用于在建立時(shí)間Setup和保持時(shí)間Hold檢查中人為地增加或減少時(shí)序路徑的可用時(shí)間窗口從而確保芯片在存在這些非理想因素時(shí)仍能工作。建立時(shí)間檢查不確定性會(huì)減少有效的時(shí)間窗口。命令為set_clock_uncertainty -setup value [get_clocks clkA]。這意味著工具在進(jìn)行建立時(shí)間分析時(shí)會(huì)認(rèn)為時(shí)鐘的有效周期比實(shí)際周期短了value這么多。保持時(shí)間檢查不確定性會(huì)增加時(shí)間窗口的需求。命令為set_clock_uncertainty -hold value [get_clocks clkA]。這意味著工具在進(jìn)行保持時(shí)間分析時(shí)會(huì)要求數(shù)據(jù)在時(shí)鐘沿之后穩(wěn)定保持更長(zhǎng)的時(shí)間value。一個(gè)典型的設(shè)置是set_clock_uncertainty -setup 0.2 -hold 0.1 [get_clocks clk_core]。這表示考慮到抖動(dòng)和噪聲我們?yōu)閏lk_core的建立時(shí)間檢查預(yù)留了200ps的余量為保持時(shí)間檢查預(yù)留了100ps的余量。實(shí)操技巧不確定性的設(shè)置需要平衡。設(shè)置過大會(huì)導(dǎo)致工具過度優(yōu)化增加面積和功耗甚至使時(shí)序無法收斂。設(shè)置過小則可能無法覆蓋實(shí)際硅片中的變化導(dǎo)致流片失敗。通常建立時(shí)間不確定性約為時(shí)鐘周期的3%-5%保持時(shí)間不確定性約為建立時(shí)間的一半。這個(gè)值需要與設(shè)計(jì)團(tuán)隊(duì)、后端團(tuán)隊(duì)和芯片工藝特性共同商定。3. 復(fù)雜時(shí)鐘結(jié)構(gòu)與高級(jí)約束實(shí)戰(zhàn)3.1 生成時(shí)鐘與時(shí)鐘分頻/倍頻在實(shí)際設(shè)計(jì)中主時(shí)鐘Master Clock經(jīng)常通過時(shí)鐘門控、分頻器、PLL等產(chǎn)生多個(gè)衍生時(shí)鐘Generated Clock。我們必須使用create_generated_clock來正確定義它們與源時(shí)鐘的關(guān)系否則STA工具無法分析相關(guān)的時(shí)序路徑。例如一個(gè)簡(jiǎn)單的2分頻時(shí)鐘create_clock -name CLK -period 10 -waveform {0 5} [get_ports clk_in] create_generated_clock -name CLK_DIV2 -source [get_ports clk_in] -divide_by 2 [get_pins div_reg/Q]-source指明了母時(shí)鐘-divide_by定義了分頻比。工具會(huì)自動(dòng)推導(dǎo)出CLK_DIV2的周期為20ns波形為{0 10}。對(duì)于更復(fù)雜的場(chǎng)景如使能信號(hào)門控的時(shí)鐘、或經(jīng)過組合邏輯的時(shí)鐘必須使用-edges選項(xiàng)來精確描述生成時(shí)鐘邊沿與源時(shí)鐘邊沿的對(duì)應(yīng)關(guān)系。錯(cuò)誤定義生成時(shí)鐘是導(dǎo)致時(shí)序分析遺漏或錯(cuò)誤的常見原因。3.2 時(shí)鐘組與異步時(shí)鐘域處理并非所有時(shí)鐘之間都存在時(shí)序關(guān)系。例如一個(gè)來自以太網(wǎng)MAC的時(shí)鐘和一個(gè)來自USB控制器的時(shí)鐘通常是完全異步的。用set_clock_groups命令可以將時(shí)鐘分組并聲明組間關(guān)系。異步時(shí)鐘組set_clock_groups -asynchronous -group {clk_eth} -group {clk_usb}。這告訴STA工具不要對(duì)clk_eth和clk_usb之間的路徑進(jìn)行建立/保持時(shí)間檢查因?yàn)樗鼈兪钱惒降?。這些路徑必須通過同步器如兩級(jí)觸發(fā)器來處理其時(shí)序通過其他方法如最大傳輸延遲約束set_max_delay來保證。互斥時(shí)鐘組同一個(gè)時(shí)鐘源通過MUX選擇輸出不同頻率的時(shí)鐘這些時(shí)鐘在同一時(shí)刻只有一個(gè)有效。set_clock_groups -physically_exclusive -group {clk_1g} -group {clk_100m}。這比異步更嚴(yán)格表示它們不僅異步而且物理上不會(huì)同時(shí)存在。正確設(shè)置時(shí)鐘組是約束中的重中之重。遺漏異步時(shí)鐘組聲明會(huì)導(dǎo)致工具徒勞地嘗試優(yōu)化那些本應(yīng)被忽略的跨時(shí)鐘域路徑浪費(fèi)大量運(yùn)行時(shí)間并可能掩蓋真正的時(shí)序問題。3.3 時(shí)鐘延遲與不確定性的動(dòng)態(tài)設(shè)置在設(shè)計(jì)的全流程中時(shí)鐘約束并非一成不變。綜合階段此時(shí)還沒有時(shí)鐘樹網(wǎng)絡(luò)延遲是預(yù)估的不確定性可以設(shè)置得相對(duì)寬松一些重點(diǎn)關(guān)注邏輯優(yōu)化。布局后Post-Place有了初步的布局信息可以用更準(zhǔn)確的線延遲模型來更新網(wǎng)絡(luò)延遲預(yù)估并開始收緊不確定性約束。時(shí)鐘樹綜合后Post-CTS這是關(guān)鍵轉(zhuǎn)折點(diǎn)。此時(shí)真實(shí)的時(shí)鐘樹已經(jīng)插入工具可以計(jì)算出每個(gè)寄存器的“傳播時(shí)鐘延遲”Propagated Clock。必須用set_propagated_clock命令替換掉之前預(yù)估的網(wǎng)絡(luò)延遲約束。同時(shí)不確定性中的“時(shí)鐘偏移”部分可以顯著減小因?yàn)镃TS已經(jīng)將Skew控制在目標(biāo)范圍內(nèi)。布線后Post-Route提取的寄生參數(shù)RC最準(zhǔn)確可以進(jìn)行最終的 sign-off 級(jí)別時(shí)序分析。此時(shí)的不確定性主要只包含時(shí)鐘抖動(dòng)和少量的額外余量。這個(gè)動(dòng)態(tài)調(diào)整的過程體現(xiàn)了從“預(yù)估建?!钡健熬_分析”的演進(jìn)。一個(gè)常見的坑是CTS后忘記將set_clock_latency替換為set_propagated_clock導(dǎo)致時(shí)序分析仍然基于錯(cuò)誤的預(yù)估延遲從而使分析結(jié)果失去意義。4. 時(shí)鐘約束的典型問題與調(diào)試技巧4.1 約束不完整或沖突問題設(shè)計(jì)中有時(shí)鐘信號(hào)但沒有用create_clock或create_generated_clock定義。工具會(huì)將其視為“未約束”的時(shí)鐘相關(guān)路徑不會(huì)被分析這是一個(gè)重大風(fēng)險(xiǎn)。調(diào)試使用STA工具如PrimeTime的命令report_clock或check_timing來報(bào)告所有時(shí)鐘和未約束的時(shí)序路徑。必須確保每個(gè)時(shí)鐘域都被正確定義。問題同一個(gè)時(shí)鐘源被重復(fù)定義了多次create_clock或者時(shí)鐘組設(shè)置矛盾如既聲明為異步又存在路徑約束。調(diào)試仔細(xì)檢查SDC文件確保約束來源清晰。通常建議將時(shí)鐘基礎(chǔ)約束寫在一個(gè)獨(dú)立的、權(quán)威的SDC文件中其他模塊級(jí)的約束通過derive_clocks等命令自動(dòng)推導(dǎo)或補(bǔ)充。4.2 生成時(shí)鐘定義錯(cuò)誤問題對(duì)于通過組合邏輯如與門、或門產(chǎn)生的門控時(shí)鐘僅使用-divide_by無法正確描述其行為導(dǎo)致生成時(shí)鐘的邊沿和周期計(jì)算錯(cuò)誤。解決方案必須使用-edges選項(xiàng)明確列出源時(shí)鐘的哪個(gè)邊沿對(duì)應(yīng)生成時(shí)鐘的上升沿、下降沿等。例如一個(gè)基于使能信號(hào)的門控時(shí)鐘可能需要結(jié)合-combinational和邊沿描述來定義。4.3 跨時(shí)鐘域約束的陷阱問題遺漏了異步時(shí)鐘組的聲明導(dǎo)致工具報(bào)告大量無法收斂的跨時(shí)鐘域路徑違例干擾了對(duì)真實(shí)關(guān)鍵路徑的判斷。調(diào)試首先梳理設(shè)計(jì)的時(shí)鐘架構(gòu)圖明確所有時(shí)鐘的來源和關(guān)系。對(duì)所有確認(rèn)異步的時(shí)鐘對(duì)使用set_clock_groups -asynchronous進(jìn)行聲明。對(duì)于需要通過同步器的路徑使用set_false_path或set_max_delay -datapath_only來定義合理的時(shí)序要求而不是完全忽略。4.4 時(shí)鐘不確定性設(shè)置不當(dāng)問題在CTS后沒有根據(jù)實(shí)際的時(shí)鐘樹報(bào)告來調(diào)整set_clock_uncertainty。仍然使用綜合階段較大的不確定性值導(dǎo)致過度設(shè)計(jì)或隱藏了潛在的保持時(shí)間問題。實(shí)操心得CTS后應(yīng)使用report_clock_timing或類似命令查看時(shí)鐘樹的實(shí)際Skewinsertion delay的差異和抖動(dòng)。將這部分值從之前的總不確定性中扣除。例如前期設(shè)置-setup 0.3其中預(yù)估Skew為0.15抖動(dòng)為0.1其他余量0.05。CTS后實(shí)測(cè)Skew為0.08那么新的建立時(shí)間不確定性可以更新為 0.1抖動(dòng) 0.05余量 0.15ns。對(duì)于保持時(shí)間CTS后通常Skew對(duì)保持時(shí)間有利但也要檢查局部偏差不確定性可以設(shè)得更小。4.5 時(shí)鐘延遲設(shè)置的階段錯(cuò)配問題在布局后或CTS后仍然使用set_clock_latency來設(shè)置網(wǎng)絡(luò)延遲而不是用set_propagated_clock。這會(huì)導(dǎo)致時(shí)鐘路徑的延遲計(jì)算嚴(yán)重失真。檢查清單在進(jìn)入每個(gè)后端階段Place, CTS, Route后運(yùn)行report_clock命令檢查時(shí)鐘的“屬性”。如果看到“Propagated”標(biāo)志說明傳播延遲已啟用。如果沒有則需要檢查約束腳本確保執(zhí)行了set_propagated_clock命令。5. 從理論到簽核構(gòu)建穩(wěn)健的時(shí)鐘約束策略構(gòu)建一套穩(wěn)健的時(shí)鐘約束策略遠(yuǎn)不止是寫幾條SDC命令那么簡(jiǎn)單。它需要從前端設(shè)計(jì)階段就開始規(guī)劃并貫穿整個(gè)后端流程。第一步架構(gòu)與規(guī)劃。在RTL設(shè)計(jì)階段就要明確時(shí)鐘方案有幾個(gè)時(shí)鐘域它們之間的關(guān)系是什么同步、異步、衍生預(yù)期的頻率是多少時(shí)鐘門控策略如何將這些決策文檔化并轉(zhuǎn)化為初步的時(shí)鐘約束框架。第二步約束開發(fā)與驗(yàn)證。編寫基礎(chǔ)SDC約束create_clock,create_generated_clock,set_clock_groups。利用形式驗(yàn)證工具如Conformal Constraint或STA工具在門級(jí)網(wǎng)表上驗(yàn)證這些約束是否與RTL設(shè)計(jì)意圖一致。這是一個(gè)非常重要的環(huán)節(jié)可以早期發(fā)現(xiàn)約束錯(cuò)誤。第三步動(dòng)態(tài)迭代與收斂。隨著后端流程推進(jìn)不斷更新延遲和不確定性約束。特別是在CTS之后從“理想時(shí)鐘”切換到“傳播時(shí)鐘”模式是時(shí)序分析真實(shí)化的關(guān)鍵一步。此時(shí)要重點(diǎn)關(guān)注時(shí)鐘樹的質(zhì)量報(bào)告Skew, Latency, Transition并據(jù)此調(diào)整后續(xù)優(yōu)化策略。第四步簽核Sign-off確認(rèn)。在最終布線完成、寄生參數(shù)提取后進(jìn)行簽核STA。此時(shí)的時(shí)鐘約束應(yīng)該是最終版本包含了最精確的傳播延遲和經(jīng)過硅片特性驗(yàn)證的抖動(dòng)、余量值。需要檢查在多種PVT條件下WC, BC, TC等時(shí)鐘約束下是否所有路徑都滿足時(shí)序要求。我個(gè)人在實(shí)際項(xiàng)目中的體會(huì)是時(shí)鐘約束文件SDC應(yīng)該被視為與RTL代碼同等重要的設(shè)計(jì)文件。它需要版本控制需要同行評(píng)審并且任何對(duì)時(shí)鐘架構(gòu)的修改都必須同步更新約束。一個(gè)常見的良好實(shí)踐是將時(shí)鐘約束分成幾個(gè)層次化的文件一個(gè)定義所有主時(shí)鐘和生成時(shí)鐘的“基礎(chǔ)時(shí)鐘”文件一個(gè)定義時(shí)鐘組和例外路徑的“時(shí)鐘關(guān)系”文件以及在不同階段pre-CTS, post-CTS, post-Route加載的、包含不同延遲和不確定性設(shè)置的“階段配置”文件。這種模塊化的管理方式能極大提高約束的可維護(hù)性和可重用性。最后再分享一個(gè)小技巧在調(diào)試復(fù)雜的時(shí)鐘多路復(fù)用Clock Mux或動(dòng)態(tài)頻率切換電路時(shí)除了正確的create_generated_clock約束強(qiáng)烈建議使用set_case_analysis命令來固定MUX的選擇信號(hào)在不同的時(shí)鐘模式下分別進(jìn)行時(shí)序分析以確保每種工作模式下的時(shí)序都能閉合。這能幫助你發(fā)現(xiàn)那些在特定時(shí)鐘切換序列下才會(huì)出現(xiàn)的隱蔽時(shí)序問題。時(shí)鐘約束的嚴(yán)謹(jǐn)性直接決定了芯片時(shí)序的可預(yù)測(cè)性和最終流片的成功率在這個(gè)環(huán)節(jié)投入再多的細(xì)心和精力都不為過。