PrimeTime 寫出來的 Conditional WIDTH SDF 不對?平行 Constraint Arc 合併陷阱
當同一 pin 上有兩條 sdf_cond 不同的平行 min_pulse_width——例如 eFuse STROBE 在讀模式與燒寫模式下——PrimeTime 會把兩條 COND WIDTH 都寫成同一對 (min::max) 合併值。修法只有一個變數,但它必須在 link_design 之前 set;對所有依賴 restore_session 的人都是個大坑。
01問題出處
TSMC 28nm SoC 上的 eFuse hard macro。Vendor lib 在 STROBE pin 上定義了兩條 min_pulse_width——讀模式約 142 ns,燒寫模式約 11000 ns——只能透過 sdf_cond 字串(check_read_start 與 check_pgm_start)區分。PrimeTime 完整 signoff 後寫出的 SDF 內,STROBE 上的兩條 COND WIDTH 都掛了同一對 (min::max):142.4570 :: 11000.0000。
乍看之下這個輸出沒什麼錯——數字確實出現過。但它是錯的:兩個值來自不同的 condition。PrimeTime 把讀模式的 pulse width 與燒寫模式的 pulse width 合併成一對 bounding (min::max),然後把同一對複製到該 pin 上每一條 COND WIDTH。
Gate-level 模擬讀進這份 SDF 後,STROBE 上每一個 WIDTH 檢查——不論電路當下處於讀或燒寫模式——都會被拿錯誤的上界去比對。輕則模擬期間出現假違例,重則真實違例被遮掉。無論哪種,這份 SDF 都已經不是 lib 的忠實反映。
02現象
Lib 裡兩條平行 min_pulse_width 對應 SDF 裡兩條 COND WIDTH,但兩條的數值在條件之間互相串了,沒有保持各自獨立。
03Liberty 真正記錄的東西
兩條互斥 when 的平行 min_pulse_width——是任何含模式 pin 的 IP 都會用到的標準寫法。
- •模式 Pin 驅動條件
PD、CSB、PGENB、LOAD、PS——eFuse 上五個模式 pin。每一條 min_pulse_width 的 when 字串都對應一個唯一的功能態。
- •sdf_cond 是輸出標籤
每一條 min_pulse_width 帶一個 sdf_cond 字串,SDF writer 應原樣寫進 COND 子句。這是 SDF 唯一能用來辨識「這個值屬於哪個功能態」的握把。
- •互斥是 Lib 規則
Library Compiler 對於 when 不互斥的多條 min_pulse_width 會發警告。Lib 乾淨的話,任何真實矽片狀態下都只有一條 constraint 是 active。
- •constraint_high 是高脈衝最小寬度
min_pulse_width () { constraint_high : N; } 設定高脈衝的最小寬度。這個案例兩條值差了約 80 倍——讀模式 142 ns vs 燒寫模式 11 us。
04根因:平行 Constraint Arc 在 link 階段被合併
PrimeTime 預設會把平行 constraint arc 以 bounding 形式儲存。同一個 endpoint 上的兩條 min_pulse_width 並不會以兩個獨立值留存到 link_design 之後——它們在 bundled arc 上塌成單一對 (min, max)。write_sdf 隨後從同一對合併值產出兩條 COND 行。
05關鍵變數:timing_parallel_constraint_arcs_compatibility
整個行為由一個 application 變數控制。預設值 false。要拿到 per-condition 的 SDF,把它設成 true。
- 01預設是 falsePrimeTime 預設 timing_parallel_constraint_arcs_compatibility = false。平行 constraint arc 在 link 階段被合併為 bounding pair——這就是 SDF 現象的源頭。
- 02set 為 true 即關閉合併set timing_parallel_constraint_arcs_compatibility true 告訴 PrimeTime 完整保留所有平行 constraint arc 數值。每個 sdf_cond 在 link、update_timing、write_sdf 全程保持自己的 constraint_high。
- 03必須在 link_design 之前 setSynopsys man page 寫得很清楚:「This variable must be set before the link_design command is run.」link_design 才是決定平行 arc 儲存方式的時刻。link 之後再 set 沒有任何作用。
- 04相容性提示變數命名與描述都暗示「不合併」是舊版預設。如果某個老腳本不設這個變數也能寫出正確 SDF,幾乎肯定當年跑在合併還沒預設啟用的舊版 PrimeTime 上。
06順序陷阱:restore_session 救不了
團隊在這個問題上最容易燒掉一個下午的方式,就是把變數設在錯誤的時機。PrimeTime session 存的是 link 之後的 timing graph,而不是 application 變數狀態;任何會影響 link 行為的變數都得在「原始建 session」的 shell 裡設,而非「restore session」的 shell。
07PT vs Tempus:相關的 Conditional Pulse-Width 差異
同一個 eFuse 設置還會在 PrimeTime 報違例、Tempus 不報。是另一個問題,但結構同源:兩家對「未明確 case_analysis 時 conditional min_pulse_width 該怎麼處理」採用了不同預設。
在同一個 STROBE pin 上,PrimeTime 會用燒寫模式的 11000 ns 去比對 SoC 在功能讀模式下實際 ~114 ns 的 STROBE 脈衝,slack 報 -10886 ns。Tempus 在同樣的資料庫上不報任何東西。
PrimeTime 並不會去解 conditional min_pulse_width 的 when 表達式。它無法判斷 PD、CSB、PGENB、LOAD、PS 是否被約束在「check_pgm_start 不可達」的狀態。沒有對這些模式 pin 顯式 set_case_analysis,兩條 conditional 都會保持 active,而最壞那條主導違例。
Tempus 似乎對未解 conditional pulse-width 用了不同預設——更接近「條件不可達就不報」。兩種行為都不算錯,只是對同一個歧義輸入採用了不同預設。在 PrimeTime 裡的修法是用 set_case_analysis 鎖住模式 pin,讓燒寫模式 constraint 自動失效;或直接用 set_disable_timing 對應 timing arc 把它關掉。
08修復腳本
一份乾淨可重複的 PrimeTime 流程,產出 per-condition SDF 並避免模式相依的假違例。對任何用了 conditional 平行約束的 IP——eFuse、OTP、自訂類比 wrapper、含 mode-dependent min_pulse_width 或 min_period 的東西——都當清單用。
09如何驗證輸出正確
三個檢查確認修復生效、SDF 忠實。
- •1. 確認變數在 link_design 之前 active
set 之後立刻 printvar timing_parallel_constraint_arcs_compatibility,link_design 之前再 print 一次。用 report_app_var -only_non_default 抽查整體 override 集合。
- •2. 驗證 sdf_cond 在 lib 中保留下來
Link 之後查詢:foreach_in_collection a [get_lib_timing_arcs -of [get_lib_pins '*/STROBE']] { echo "[get_attribute $a sdf_cond] [get_attribute $a when]" }。sdf_cond 為空表示 .db 編譯時沒保留字串——要從原始 .lib 重編。
- •3. 對 SDF Per-Condition Diff
Write_sdf 之後 grep 該 pin,確認每一條 COND WIDTH 行的 (X::X) 中 X 等於該 when 對應的 constraint_high。如果同一 pin 上兩條行還共享同一對 (min::max),表示合併發生了——回頭檢查變數是否真的在 link 之前設好。
10其他會影響的設定
這個變數不孤立工作。幾個鄰居設定會強化、遮蔽、或覆蓋它的效果。
11為什麼這個 pattern 在不同專案重複出現
Conditional min_pulse_width 與 min_period constraint 出現在所有有模式 pin 的 IP——eFuse、OTP、MTP、有模式控制的 PLL、某些 ADC 取樣時鐘。Library 編碼是標準的,signoff 失效模式也是標準的。
12結語
現代 signoff 的工程風險,多半已不在數學裡,而在工具預設與 lib 編碼如何互動。Conditional min_pulse_width / SDF 這個案子是個乾淨的例子:一個變數、一條順序規則、一個 lib 慣例——一個能順利通過完整 STA signoff、卻以靜默損壞形式落到 gate-level 模擬裡的失效模式。
如果你的專案用了 eFuse、OTP,或任何含模式相依 pulse-width constraint 的 IP,請審查交給 gate-level 模擬的 SDF。看同一 pin 上多條 COND WIDTH 行是否共享相同 (min::max)——這就是這個陷阱的指紋,而修法只是放在對的檔案裡的一行 TCL。
遇到一個 SDF 或 signoff 異常解釋不通?
我們在 PrimeTime 變數、lib 編譯、工具預設差異裡花了不少時間。把現象丟過來——我們會告訴你這是設置問題、工具 bug,或 lib 在藏什麼。
References
- [1]PrimeTime Suite 變數與命令參考Synopsys
- [2]Standard Delay Format (SDF) 3.0 規範IEEE 1497
- [3]Liberty Reference Manual — min_pulse_width 與 sdf_condSynopsys / OSCI Liberty
