SDC是如何煉成的?時鍾定義篇 - 附create_generated_clock花式定義方法!


From: 老本 Benjamin RTL2GDS

定義時鍾

從最早的芯片規格定義分解出系統所需要的時鍾和頻率,以及各個模塊需要的時鍾和頻率。

SoC的時鍾一般是由PLL產生,然后經過時鍾生成電路和分配網絡,最終給具體的功能模塊使用。

一般地,第三方IP供應商都會提供比較成熟的SDC,SoC集成時需稍作修改。

對於自研的IP和SoC頂層,設計人員在提供RTL的同時,也需提供一份時鍾結構圖,一方面是方便撰寫SDC,另一方面對后端PnR有針對性的進行CTS也非常有幫助。

 

時鍾結構圖分不同的層次,或抽象或具體,看具體的需要了,下面是一顆MCU全局時鍾分布的結構圖,大家有個認識就可以:

 

 

基於詳細的時鍾結構圖,定義時鍾的命令有兩個:create_clock和create_generated_clock

其中,create_clock命令比較簡單易懂,格式如下

create_clock [-name clock_name] \ -period period_value \ [-waveform edge_list] \ [-add] \ [source_objects]



create_generated_clock命令解析:create_generated_clock命令格式如下,主要是定義generated clock和master clock的關系:
create_generated_clock [-name clock_name] \ -source master_pin \ [-master_clock clock] \ [-edge edge_list] \ [-edge_shift shift_list] \ [-divide_by factor] \ [-multiply_by factor] \ [-duty_cycle percent] \ [-combinational] [-invert] \ [-add] \ source_objects

create_generated_clock 需要指定源時鍾(master clock)的master_pin,在CTS時,默認會去balance這兩個時鍾(即generated clock 和 master clock),讓skew盡可能小。
而且在計算generated clock的clock latency時,會把從master clock pin 到generated clock pin之間的delay也考慮在內。
在工具中report_timing的時候,通過選項-path_type full_clock_expanded可以將master clock的部分也展開。

report_timing -path_type full_clock

report_timing -path_type full_clock_expanded

需要注意:在使用create_generated_clock時,需要保證電路結構和命令的效果是一致的,否則工具在report_timing時會報錯,比如下面的錯誤(UITE-461),這時就要仔細檢查分頻電路結構了。
Error: Generated clock 'CLKdiv2 with source pin Udiv/Q' 'rise_edge' is not satisfiable; zerosource latency will be used. (UITE-461)
Error: Generated clock 'CLKdiv2 with source pin Udiv/Q' 'fall_edge' is not satisfiable; zerosource latency will be used. (UITE-461)



簡單2分頻

 

先看一個簡單的2分頻的實際的例子,命令和效果圖如下:

create_clock -name SYSCLK \ -period 2 \ [get_ports SYSCLK]

create_generated_clock -name DIVIDE \ -source [get_ports SYSCLK] \ -divide_by 2 \    [get_pins FF1/Q]

 

 

 
        

考慮了edge/edge_shift的3分頻實例

 
        

下面是3分頻的實例,-edge選項中{3 5 9}分別表示SYSCLK的第3、5、9個時鍾沿(clock edge),也分別對應DIV3B的一個完整時鍾周期(上升、下降、上升)的時鍾沿時間點。

而-edge_shift選項{2.2 2.2 2.2}表示將DIV3B每個時鍾沿都往后延遲2.2ns,命令和效果圖如下:

create_clock -name SYSCLK \ -period 2.2 \ [get_ports SYSCLK]
create_generated_clock -name DIV3B \ -source [get_ports SYSCLK] \ -edges { 3 5 9 } \ [get_pins U3/Q]
create_generated_clock -name DIV3C \ -source [get_ports SYSCLK] \ -edges { 3 5 9 } \ -edge_shift {2.2 2.2 2.2} \ [get_pins U4/QN]

 

 

考慮invert/preinvert的實例

 

create_generated_clock使用-invert/-preinvert選項都表明generated clock與master clock相位相反,但這兩個選項的區別是:

  • preinvert : Creates a generated clock based on the inverted sense of the master clock.

  • invert : Creates an inverted generated clock based on the non-inverted sense of the master clock.

 

命令和效果圖如下:

create_generated_clock -name gclk_pos \-source [get_pins FF1/CLK] \-divide_by 2 \[get_pins FF1/Q]
create_generated_clock -name gclk_neg \-source [get_pins FF1/CLK] \-divide_by 2 \-preinvert \[get_pins FF1/Q]
create_generated_clock -name glk_inv \-source [get_pins FF1/CLK] \-divide_by 2 \-invert \[get_pins FF1/Q]

 

 

同一點定義多個generated clock

在實際電路中比較常見的情況是,不同的場景下使用不同頻率的時鍾來驅動電路,如下圖所示,同一個時鍾,與經過二分頻,四分頻后的時鍾經過MUX輸出給電路使用。

 

 

這種情況下,需要在UMUX輸出點定義三個時鍾CLKbypass/CLKdiv2/CLKdiv4,而且這三個時鍾在物理上是不能共存的(physically_exclusive),可以考慮使用以下命令來定義時鍾:

create_clock -period 10 CLK
create_generated_clock -name CLKbypass \ -source [get_ports CLK] \ -master CLK \ -divide_by 1 \ -combinational \ -add \ UMUX/Y
create_generated_clock -name CLKdiv2 \ -source FFdiv2/CK \ -master CLK \ -divide_by 2 \ -add \ UMUX/Y
create_generated_clock -name CLKdiv4 \ -source FFdiv4/CK \ -master CLK \ -divide_by 4 \ -add \ UMUX/Y
set_clock_groups -physically_exclusive \ -group {CLKbypass} \ -group {CLKdiv2} \ -group {CLKdiv4}


注意,這種方式定義時鍾看似合理,但是容易造成問題,因為在CLK和UMUX/Y之間有三條不同的路徑,延遲大小不同,所以在計算timing時,在launch path和capture path上選擇的路徑會不同,帶來悲觀的影響,如下圖所示,也有可能在計算min_pulse_width時造成假的違例。

 

 

在Solvnet上給出了更恰當的處理方式,具體命令如下:

# create parent clock
create_clock -period 10 CLK
# create divide-by-2, divide-by-4 generated clocks
create_generated_clock -name CLKdiv2 -divide_by 2 FFdiv2/Q -source FFdiv2/CK
create_generated_clock -name CLKdiv4 -divide_by 4 FFdiv4/Q -source FFdiv4/CK
# create "MUXed" versions of all clocks arriving at MUX
create_generated_clock -name CLK_mux -combinational UMUX/A -source UMUX/A
create_generated_clock -name CLKdiv2_mux -combinational UMUX/B -source UMUX/B
create_generated_clock -name CLKdiv4_mux -combinational UMUX/C -source UMUX/C
# create divide-by-3 versions of all clocks arriving at FFdiv3
create_generated_clock -name CLK_mux_div3 \ -divide_by 3 FFdiv3/Q -source FFdiv3/CK -master CLK_mux -add
create_generated_clock -name CLKdiv2_mux_div3 \ -divide_by 3 FFdiv3/Q -source FFdiv3/CK -master CLKdiv2_mux -add
create_generated_clock -name CLKdiv4_mux_div3 \ -divide_by 3 FFdiv3/Q -source FFdiv3/CK -master CLKdiv4_mux -add
# apply physical exclusivity to all clock families (generated clocks included)# which are exclusive due to statically switched MUX
set_clock_groups -physically_exclusive \ -group {CLK_mux CLK_mux_div3} \ -group {CLKdiv2_mux CLKdiv2_mux_div3} \ -group {CLKdiv4_mux CLKdiv4_mux_div3}


 








免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM