Fanout,即扇出,指模塊直接調用的下級模塊的個數,如果這個數值過大的話,在FPGA直接表現為net delay較大,不利於時序收斂。因此,在寫代碼時應儘量避免高扇出的情況。但是,在某些特殊情況下,受到整體結構設計的需要或者無法修改代碼的限制,則需要通過其它優化手段解決高扇出帶來的問題。以下就介紹三個這樣的方法:
首先來看下面這個實例,如圖1所示為轉置型FIR濾波器中的關鍵路徑時序報告,在DSP in FPGA的FIR專題中有介紹轉置型結構FIR濾波器輸入數據的扇出較大,在下圖中所示為11,因此net delay高達1.231ns,輸入數據驅動了11個DSP48E1。
在沒有優化情況下,該設計的fmax:206.016MHz
1. 寄存器複製
寄存器複製是解決高扇出問題最常用的方法之一,通過複製幾個相同的寄存器來分擔由原先一個寄存器驅動所有模塊的任務,繼而達到減小扇出的目的。通過簡單修改代碼,如圖所示,複製了4個寄存器:din_d0、din_d1、din_d2、din_d3,din_d、din_d0、din_d1、din_d2分別驅動2個DSP48E1,din_d3驅動3個DSP48E1。其中在代碼中為防止綜合器優化相同寄存器,在對應信號上加入了(* EQUIVALENT_REGISTER_REMOVAL="NO" *)屬性避免被優化。
綜合實現後得到,該數據路徑上輸入數據fanout減為2,對應net delay也減小到了0.57ns。得到設計如圖5所示,與期望的相同,複製了4個寄存器來分擔fanout。經過寄存器優化後得到fmax:252.143MHz
2. max_fanout屬性
在代碼中可以設置信號屬性,將對應信號的max_fanout屬性設置成一個合理的值,當實際的設計中該信號的fanout超過了這個值,綜合器就會自動對該信號採用優化手段,常用的手段其實就是寄存器複製。屬性設置如下代碼所示:
(* max_fanout = "3" *)reg signed [15:0] din_d;
將din_d信號的max_fanout屬性設置成3,經過綜合實現後,得到fanout只有2,相應的net delay也只有0.61ns,自動優化效果還不錯。其中din_d_12_1、din_d_12_2、din_d_12_3是綜合器優化後自動添加,即實現了寄存器複製功能。經過設置max_fanout屬性優化後得到fmax:257.135MHz
vivado中的max_fanout
打算降低扇出的網絡必須是reg驅動。因為降低扇出的原理就是reg驅動超過N(設置參數)條網絡的時候,就複製一個同樣的reg驅動其他N條網絡,如果複製2個還不夠就一直複製到足夠為止,見圖1。
-flatten_hierarchy不能設置為none。圖形界面設置位置見圖2。
如果需要優化的信號在IP核內部那麼在布局完成後使用下面的命令phys_opt_design -force_replication_on_nets [get_nets net_name]來保證IP核取消對內部網絡的保護,能夠正常複製高扇出網絡。
圖1.寄存器複製示意圖
圖2. flatten_hierarchy設置位置
max_fanout的使用形式
verilog綜合屬性設置:(*MAX_FANOUT = 50 *) reg test;
這裡的綜合屬性必須設置在要降低扇出的寄存器前面,否則一定不會按照設計者意圖綜合。這種方法缺點是不能作用於IP核內部的某個信號。
max_fanout的參數意義
(*MAX_FANOUT = 50 *) reg test;裡面的參數就只有一個——50,網絡扇出超過50就會複製一個,保證每個複製的寄存器下面的扇出都不超過此參數。xdc約束也一樣,不再贅述。
注意,圖1的綜合設置裡面有-fanout_limit這個參數,並且默認是10000。這裡是約束全局扇出的,但是max_fanout命令的優先級會高於這裡的設置參數。所以編譯器會優先按照你的綜合屬性或者XDC約束來進行優化。
3. BUFG
通常BUFG是用於全局時鐘的資源,可以解決信號因為高扇出產生的問題。但是其一般用於時鐘或者復位之類扇出超級大的信號,此類信號涉及的邏輯遍布整個晶片,而BUFG可以從全局的角度優化布線。而且一塊FPGA晶片中BUFG資源也有限,在7k325tffg900上也僅有32個,如果用於普通信號的高扇出優化也不大現實。因此,在時鐘上使用BUFG是必須的,但是如果設計中遇到某些復位信號因高扇出產生的時序問題時,可以在此信號上使用BUFG來優化。