本章討論關(guān)于數(shù)字設(shè)計(jì)中的“面積”問題,并提出若干在FPGA設(shè)計(jì)中優(yōu)化面積的方法曹鸠。
我們將通過選擇不同拓?fù)浣Y(jié)構(gòu)來減少面積消耗,這與我們熟知的通過綜合、布線工具的約束來優(yōu)化電路面積不同散怖,約束方式是針對不同器件特性來降低邏輯門與模塊的數(shù)量,而拓?fù)浣Y(jié)構(gòu)是在更高層面上來解決這個(gè)問題肄渗,適用于所有器件镇眷。
優(yōu)化面積通常是最大限度地重用邏輯資源,這會以犧牲數(shù)據(jù)吞吐量為代價(jià)翎嫡。
本章將具體針對下列問題進(jìn)行討論:
1)收起流水線以在不同計(jì)算階段重用邏輯資源偏灿。
2)在無現(xiàn)有的遞歸、循環(huán)等算法時(shí)钝的,通過控制邏輯來實(shí)現(xiàn)邏輯復(fù)用。
3)在不同功能操作之間共享邏輯資源铆遭。
4)復(fù)位對面積優(yōu)化的影響:
- 缺少reset功能的影響硝桩;
- 缺少set功能的影響;
- 缺少異步reset功能的影響枚荣;
- RAM reset的影響碗脊;
- 使用set/reset對邏輯資源進(jìn)行優(yōu)化。
2.1 收起流水線
顧名思義橄妆,本小節(jié)與上一章的流水線操作正相反衙伶,通過復(fù)用流水線中的重復(fù)邏輯,實(shí)現(xiàn)面積的降低害碾。
定點(diǎn)數(shù)乘法是常見的可以寫為流水線的設(shè)計(jì)模塊矢劲,我們可以通過添加移位和加法器來“收起”它,乘法器被優(yōu)化為受B位數(shù)控制的A的移位累加算法慌随。
優(yōu)化前代碼:
module mult8(
output [7:0] product,
input [7:0] A,
input [7:0] B,
input clk);
reg [15:0] prod16;
assign product = prod16[15:8];
always @(posedge clk)
prod16 <= A * B;
endmodule
優(yōu)化后代碼:
module mult8(
output done,
output reg [7:0] product,
input [7:0] A,
input [7:0] B,
input clk,
input start);
reg [4:0] multcounter; // counter for number of shift/adds
reg [7:0] shiftB; // shift register for B
reg [7:0] shiftA; // shift register for A
wire adden; // enable addition
assign adden = shiftB[7] & !done;
assign done = multcounter[3];
always @(posedge clk) begin
// increment multiply counter for shift/add ops
if(start) multcounter <= 0;
else if(!done) multcounter <= multcounter + 1;
// shift register for B
if(start) shiftB <= B;
else shiftB[7:0] <= {shiftB[6:0], 1’b0};
// shift register for A
if(start) shiftA <= A;
else shiftA[7:0] <= {shiftA[7], shiftA[7:1]};
// calculate multiplication
if(start) product <= 0;
else if(adden) product <= product + shiftA;
end
endmodule
2.2 基于控制信號的邏輯復(fù)用
當(dāng)共享邏輯明顯大于所需的控制邏輯時(shí)芬沉,可以通過添加控制邏輯的方式實(shí)現(xiàn)共享邏輯復(fù)用。
多數(shù)情況下阁猜,邏輯的復(fù)用并不想2.1節(jié)那么簡單丸逸,需要創(chuàng)建一些控制邏輯,比如狀態(tài)機(jī)剃袍,來更好的實(shí)現(xiàn)黄刚。以低通FIR濾波器的實(shí)現(xiàn)為例。
實(shí)現(xiàn)代碼:
module lowpassfir(
output reg [7:0] filtout,
output reg done,
input clk,
input [7:0] datain, // X[0]
input datavalid, // X[0] is valid
input [7:0] coeffA, coeffB; coeffC); // coeffs for low pass filter
// define input/output samples
reg [7:0] X0, X1, X2;
reg multdonedelay;
reg multstart; // signal to multiplier to begin computation
reg [7:0] multdat;
reg [7:0] multcoeff; // the registers that are multiplied together
reg [2:0] state; // holds state for sequencing through mults
reg [7:0] accum; // accumulates multiplier products
reg clearaccum; // sets accum to zero
reg [7:0] accumsum;
wire multdone; // multiplier has completed
wire [7:0] multout; // multiplier product
// shift-add multiplier for sample-coeff mults
mult8?8 mult8?8(.clk(clk),
.dat1(multdat),
.dat2(multcoeff),
.start(multstart),
.done(multdone),
.multout(multout));
always @(posedge clk) begin
multdonedelay <= multdone;
// accumulates sample-coeff products
accumsum <= accum + multout[7:0];
// clearing and loading accumulator
if(clearaccum) accum <= 0;
else if(multdonedelay) accum <= accumsum;
// do not process state machine if multiply is not done
case(state)
0: begin
// idle state
if(datavalid) begin
// if a new sample has arrived
// shift samples
X0 <= datain;
X1 <= X0;
X2 <= X1;
multdat <= datain;
multcoeff <= coeffA;
multstart <= 1;
clearaccum <= 1; // clear accum
state <= 1;
end
else begin
multstart <= 0;
clearaccum <= 0;
done <= 0;
end
end
1: begin
if(multdonedelay) begin
// A*X[0] is done, load B*X[1]
multdat <= X1;
multcoeff <= coeffB;
multstart <= 1;
state <= 2;
end
else begin
multstart <= 0;
clearaccum <= 0;
done <= 0;
end
end
2: begin
if(multdonedelay) begin
// B*X[1] is done, load C*X[2]
multdat <= X2;
multcoeff <= coeffC;
multstart <= 1;
state <= 3;
end
else begin
multstart <= 0;
clearaccum <= 0;
done <= 0;
end
end
3: begin
if(multdonedelay) begin
// C*X[2] is done, load output
filtout <= accumsum;
done <= 1;
state <= 0;
end
else begin
multstart <= 0;
clearaccum <= 0;
done <= 0;
end
end
default
state <= 0;
endcase
end
endmodule
2.3 邏輯共享
對于以面積為主要要求的緊湊型設(shè)計(jì)民效,應(yīng)在不同模塊中搜索相似的邏輯憔维,這些邏輯可以被帶到全局層面被多個(gè)模塊共享涛救。
下圖中模塊A和B是兩個(gè)完全獨(dú)立的邏輯。A是一個(gè)計(jì)數(shù)分頻器埋同,8-bit計(jì)數(shù)器自動計(jì)數(shù)和歸零州叠;B是一個(gè)PWM生成器,11-bit計(jì)數(shù)器在固定值歸零凶赁。通過邏輯共享咧栗,可以有效節(jié)省面積。
優(yōu)化前:
優(yōu)化后:
2.4 復(fù)位對面積的影響
不恰當(dāng)?shù)膹?fù)位方式可能造成大量額外的邏輯資源浪費(fèi)虱肄,不利于面積優(yōu)化致板。
2.4.1 reset對資源的影響
FPGA內(nèi)部有許多特定的built-in資源,例如移位寄存器咏窿,可以有效節(jié)省LUT與FF的使用斟或,但是在非必要的reset使用情況下,綜合工具就會放棄使用built-in資源集嵌,造成資源浪費(fèi)萝挤。如下兩種設(shè)計(jì)會導(dǎo)致完全不同的結(jié)果:
生成的電路區(qū)別如下:
2.4.2 set對資源的影響
與移位寄存器不同,大多數(shù)FPGA的內(nèi)置DSP資源包含reset功能根欧,但如何非要使用set怜珍,則會在輸出端的產(chǎn)生多余邏輯。
2.4.3 異步reset對資源的影響
許多新出的高性能FPGA內(nèi)置資源還有同步reset功能凤粗,如DSP酥泛,但如果非要使用異步reset,也會浪費(fèi)大量邏輯資源嫌拣。
2.4.4 reset RAM
去復(fù)位RAM通常是一種糟糕的設(shè)計(jì)柔袁,尤其是使用異步復(fù)位。
通常情況下异逐,我們希望使用BRAM資源來完成FPGA內(nèi)部存儲功能捶索,節(jié)省FF資源,但不恰當(dāng)?shù)膹?fù)位(異步復(fù)位)會適得其反应役。
2.4.5 利用FF的set/reset因腳來優(yōu)化設(shè)計(jì)
可以發(fā)現(xiàn)情组,F(xiàn)F的set可以完成外部或門功能;reset則與外部的與門功能等效箩祥。如下圖所示:
利用這個(gè)原理可以使一些看似復(fù)雜的邏輯變得意外簡單: