把一切交給時間 之版圖實現(xiàn)第五步 -- clock
掃描二維碼
隨時隨地手機看文章
clock是整個timing closure中最重要的部分,只有把這顆時鐘樹(clock tree)種好了,我們才能吃到甜美的果實。
按照慣例,先拿流程圖來做以總覽
由于clock是在給實際放置好std-cell的數據庫,構建真實的clock tree,每一個std-cell的位置都會影響到CTS的構建,所以,一個要用來build clock tree的數據庫需要有以下的基本質量:
1:所有的cell 都是經過優(yōu)化處理的
2:所有的cell的放置都是合法化的(legalize),CTS是不會動已經放置好的cell的,在CTS步驟里邊legalize,一般的cell只會非常位置偏移。這是保證place timing、congestion最好的選擇)
3:數據庫里的data path沒有大扇出的max_fanout問題
我們經常說clock tree。那么什么是clock tree呢,在開始CTS之前,我們先來認識一下什么是clock tree。
一般把clock稱之為tree(樹狀結構),是非常形象的。我們用下面這個二叉樹的拓撲結構圖,表明了一個clock domain的邏輯結構:
如圖所示,我們對各個點位做如下設定
點位1: primary clock source。使用create_clock命令所對應的clock點
點位6/7/8/9/10: 掛靠在這個primary clock 下面的leaf FF。
點位2/3: 隸屬于在這個 primary clock 下面的generated clock:從屬于primary clock的generated clock
點位4/5: 點位2的generated clock tree里邊的組合邏輯:一般的設計都會有DFT的mux在這些位置上。
從以上樹狀圖示例里邊,可以看到一個簡單clock domain里邊的各個元素。
理論上講,所有隸屬于primary clock source (點位1)的leaf cell (點位6/7/8/9/10),它們之間都是可能有timing check的。從clock tree的角度而言,每一個leaf cell 的clock pin到clock source的delay都要盡可能的相似,這樣才會盡可能的接近place的時序結果(都為0,也是一種相似)。因為在place階段,我們假設所有的leaf FF到clock source 都是0 delay的(ideal_clock)。
在了解了clock 的樹狀結構后,這里要再澄清幾個基本概念,有助于我們理解clock tree和工具的行為。
Primary clock: 這個是模塊的主時鐘,一般的模塊至少有一個主時鐘,有時會有多個,但是相互之間通?;楫惒疥P系。一般使用create_clock命令定義的clock就是主時鐘。這種clock一般的定義點無外乎port或者內部macro的輸出。
命令示例:
create_clock [get_ports func_clk_i] -name clk_func_clk -period 100 -waveform {0 50}
Generated clock: 這個是模塊內部的分頻時鐘。這個clock 的source通常來自于primary clock,或者另外一個generated clock(在層疊(cascaded)generated clock的 情況下)。它的定義點一般來自于一個clock gating cell (latch output)或者一個DFF的輸出點。
命令示例:
create_generated_clock [get_pins gated_clk_latch/o] -name gclk_1_func_clk -source [get_ports func_clk_i] -master_clock clk_func_clk -edges {1 2 5} ; # a latch as clock gating cell, half frequency with 25/75 duty cycle
create_generated_clock [get_pins divider_reg/o] -name gclk_2_func_clk -source [get_ports func_clk_i] -master_clock clk_func_clk -edges {1 5 9} ; # DFF divider for a clock, 1/4 frequency with half-half duty cycle.
Latency:時鐘延遲值。這個是從clock source到你的leaf cell的 clock pin的時延值。
Skew:同一clock domain下邊的,任意兩個leaf cell時鐘延遲之差的最大值。這個是評估一個clock tree做的好還是不好的關鍵指標。一般是基于一個clock domain的所有l(wèi)eaf FF/macro clock pin。Skew越大,timing越難收斂,hold/setup也容易出現(xiàn)沖突。通常來講,CTS的目標就是降低skew,如果做到極致,skew為零,那么我們的時鐘樹就是理想的樹了。
以下圖為例,構建了連帶上述命令描述的一個clock domain結構
從上圖這個clock domain上可以抽取出以下信息
有了上面的這個latency,就可以推算出來skew如下
最終的評判某一個clock tee是不是做的好,就是來自于上邊這個clock skew值。
這里需要在做以下說明以幫助大家理解
1:示例里邊有有三個clock domain:一個primary clock 外加兩個generated clock
2:在CTS的優(yōu)化中,如果一個leaf cell的位置同時處于primary clock 和 generated clock 的fanout,CTS約定,在構建clock tree 的時候,它只屬于離它最近的generated clock。Skew的計算機制也是基于此。
3;通常來講,同屬于一個primary clock下邊的所有generated clock 以及它們的primary clock都是一個同步組(sync-group),它們之間的leaf cell都有timing check。所以這里邊會有 func_clk_ff* 和 gclk*_ff* 的timing check。
有了這些基本概念后,現(xiàn)在開始做CTS前的配置工作:
1: clock reference lib cell 設定
一般的clock buffer、inverter都是相較于普通buffer/inverter更快,但是面積、漏電流也更大。所以這些cell只用于做 clock tree的構建。來獲得更小的skew和latency。整個芯片在這樣的規(guī)劃下,達到一個面積、功耗和clock skew的平衡點。
所以在整個流程中,嚴格來講,只有在CTS這一步才會打開clock buffer/inverter 給clock tree使用,剩下的所有步驟都是禁止使用clock buffer/inverter的,這里會提出一個新的一個檢查點,在你準備做CTS之前,先檢查一下你的place數據庫,如果有clock library cell存在的情況,請查閱你的target library 來定位問題。
命令示例如下:
set_clock_tree_references -references {clk_buf1 clk_buf2 clk_inv1 clk_inv2}
ICC的這個命令優(yōu)先級很高,無論這個lib_cell在之前是不是被dont_use,這個命令都會讓CTS使用這些cell來構建clock tree(但是如果命令set_clock_tree_references 之后,仍然對這些lib_cell進行dont_use設定,這樣依然會阻礙CTS的使用)。這里一定要注意一個問題,就是這個列表里邊一定要有inverter,否則在CTS時候出錯。
2:clock NDR rule
NDR是一個縮寫,全稱是None Default Routing-rule。我們在進行CTS的時候要引入這個特殊的clock routing rule,以備工具測算真實的clock net routing resources使用。這里我們需要對clock設定較普通繞線更為嚴格的routing rule
一般講,在同一層的兩根普通繞線,可以落在相鄰的兩個track上,在線寬合規(guī)的情形下,就不會有PV DRC spacing的問題。但是為了能削弱SI對clock net routing的影響,我們這里給clock定義了更為嚴格的multiple spacing routing rule,這個multiple至少是2或者3。設定后,工具在規(guī)劃資源的時候就會考慮clock的額外需求。下面的命令定義了一個3倍spacing的NDR rule。
define_routing_rule clk_NDR_rule -default_reference_rule -multiplier_spacing 3
而后,我們需要把這個NDR rule關聯(lián)到clock 上就好了,命令如下
set_clock_tree_options -routing_rule clk_NDR_rule
3: clock routing layer的設定
還記得我們在第三章,power那一部分的講解嗎?在那里,我們提到過clock的routing layer的信息。Clock routing的繞線優(yōu)先級是高于data path的,所以在繞線層的定義上,我們會把clock routing layer盡量定義到高層。
如果我們最高繞線層是M8,我們可以定義如下
set_clock_tree_options -layer_list {M6 M7 M8}
4;logical DRC的設定
我們知道,在timing分析里邊,都會有DRC的目標,在CTS中,基于項目需求,我們會有更嚴格的目標設定,下邊是一個示例,具體需要依據項目和工藝的要求設定:
set_clock_tree_options -max_transition 0.3
set_clock_tree_options -max_capacitance 0.1
set_clock_tree_options -max_fanout 32
還有一個就是我們前面提到的CTS的重要目標:skew (盡管這個不是DRC的范疇)
默認工具是按照0來約束skew的,這是一個理論值,實際是不可能達到的,只有ideal clock tree才能達到。我們基于項目需要和clock period設定一個稍微寬松的值,對于rum time、power、面積等指標回事一個科學的折中,示例如下:
set_clock_tree_options -target_skew 0.2
5: 特征點的設定:
CTS支持以下特殊點的設定,這些設定會影響CTS的細節(jié),正常情況下,用戶不用干預,這里我們不做展開,會有一篇CTS番外來介紹他們的細節(jié),有興趣的同學可以關注下。
Stop pin: 停留點位
None-stop pin: 非停留點位
Exclude pin: 除外點位
Floating pin: 單列點位
Ignore pin: 忽略點位
到達這里,我們已經有了大體的概念了,接下來我們就來看看CTS 到底在我們的數據庫里做了哪些神操作。
工具在讀取了上述的各項設置后,就可以開始愉快的build tree了(真的會愉快嗎?^_^)
大家回看一下在本文開始的那個樹狀結構圖,對于這個樹狀結構,cts其實是在做一個多叉樹的遍歷過程。所以在build tree的時候,有兩種方式可以選擇top-down和bottom up。
在一般的應用中,我們習慣使用top-down方式, 從clock source 做起,直到找到一點的leaf cell clock pin,然后構建這點到clock source的clock buffer tree;接下來依次查找下一個leaf cell clock pin,然后再次構建這個新點到clock source的clock buffer tree。如此往復,直到把整個多叉樹的結構遍歷完成。
但是在cts里邊,它的目標是控制latency和保證skew,如果是top-down的方式,工具永遠不知道當下節(jié)點的多叉樹有多深,很難判定你在當前節(jié)點需要構建多少latency,很有可能帶來反復修正的問題,這樣的會大大降低clock tree的質量。所以從收斂skew的角度,選擇bottom-up的方式是更為合理的。
于是就有了下邊這張cts遍歷多叉樹順序圖。有了這張圖,再也不用擔心cts看不懂了。
為了保證完備性,不漏掉任何一個leaf cell clock pin。這里的多叉樹的遍歷本質上是一個遞歸的過程。在每一次遞歸的節(jié)點,cts都會記錄下當前的phase delay(從當前結點到leaf cell clk pin的delay信息),依據這個phas delay信息,無論leaf cell距離clock sourced的深度有多大的不同,工具都盡量讓每一個leaf cell clk pin的latency相近,這就是使用clock buffer/inverter 要完成的目標。
同時在構建clock tree的時候,工具一定會兼顧max_tran,max_cap等DRC的需求。一個tree有好的skew那么他的hold就好控制,有了高質量的transition、cap那么他的aocv效應的影響就能降低,最終都朝著mcmm timing clean的目標進發(fā)。





