隨着FPGA的廣泛應用,所含的資源也越來越豐富,從基本的邏輯單元、DSP資源和RAM塊,甚至CPU硬核都能集成在一塊芯片中。在做FPGA設計時,如果針對FPGA中資源進行HDL代碼編寫,對設計的資源利用和時序都有益。下面主要講解一下如何巧用FPGA中資源:
1. 移位寄存器
FPGA中的移位寄存器使用在前面的博文中有所論述,Xilinx FPGA中的LUT可以作為SRL使用,主要可參考此博文《Xilinx 7系列FPGA使用之CLB探索》,在此想補充論述一下SRL的延時,首先看一下如下代碼,實現了一個19級的移位寄存器。
1 module srl_test( 2 input clk, 3 input rst, 4 input din, 5 output dout 6 ); 7 reg din_d; 8 always@(posedge clk) begin 9 if(rst) 10 din_d<=1'b0; 11 else 12 din_d<=din; 13 end 14 reg [18:0] d_sh; 15 always@(posedge clk) begin 16 d_sh<={d_sh[17:0],din_d}; 17 end 18 assign dout=d_sh[18]; 19 endmodule
綜合得到結構如圖1所示,其中輸入din由FF(din_d)寄存,隨后的移位操作由一個SRL32E和FF組成,SRL中A=“10001”,實現了18級移位,因此SRL32E和FF的組合也能實現19級的移位,但是代碼中dout是直接assign組合輸出,並沒有輸出寄存,為什么綜合得到結構是FF寄存輸出,以下分析一下原因。
圖1
在FPGA內部時序分析一般以register-to-register為基礎模型,首先來看一下圖1所示路徑,為srl32-to-ff的路徑,其數據路徑延時報告如圖3所示,延時Prop_srlc32e_CLK_Q表示充當移位寄存器的LUT的clk_to_out延時,達到0.97ns,相比於FF的clk_to_out延時(0.24ns)相差甚大,如果沒有最后一級的FF寄存,則輸出為純組合邏輯輸出,這段路徑的延時將會被引入到下一級模塊的時序分析中,下一級模塊的輸入如果也沒有輸入寄存,則這一段數據路徑的延時將會很大,不利於時序收斂;而加入FF寄存,直接切斷了數據路徑,在這段register-to-register模型中,數據路徑延時僅有LUT的clk_to_out延時0.97ns,在一般情況下都能達到時序收斂。因此綜合器自動將最后一級移位以FF形式實現,在代碼功能不變的前提下,優化了時序;而且這個FF是同一個Slice中的FF,並不會消耗多余的Slice,由於SRL32E和FF處於同一個Slice,它們之間的走線屬於內部走線,因此延時將會很小,由延時報告中SRL32E到FF(d_sh_18)的走線延時為0ns可以驗證。
圖2
圖3
移位寄存器綜合得到的SRL+FF組合結構體現了綜合器的智能,但是此結構僅限於靜態地址的移位寄存器實現,動態地址的移位寄存器的Q端是直接組合邏輯輸出的,需要人為地在代碼中添加FF寄存。
2. Register大搜索
在FPGA中的register資源可以說是無處不在,幾乎每個角落都有它的身影,Xilinx 7系列FPGA中,每個Slice中有8個register,除此之外,在DSP48E1、Block RAM蘊藏了很多register,其中在1個DSP48E1中多達上百個。
首先講解一下如何使用DSP48E1中豐富的register資源,如下兩段代碼:
綜合得到資源利用和性能對比如下表所示,結構如圖4所示,其中Code1和Code2都使用了1個DSP48E1資源;Slice Resigter,Code2使用比Code1多了32個,用於輸入2*8-bit和輸出16-bit信號的寄存,而Code1沒有使用額外的Slice的register資源,是因為這些register是在DSP48E1中實現了;並且Code2的Fmax相比於Code1也較差,是因為Code2中結構使用了額外的Slice Resigter,連接乘法器需要外部走線,增加了數據路徑延時,而Code1中register與乘法器之間是內部走線,延時可以忽略,因此時序上較好。
|
Code 1 |
Code 2 |
Slice Registers |
0 |
32 |
DSP48E1s |
1 |
1 |
Maximum frequency |
360.750MHz |
253.678MHz |
圖4
而比較Code1和Code2的差異,就是復位,Code1中寄存采用的是同步復位,而Code2采用異步復位,因為DSP28E1中的register只支持同步復位,如果采用異步復位,綜合器就不會采用DSP48E1中的register實現,而是使用額外的Slice Resgiter,因此建議在使用DSP資源時采用同步復位,這樣可以充分使用其中的register資源,對於FPGA資源耗用和性能上都有益。
而使用Block RAM中register資源與DSP類似,復位方式也需要是同步綜合器才能識別。
另外還有一處的register可供利用,那就是IOB,通過設置synthesis和map選項,可以將輸入和輸出的register映射到IOB中的register實現,如圖5為選項設置,在synthesis選項中,將-iob設置為Auto或者Yes,在Map選項中,將-pr設置為For Inputs and Outputs。
圖5
對上述Code2進行綜合實現,得到報告如下,報告顯示輸入和輸出register並沒有使用額外的Slice Resigter實現,而是映射到了IOB Flip Flops中,如圖6所示為IOB中的register。
Slice Logic Utilization:
Number of Slice Registers: 0 out of 407,600 0%
Number of Slice LUTs: 0 out of 203,800 0%
IO Utilization:
Number of bonded IOBs: 34 out of 500 6%
IOB Flip Flops: 32
圖6
綜上,在做FPGA設計時,可以充分利用DSP、Block RAM、IOB等資源中的register,不但節省資源而且可以在一定程度上提高性能。