在FPGA中我們寫的最大的邏輯是什么?相信對大部分朋友來說應(yīng)該是計數(shù)器,從最初板卡的測試時我們會閃爍LED,到復(fù)雜的AXI總線中產(chǎn)生地址或者last等信號,都會用到計數(shù)器,使用計數(shù)器那必然會用到進(jìn)位鏈。
可能很多剛開始接觸FPGA的同學(xué)沒聽過進(jìn)位鏈,也就是Carry Chain,我們這里再回顧一下。FPGA的三個主要資源為:
1. 最低邏輯單元
可配置邏輯單元(CLB)
存儲單元
運(yùn)算單元(DSP48)
2. 一流的I / O資源
3. 布線資源
其中,CLB在FPGA中最豐富,在7系列的FPGA中,一個CLB中有兩個Slice,Slice中包含4個LUT6、3個數(shù)據(jù)選擇器MUX,兩個獨立進(jìn)位鏈(Carry4,Ultrascale是CARRY8)和8個主軸。
首先,我們來看下Carry Chain的結(jié)構(gòu)原理,其輸入輸出接口如下:

其中,
CI是上一個CARRY4的進(jìn)位輸出,位寬為1;
CYINT是進(jìn)位的初始化值,位寬為1;
DI是數(shù)據(jù)的輸入(兩個加數(shù)的任意一個),位寬為4;
SI是兩個加數(shù)的異或,位寬為4;
O是加法結(jié)果輸出,位寬為4;
CO是進(jìn)位輸出,位寬為4;(為什么進(jìn)位輸出是4bit?后面有解釋)
Carry4的內(nèi)部結(jié)構(gòu)如下圖所示:

這里我們要先解釋一下FPGA中利用卡里鏈(Carry Chain)實現(xiàn)加法的原理,比如兩個加數(shù)分別為a = 4'b1000和b=4'b1100,其結(jié)果應(yīng)該是8+12=20。
a = 4'b1000; b = 4'b1100; S = a ^ b = 4'b0100; D = b = 4'b1100; //D取a也可以 CIN = 0; //沒有上一級的進(jìn)位輸入 CYINIT = 0; //初始值為0 // 下面為CARRY4的計算過程,具體的算法跟上圖中過程一樣 S0 = 0; //S的第0位 O0 = S0 ^ 0 = 0 ^ 0 = 0; CO0 = DI0 = 0; //上圖中的MUXCY,S0為0時,選擇1,也就是DI0,S0為1是選擇2 S1 = 0; O1 = S1 ^ CO0 = 0 ^ 0 = 0; CO1 = DI1 = 0; S2 = 1; O2 = S2 ^ CO1 = 0 ^ 1 = 1; CO2 = CO1 = 0; S3 = 0; O3 = S3 ^ CO2 = 0 ^ 0 = 0; CO3 = DI3 = 1;
加法最終的輸出結(jié)果為:{CO3,O3,O2,O1,O0} = 5'b10100 =20。進(jìn)位輸出在CARRY4的內(nèi)部也使用到了,因此有4個位的進(jìn)位輸出CO,但輸出給下一級的只是CO [3]。
再來看完下面的例子就更清晰了。Example的代碼如下:
module top(
input clk,
input [7:0] din_a,
input [7:0] din_b,
output reg[7:0] dout
);
always @ ( posedge clk )
begin
dout <= din_a + din_b;
end
endmodule
綜合之后的電路如下:

在本程序中,加數(shù)為din_a和din_b,圖中
1 表示CARRY4的進(jìn)位輸出到下一級的進(jìn)入輸入;
2 表示輸入的一個加數(shù)din_a(換成din_b也是可以的);
3 表示第二級輸入的DI端口,因為第二級CARRY是通過第一級的進(jìn)位輸出進(jìn)行累加,因此該接口為0;
4 表示輸入兩個加數(shù)的異或結(jié)果。
可以拋光,當(dāng)進(jìn)行兩個兩個bit的數(shù)據(jù)進(jìn)行加法操作時,會使用兩個CARRY4級聯(lián),那如果是對48位的數(shù)據(jù)進(jìn)行相加,那就會用到12個的CARRY4的級聯(lián),這樣(此處需要注意的是,在Vivado的設(shè)置下,如果進(jìn)行的是12bit以下的數(shù)據(jù)加1'b1的操作,那么Vivado綜合的結(jié)果并不會使用CARYY4,或者使用LUT來實現(xiàn)加法器)。
那如何解決這種問題呢?我們可以把加法操作進(jìn)行拆解,比如拆解成3個16bit的計數(shù)器,那這樣就會只有4個CARRY4的級聯(lián),時序情況就好了很多。
對比程序如下:
module top(
input clk,
input [47:0] din1,
input [47:0] din2,
output reg[47:0] dout1,
output [47:0] dout2
);
always @ ( posedge clk )
begin
dout1 <= din1 + 1'b1;
end
genvar i;
generate
for(i = 0;i < 3;i=i+1) begin:LOOP
wire carry_co;
reg [15:0] carry_o=0;
wire ci;
if(i==0) begin
always @ ( posedge clk )
begin
carry_o <= din2[i*16+:16] + 1'b1;
end
end //if
else begin
always @ (posedge clk) begin
if(LOOP[i-1].carry_co == 1)
carry_o <= carry_o + 1'b1;
end
end //else
assign LOOP[i].carry_co = (LOOP[i].carry_o==16'hffff)?1'b1:1'b0;
assign dout2[i*16+:16] = LOOP[i].carry_o;
end //for
endgenerate
endmodule
:綜合后的schematic后可以發(fā)現(xiàn),在dout2的輸出中,每4個CARRY4后都會有一級的觸發(fā),這樣時序就會好很多,但造成的代價是LUT會增加。
編輯:hfy
-
FPGA
+關(guān)注
關(guān)注
1650文章
22217瀏覽量
628055 -
計數(shù)器
+關(guān)注
關(guān)注
32文章
2303瀏覽量
97332
發(fā)布評論請先 登錄
亞馬遜 SP-API 深度開發(fā):關(guān)鍵字搜索接口的購物意圖挖掘與合規(guī)競品分析
微機(jī)消諧器是什么?技術(shù)原理深度解析
聚徽深度解析國內(nèi)工控平板電腦的工業(yè)級抗干擾技術(shù)如何實現(xiàn)?
GPU架構(gòu)深度解析
邊緣AI MPU深度盤點:品牌、型號與技術(shù)特性全解析
解鎖未來汽車電子技術(shù):軟件定義車輛與區(qū)域架構(gòu)深度解析
FPGA時序約束之設(shè)置時鐘組
風(fēng)華電容命名方法深度解析
深度解析Linux中的DNS服務(wù)
國產(chǎn)自研新標(biāo)桿:龍芯GM9-3003主板深度解析
有沒有對appsfpga_io模塊輸入端功能時序的控制的資料?
玻璃通孔(TGV)技術(shù)深度解析
FPGA驅(qū)動AD芯片之實現(xiàn)與芯片通信

深度解析FPGA時序的進(jìn)位鏈
評論