其實,關於密度有兩個說法。
一是utilization,也就是設計的利用率。一般來說,為了成本考慮,利用率能做的越高越好,也就是std cell密度越高越好。
二是在利用率確定的情況下,std cell的局部密度,也是今天要討論的話題。
在設計的面積已經確定的情況下,std cell局部密度是越低越好?還是越高越好?答案當然是不一定。
局部密度高,對時序好。因為線短,net delay小,transition小,cell delay也小。但是,局部密度過高,可能對繞線不好,另一個風險是沒有足夠的空間給eco來修timing和修hold等。
局部密度低,恰恰相反,對繞線好,但是對timing差,對power也不好。
所以,一般的設計里,局部密度要綜合考慮:即congestion嚴重的地方,cell密度要低點;timing要求高的地方,cell密度可以高點。所以整個設計里的密度通常看起來是不均勻的。
那么在ICC2里,到底是誰在控制密度?
答案是placer(或者叫coarse placer)。placer在ICC2里至少有三處被調用:
第一處:place_opt -from initial_place -to initial_place
第二處:place_opt -from final_place -to final_place
第三處:clock_opt -from final_opto
如果腳本里還有使用create_placement,那也是在調用placer。
placer會在timing要求高的地方,把std cell擺的緊湊,局部密度高。在有congestion的地方,把std cell往四周推開,讓這個區域密度低,有利於解決congestion。
下一個問題來了,密度需要高的地方,可以高到什么程度?解congestion往四周推散cell,推的力度又可以到達什么程度?
ICC2里有兩個對應的參數來控制。前者用max_density,后者用max_util。
max_density用來控制放std cell時的最高密度,最高不可以超過它。
max_util來控制解congestion時,往四周推散cell的力度,最高不可以超過它。比如max_util=0.9,那么往周圍推散cell時,周圍的std cell密度(利用率)達到了0.9就停止推了,即使還沒有完全解決congestion也會停下來。因為再往四周退散,四周密度超過90%,就有很大的風險了。
max_util=0.9,那么往周圍推散cell時,周圍的std cell密度(利用率)達到了0.9就停止推了,即使還沒有完全解決congestion也會停下來。因為再往四周退散,四周密度超過90%,就有很大的風險了。
兩個參數都是用來控制最高密度,但是作用不一樣。前者是開始放std cell的時候,能達到的最高密度;后者是placer解cogestion時,能推到什么程度。雖然兩者都是placer一起同時控制的,但為了理解方便,我們可以認為有先后順序。即先按max_density做placement,再按照max_utli來推散cell解congestion。
局部密度一定要合理,根據你的設計來定,沒有固定的值。
好了,理解了這兩個概念,控制起來就非常簡單了。
均勻密度
要讓std cell在設計里均勻擺放,很簡單,就是設置如下變量
place.coarse.auto_density_control=false
place.coarse.max_density=0
自動密度控制選項關掉且max_density=0,則placer就會均勻的擺放std cell。
聰明的讀者可能會問,你不是說placer還會看max_util這個參數嗎?如果這個參數設置了,那密度還會均勻嗎?
答案是看你有沒有用congestion driven的placement。
比如create_placement, 不加任何參數時,不是congestion driven,這時不看max_utli。create_placement -congestion,則是congestion driven,是會看max_utli的。
place_opt -from initial_place -to initial_place,不是congestion driven
place_opt -from final_place -to final_place,是congestion driven
對於絕大多數flow來說,都會跑final_place這步驟,所以設計不會完全均勻;會在局部有congestion的地方,密度會低些(它周圍會高點)。所以均勻密度也是指大體均勻,還是需要去解決congestion的。
來個均勻密度的例子。
而對於非均勻密度的控制,工具提供兩種方式:自動擋和手動擋。大多數設計用自動擋就足夠了。但不排除有些設計對密度要求特別嚴,這時候就需要手動擋了。
自動擋
place.coarse.auto_density_control = true
place.coarse.max_density=0 (default value)
place.coarse.congestion_driven_max_util=0.93(default value)
自動密度控制開關打開后,另外兩個app option用默認值,工具自動決定各個階段的max_density和max_util,具體的值如下:
Stage |
Max_density |
Max_util |
initial_place |
0.2 |
0.87 |
2nd pass incr place |
0.6 |
0.87 |
final_place |
0.7 |
0.90 |
clock_opt place |
0.8 |
0.93 |
細心的讀者會發現,自動擋並不是一個固定的值,而是在不同的階段有不同的值。並且隨着步驟的進行,density也越來越高。
手動擋
如果想自己控制密度,那也很簡單,設置如下變量即可:
place.coarse.auto_density_control=false
place.coarse.max_density = xxx
place.coarse.congestion_driven_max_util = xxx
手動擋設定后,每個步驟的placer都會遵從這個設置。如果你想不同步驟的placer的密度不一樣,你也可以做完上一個placement后,及時修改這兩個參數,那么后面的placer就會用新的參數。