IO約束在頂層和模塊級的主要命令都是以下幾個,但是實際應用的復雜程度不可同日而語,本篇會先介紹模塊級IO約束實戰經驗,然后講解頂層IO約束復雜性,過程中會介紹DDR接口時序。
set_input_delay
set_output_delay
set_drive
set_driving_cell
set_input_transition
set_load
...
各個命令的具體用法可以在PT中通過man了解詳情,這里就不費勁重復了:
pt_shell > man set_input_delay
模塊級IO約束實戰
上圖給出了一種IN2REG路徑的示意圖,DUA為當前模塊,外部有一個假想的虛擬寄存器在驅動CIN端口,這種情況下我們可通過以下命令來約束:
set period 8
create_clock -name CLKP -period $period [get_ports CLKP]
#創建同頻率的虛擬時鐘
create_clock -name vCLKP -period $period
#參考值為0.6,根據實際情況調整
set_input_delay [expr 0.6 * $period] -clock vCLKP [get_ports CIN]
#假設端口buffer為BUFX4
set_driving_cell -lib_cell BUFX4 -pin Z [get_ports CIN]
虛擬時鐘的作用
使用set_input_delay時,可以指定真實時鐘CLKP,也可以指定虛擬時鐘vCLKP,在CTS之前是沒有區別的。然而,在CTS之后,如果指定的是真實時鐘,那么虛擬寄存器的時鐘延遲就被忽略了。如果指定的是虛擬時鐘,工具往往可以根據內部真實時鐘的平均延遲來估算外部虛擬寄存器的時鐘延遲,更加合理。
一般地,為了讓頂層的時序更容易滿足,在模塊級優化的時候,都會對自己內部的IN2REG和REG2OUT路徑約束更加嚴格,可以設置外部的延遲為60%的時鐘周期,給內部的數據路徑留40%的空間。不過,具體問題需要具體分析了。
需要注意,set_input_delay 可以指定-max和-min選項,分別對應setup和hold時序檢查,如果只是指定其中一個選項,或者都不指定,那么工具在檢查setup和hold時,會使用相同的值。
端口Buffer和set_driving_cell配合使用
在實際項目中,為了避免模塊之間,或者模塊和頂層之間IO接口部分出現時序問題,一般會要求在靠近IO端口的地方添加具有一定驅動能力的端口Buffer。在這種情況下,可以通過set_driving_cell來模擬端口的真實外部環境。假如沒有端口Buffer,也可以通過set_input_transition大致指定輸入端口的驅動能力。
總體來說,set_driving_cell會考慮到OCV的影響,input transition是查表計算出來的,而set_input_transition比較簡單粗暴,在IO端口時序不那么關鍵的時候,也可以使用。但在頂層,一般使用后者,因為IO單元的輸入電容較大,芯片外部具備驅動能力較強的器件,標準單元庫中沒有buffer能夠驅動。
頂層IO約束實戰
頂層IO約束在原理上與模塊級沒有本質區別,然而由于頂層需要與外部器件進行通訊,除了GPIO,還會接觸到各種標準協議接口,例如UART,I2C,SPI,LVDS,DDR等等,在寫SDC前需要讀一讀協議。更復雜的情況是,由于存在端口復用的情況,往往同一個端口具備多種時序要求,需要逐一定義。
上圖是一個PinMux(也稱為IOMux)的示意圖,在SoC設計中非常常見,特別對于IO limited的芯片來說,PinMux是很有必要的。看似復雜,其實只要各個擊破就能達到目標,SDC標準制定者已經為我們考慮到了這一點,通過set_input_delay的選項-add_delay,可以對同一個端口設置多重約束,例如:
set_input_delay [expr 0.6 * $periodA] -clock CLKA [get_ports CIN] -add_delay
set_input_delay [expr 0.3 * $periodB] -clock CLKB [get_ports CIN] -add_delay
另外,針對頂層輸出數字端口,需要根據芯片使用的實際情況set_load,一般的GPIO端口負載電容都在pF級別。
-
寄存器
+關注
關注
31文章
5357瀏覽量
120668 -
SoC設計
+關注
關注
1文章
148瀏覽量
18791 -
輸入電容
+關注
關注
1文章
41瀏覽量
9842 -
虛擬機
+關注
關注
1文章
919瀏覽量
28279 -
DDR接口
+關注
關注
0文章
5瀏覽量
7549
發布評論請先 登錄
相關推薦
評論