1問題
在做模塊級約束的時候,外部的真實IO delay是還不知道的。為了讓模塊綜合結果盡可能滿足外部苛刻的條件,經驗值是將IO delay設置為相關聯的驅動時鐘周期的60%,給模塊內部的路徑留下40%的時鐘周期,這適用于
1.INPUT->REG路徑
2.REG->OUTPUT路徑
而對于INPUT->OUTPUT的路徑(feedthrough),如果按照這樣的設置,因為端口輸入和輸出延時已經占了60%+60%=120%的時鐘周期,超過一個周期,這是不可能實現的約束,一般會把IO delay調節成IO 相關聯的驅動時鐘周期的40%,給模塊內部的路徑留下20%的時鐘周期
但是對于下面這樣一種電路,情況有些特殊,這也是實際設計中經常出現的電路:
注意到這個電路的不同之處在于,INPUT不僅連接了INPUT->REG的路徑,同時另一分支連接到OUTPUT。而OUTPUT也同時被COMBO-A和REG->OUTPUT的邏輯所驅動。對于這樣的結構,
1.對于INPUT->REG,和REG->OUTPUT,總是希望IO delay是60%的時鐘周期的
2.INPUT->OUTPUT的feedthrough約束為20%的時鐘周期。
要怎樣才能同時滿足這兩個需求呢?
2結論與解決方案
1. 在做模塊級綜合的時候,對于IO路徑一般會使用60%的端口時鐘進行約束,如果這樣的路徑涉及到feedthrough path,也就是INPUT->REG的路徑同時有分支到INPUT->OUTPUT的路徑,并且該OUTPUT同時被這段feedthroughlogic以及REG驅動,全部按照端口60%驅動時鐘的IO約束會造成無法優化的路徑,也就是infeasible path
2. 對于infeasible path,dc不會做任何優化,如果不解決這樣的問題,綜合結果不是最優解
3. set_max_delay=input delay(60%CLK_V)+comb delay+output delay(60%CLK_V)可以解決這個問題,但當端口情況復雜的時候約束數量會很多,并且約束本身不便于理解
4.在同一個端口既定義了專門使用于INPUT->REG和REG->OUTPUT的CLK_V,同時定義了專門使用于INPUT->OUTPUT的CLK_V_FEED,并設置相應的CLOCK GROUP或者false_path可以最好地滿足這個需求。
3測試與實驗
以下面RTL為例:
這樣一個電路經過翻譯之后(綜合優化之前)大概是以下的電路,INPUT->OUTPUT的路徑組合邏輯部分是兩個乘法器,而INPUT->REG的組合邏輯部分是兩個加法器(這里不過多關注具體的功能):
假設:
1.周期設為2ns,500MHz的頻率
2.整個設計只有一個時鐘
3.每條路徑都是單周期路徑
4.IO的相關寄存器都存在于block之外,需要設置Virtual clock
5. INPUT端口(除去CLOCK)驅動為一個X1的buffer,OUTPUT端口的負載均為3個X1的buffer
如果我們按照傳統的約束方法,將IOdelay設置為60%的時鐘周期:
經過DC綜合之后,可以看到電路被優化成了以下結構,藍圈部分是input port->reg的路徑,以寄存器為終點。紅圈部分是我們要重點關注的input port->output port的路徑,也就是feedthrough path:
我們使用report_timing看一下結果。
可以看到input port->reg(藍)的路徑主要是兩個加法器,重點關注input delay的設置,成功地被設置成60%的時鐘周期(2*0.6=1.2),這是符合預期的。并且這條路徑滿足時序要求:
然后我們再看下input port->output port的路徑(紅)。這塊主要是兩級乘法器的邏輯。因為這塊邏輯包含了不止一條的路徑,report_timing默認情況下選擇最差的一條(in_3[0]->out_comb[1]):
可以看到這條路徑被映射成了AND2X1->AND3X1->INVX1->AND3X1->XOR2X1,單就這一段組合邏輯的延時(算上端口上的延時)是0.59。因為input delay和output delay已經超過了一個時鐘周期(6+6=12>10),所以無論這段邏輯如何優化,都會是違例路徑。
另外我們注意到在使用report_timing的時候,DC顯示了如下warning:
這里infeasible的意思為“不可實行的”,查看該warning的詳細信息:
這段描述的重點在紅線部分。Infeasible path指的是那些無論如何都不可能滿足約束的路徑,也就是我們這個例子中Input port->output port的這條路徑。如果不加以處理,綜合器對這種路徑是不會做任何優化的,會影響到最后的QoR。
按照manpage中的WHAT NEXT的方法,使用report_timing -attribute可以看到這段路徑是infeasible的:
既然問題是由于約束過緊導致,那么只要相應的放寬對這條路徑的約束就可以了。之所以這個例子比較復雜,是因為我們如果不做特殊設置的話,無法兼顧到同時滿足
1.對于INPUT->REG,和REG->OUTPUT,總是希望IO delay是60%的時鐘周期的
2.INPUT->OUTPUT的feedthrough約束為20%的時鐘周期。
為了解決這個問題,我們必須對此類路徑做特殊設置。
方法1:
在約束中有一類特殊的約束叫exception,就是為了特殊情況而存在的。
可以使用set_max_delay的方法來對這樣的路徑進行單獨約束,因為set_max_delay是一種exception,它可以覆蓋原有的約束。舉個例子,如果這條feedthrough path你所期望的延時是DELAY_COMB,并且端口的IO delay還是想保持原先的60%的時鐘周期,那么可以通過設置max_delay=DELAY_COMB+0.6*P_VCLK*2。
這里可以看到這段INPUT->OUTPUT的max_delay被設置成了1.2倍的時鐘周期外加一段延時的時間,這在現實中是不可能存在的路徑。但這么設置并不意味著這條路徑從外部起始寄存器->INPUT->COMB->OUTPUT->外部終點寄存器真的有超過一個時鐘周期那么長(假設整個設計只存在一個時鐘)。這樣設置只是因為set_max_delay這個約束在進行分析的時候會天然考慮到input delay和output delay,而在這個方法中,并沒有對端口的input delay和output delay進行改動,他們還是60%的時鐘周期。這個約束的關鍵在于給予了中間這段從INPUT->OUTPUT的路徑一段額外的DELAY_COMB的時間,而這個值是可以自己確定的。假設留給這段邏輯20%的時鐘周期,也就是0.2*2=0.4,在約束中加入以下設置:
綜合之后的report_timing -from in_3[0] -to out_comb[1] -attribute結果:
根據這個新的結果,我們可以看到
1.之前的約束違例問這條路徑不再是infeasible path
2.之前這條路徑是AND2X1->AND3X1->INVX1->AND3X1->XOR2X1,總的延時是0.59。DC沒有做任何的優化。而在增加了max delay的約束之后,DC重新將這段路徑優化成了NAND2X0->OR2X2->NBUFFX2->NAND2X0->XOR2X2,總的延時是0.5,以此來滿足20%的時鐘周期也就是0.4的約束。 雖然仍然有違例,但比起之前infeasible path沒有得到優化,這段路徑的在優化后延時減小了。
方法2
方法1使用set_max_delay來給這段INPUT->OUTPUT路徑設置20%的時鐘周期,對于一組的INPUT->OUTPUT,約束只需要加三行。
但實際上在綜合之前,是不知道哪些INPUT->OUTPUT會存在這樣的feedthrough的情況,因而為了保證結果,對于所有這樣的路徑都要進行max delay的設置來防止infeasible path的出現。實際的設計中端口不全是由是一樣的外部時鐘驅動,對于不同外部時鐘驅動的端口,都要分別進行max delay的約束。假設這樣的INPUT->OUTPUT組數特別多,方法1實際上是很繁瑣的。比如如果有3個輸入都是不同時鐘驅動的,3個輸出也都是不同時鐘驅動的,那么一共有3*3=9組max_delay需要設置。
并且使用max delay的設置,從直觀上并不利于理解。因為max delay設置的值實際上超過了一個時鐘周期。
那么是否可以對feedthrough的IO端口額外做如下設置?
通過使用set_input_delay -add,在IO端口額外加上一個40%VCLK的時鐘。這樣對于上述場景(3個輸入都是不同時鐘驅動的,3個輸出也都是不同時鐘驅動),只需要6條設置input delay和output delay的命令,不需要對于每一組可能情況都去進行設置。
并且這樣對于INPUT->REG的路徑,還是會使用60%VCLK的約束,滿足需求。但是對于feedthrough path,因為IO同時存在40%VCLK和60%VCLK的約束,他們都是基于同一個時鐘VCLK,實際上還是會使用更緊的60%VCLK-60%VCLK的約束,而忽略了40%VCLK的約束,問題還是沒有得到解決。使用report_timing -from in_3[0] -to out_comb[1] -attribute觀察路徑:
為了將feedthrough的路徑和INPUT->REG/REG->OUTPUT的路徑區分開來,需要在端口專門設置虛擬時鐘CLK_V_FEED來進行約束:
重新綜合,使用report_timing -from in_3[0] -to out_comb[1] -attribute觀察路徑:
可以看到這個infeasible的約束依然存在。
不同的地方在于,此時我們通過命令report_timing-from [get_clocks CLK_V_FEED] -to [get_clocks CLK_V_FEED] 觀察同樣的路徑,可以看到相新設置的CLK_V_FEED已經設置到端口上了:
如果能有一個辦法來取消CLK_V到CLK_V的約束就好了。
在exception中,false path可以實現類似功能,在這里可以使用false path設置:
重新綜合,使用report_timing -from in_3[0] -to out_comb[1] -attribute觀察綜合后路徑:
可以看到這個時候這條路徑的結果已經好于加false_path之前的結果。這是因為如果沒有設置false_path,更緊的feedthrough約束60%CLK_V->60%CLK_V會占主導作用,DC發現有infeasible的約束時便不做任何優化,即便合理的約束也同時存在。而false path可以解決這個問題。
但使用false path與之前set_max_delay類似,因為必須是每組clock一一對應,當端口clock數量繁多的時候,會有設置繁瑣的問題。
與false path相類似功能的,有另外一個命令是set_clock_groups,實現起來比較簡單。被設置到同一個group的時鐘之間存在約束,而被設置到不同group的時鐘之間不存在約束。如果通過set_clock_groups將驅動INPUT的CLK_V時鐘和OUTPUT驅動的寄存器CLK_V時鐘分到不同的clock group,那么這個問題就能得到解決。
但由于這里驅動INPUT的CLK_V和OUTPUT驅動的寄存器的CLK_V是同一個時鐘,一個時鐘沒法被分到不同的group,必須將CLK_V分為CLK_V_I和CLK_V_O:
設置CLK_V_I和CLK_V_O到不同的clock group,可以取消CLK_V_I和CLK_V_O之間的約束,但在這一步之前,需要先確定好CLK_V_I/CLK_V_O和CLK以及CLK_V_FEED之間的關系。CLK_V_I/CLK_V_O與CLK之間的約束是需要的,這是INPUT->REG和REG->OUTPUT的關系,要把他們歸到一個group。而CLK_V_I/CLK_V_O與CLK_V_FEED之間的關系是不需要的,因為這里只需要40%CLK_V_FEED->40%CLK_V_FEED的feedthrough約束,而不需要類似60%CLK_V_I->40%CLK_V_FEED這樣的關系。
可以通過以下設置,其中第二個set_clock_group用于取消第一個set_clock_group里的CLK_V_I和CLK_V_O之間的關系:
這樣一來,CLK_V_I和CLK_V_O之間就不會存在約束。再次綜合,使用report_timing -from [get_clocks CLK_V_I] -to [get_clocks CLK_V_O]:
可以看到原先存在的60%CLK_V-60%CLK_V路徑因為clock group的原因已經不存在了。
使用report_clock -groups來觀察當前的clock group和false path情況,符合預期:
最后使用report_timing -from in_3[0] -to out_comb[1] -attribute觀察綜合后路徑:
1. 使用virtual clock的約束和之前使用set_max_delay的約束實現了同樣的目標,給feedthrough path留下了2-0.8-0.8=0.4的時間,達到了目的。(注意到這和set_max_delay的綜合結果并不一致,但路徑都得到了優化)。
2.相比于set_max_delay,使用virtual clock約束更便于理解,當端口時鐘情況復雜的時候設置起來更加便利。
3.false path 和 set_clock_group都能實現需求,但當外部clock數目很多的時候使用set_clock_group來定義clock之間的關系比set_false_path更為簡潔明朗
4. false path只針對STA,set_clock_group可以選擇logically exclusive, phisically exclusive。在后端做信號完整性分析的時候有區別。使用set_clock_group會更合理一些。
4補充
最后完整的sdc如下:
這里提供了兩種參考方法,但具體到實際項目中,不同的設計不同的情況不同的公司有不同的應對,大家在實際設計中都是如何處理這種情況的呢?歡迎留言討論。如果文章中有任何錯誤,也請留言指出,大家一起學習進步~
-
電路
+關注
關注
172文章
5934瀏覽量
172462 -
時序
+關注
關注
5文章
389瀏覽量
37356
原文標題:時序約束實例分析——特殊的feedthrough path
文章出處:【微信號:ic_frontend,微信公眾號:數字前端ic芯片設計】歡迎添加關注!文章轉載請注明出處。
發布評論請先 登錄
相關推薦
評論