在RTL編碼中考慮時延
分if-else,case 的各種情況分開討論,主要目的是將分支支路中 晚到的信號放到離輸出最近的一級中.
對多if語句:
代碼
為下面代碼為多if語句
module mult_if (a,b,c,d,sel,z)
input a,b,c,d;
input[3:0]sel;
output Z;
reg Z;
always@(*) begin
z=1'b0;
if (sel[o])z=a;
if (sel[1])z=b;
if (sel[2])z =c;
if (sel[3])z =d;
end
endmodule
對應(yīng)的硬件結(jié)構(gòu)為有優(yōu)先級的級聯(lián)多路選擇器
如果有個別信號到來的比較晚。應(yīng)該要盡可能把這個延遲較大的分支單獨拿出來,放到離出口最近的選擇器中。假設(shè)b信號的延遲較大,可以在不影響邏輯功能的前提下,將b往后拉,如:
always@(*) begin
z=1'b0;
if (sel[o])z=a;
if (sel[2])z =c;
if (sel[3])z =d;
// if (sel[1])z=b;
if(sel[1]& ~(sel[2]|sel[3]))
z = b_is_late;
end
此時如果僅將if (sel[1])z=b;直接放下會使原來的邏輯功能改變。修改后的電路:
對單if語句
代碼:
module single_if_late (A,C,CTRL_is_late_arriving,Z):
input [6:1]A:
input [5:1]C;
input CTRL_is_late_arriving:
output Z;
reg Z;
always@(A or C or CTRL_is_late_arriving)begin
if(C[1]==1'b1)
Z=A[1];
else if (C[2]==1'b0)
Z=A[2];
else if (C[3]==1'b1)
Z=A[3];
else if (C[4]==1'b1&CTRL_is_late_arriving==1'b0)
Z=A[4];
else if (C[5]==1'b0)
Z=A[5];
else
Z=A[6];
end
endmodule
其中 CTRL_is_late_arriving 到來延遲較大,此時就會把這個延遲較大的分支單獨拿出來,放到離出口最近的選擇器中:
具體的修改代碼是這樣的,先將原來的if打散,再在后面出口做一個選擇,單獨處理A[4]:
module single_if_improved (A,C,CTRL_is_late_arriving,Z);
input [6:1]A;
input [5:1]C;
input CTRL_is_late_arriving;
output Z;
reg Z,Z1;
wire Z2,prev_cond;
always@(A or C)begin
if(C[1]==1'b1)
Z1=A[1];
else if (C[2]==1'b0)
Z1=A[2];
else if (C[3]==1'b1)
Z1=A[3];
else if (C[5]==1'b0)
Z1=A[5];
// removed the branch with the late_arriving control signal
// else if (C[4]==1'b1&CTRL_is_late_arriving==1'b0)
else
Z1=A[6];
end
assign Z2=A[4];
assign prev_cond=(C[1]=1'b1)l(C[2]==1'b0)||(C[3]==1'b1);
always @ (C or prev_cond or CTRL_is_late_arriving or Z1 or Z2) begin
if((C[4]==1'b1)&&(CTRL_is_late_arriving==1'b0))
if(prev_cond) Z=Z1:
else Z=Z2;
else Z=Z1 ;
end
endmodule
case和if嵌套
module case_in_if_01(A,DATA_is_late_arriving,C,sel,Z);
input[8:1] A;
input DATA_is_late_arriving;
input [2:0] sel;
input [5:!] C;
output Z;
reg Z;
always @ (sel or C or A or DATA_is_late_arriving) begin
if (C[1])
Z=A[5];
else if (C[2]==1'b0)
Z=A[4];
else if (C[3])
Z=A[1]:
else if (C[4])
case (sel)
3'b010:Z=A[8];
3'b011:Z=DATA_is_late_arriving;
3'b101:Z=A[7]:
3'b11O:Z=A[6];
default:Z=A[2];
endcse
else if (C[5]==1'b0)
Z=A[2];
else Z=A[3];
end
endmodule
假設(shè)case中有一個支路到達比較晚,其電路結(jié)構(gòu)為:
此時與單if相似,將這條通路往外提:
代碼與單if-else結(jié)構(gòu)的相似,去掉了case分支,單獨判斷這個分支:
module case_in_if_01(A,DATA_is_late_arriving,C,sel,Z);
input[8:1] A;
input DATA_is_late_arriving;
input [2:0] sel;
input [5:!] C;
output Z;
reg Z,Z1;
reg FIRST_IF;
always @ (sel or C or A or DATA_is_late_arriving) begin
if (C[1])
Z1=A[5];
else if (C[2]==1'b0)
Z1=A[4];
else if (C[3])
1Z=A[1]:
else if (C[4])
case (sel)
3'b010:Z1=A[8];
// 3'b011:Z=DATA_is_late_arriving;
3'b101:Z1=A[7]:
3'b11O:Z1=A[6];
default:Z1=A[2];
endcse
else if (C[5]==1'b0)
Z1=A[2];
else Z=A[3];
FIRST_IF=(C[1]==1'b1) || (C[2]==1'b0) ||(C[0]==1'b1);
if(!FIRST_IF && C[4] &&(sel==3'b011))
Z=DATA_is_late_arriving;
else Z=Z1;
end
endmodule
“先加后選”和“先選后加”
注意“先加后選”和“先選后加”兩種方法對數(shù)據(jù)通道延遲的影響,對以下代碼:
module BEFORE(ADRESS, PTR1,PTR2, B,CONTROL,COUNT);
input [7:O] PTR1, PTR2;
input CONTROL: //CONTROL is late arriving
output [15:0] COUNT:
parameter [7:0] BASE=8'b1000000;
wire [7:O] PRT,OFFSET;
wire [15:0] ADDR;
assign PTR = (CONTROL ==1'b1)?PTR1:PTR2;
assign OFFSET=BASE-PTR:
assign ADDR = ADRESS-{8'h00-OFFSET};
assign COUNT=ADDR+B;
endmodule
這里是先選后加, 假設(shè)控制信號到達比較晚 ,則需要改為先加后選:
代碼修改如下
assign OFFSET1 = BASE-PTR1;//could be T(BASE,PTR)
assign OFFSET2 = BASE-PTR2; //could be f(BASE,PTR)
assign ADDR1 = ADRESS-{8'h00-OFFSET1);
assign ADDR2 = ADRESS-{8'h00-OFFSET2};
assign COUNT1=ADDR1+B;
assign COUNT2=ADDR2+B;
assign COUNT=(CONTROL==1'b1)?COUNT1:COUNT2;
復制數(shù)據(jù)路徑將CONTROL信號放到最后
調(diào)整計算順序
在下例中,包含一個加法器和比較器:
module cond_oper(A,B,C,D,Z):
parameter N=8;
input [N-1:O] A,B,C,D; //A is late arriving
output [N-1:0] Z;
reg [N-1:O] Z;
always@(A,B,C,D) begin
if(A+B 24)Z<=C;
else Z<=D;
end
endmodule
假設(shè)A信號到來較晚,此時調(diào)整A的計算路徑,原來的計算順序為:
通過調(diào)整代碼:
always@(A,B,C,D) begin
if(A 24-B)Z<=C;
else Z<=D;
end
A將少過一個減法器,此時電路結(jié)構(gòu)變?yōu)?
在RTL編碼中考慮面積
- 隨著芯片工藝的進步和生產(chǎn)成本的降低,面積顯得沒有時序問題重要。
- 減少設(shè)計面積可以
- 成本降低、功耗降低,
- 特別是對于FPGA的設(shè)計,直接決定FPGA的選型。
- 一般綜合過程中可以對面積進行優(yōu)化,但在RTL編碼中如果注意節(jié)約設(shè)計面積,往往可以達到事半功倍的效果。
- 減少設(shè)計的面積
- 估計設(shè)計使用資源的數(shù)量
- 知道設(shè)計中那些部分占用了較大的面積(觸發(fā)器,加法器,乘法器)
- 觸發(fā)器的資源估計
- 觸發(fā)器的數(shù)量:觸發(fā)器的數(shù)量由功能決定,很難減少
- 觸發(fā)器的面積:比較好估計
操作符優(yōu)化
所以優(yōu)化目標大頭放在 組合邏輯 中,其對應(yīng)著RTL代碼中的各種操作符 RTL代碼屮的一個“+“可能對應(yīng)著一個64位的加法器。以下這些操作符都可能產(chǎn)生較大的組合邏輯,使用時應(yīng)加以重視,如“+”、“-”、“×”、“/”以及 條件語句的比較運算 。對于這些操作,首先應(yīng)該 判斷其必要性 ,是否能用更簡單的運算代替。
比如考慮
if(A< 32)
可以將其修改為
if(A[5]==1'b1)
通過這種方式即可節(jié)省一個6bit的比較器
此處例子中,需要考慮A的自身位寬,未必適合于所有設(shè)計,對所有定值比較都可以這樣考慮
資源共享
如果,必須使用復雜的運算符,則應(yīng)考慮是否可以 資源共享 。盡管電路邏輯綜合工具也會在綜合的過程中采用資源共享的方法進行優(yōu)化,但是,綜合器的策略是有限的,因此在編寫RTL的時候,應(yīng)該盡量考慮共享,而不是把這項工作完全留給綜合工具。
比如對以下代碼:
If(y1 >a+b+q)
statement1;
If(y2 >a+b+r)
statement2;
If(y3 >a+b+s)
可以修改為:
sum<=a+b;
If(yl >sum+q)
statement1;
If(y2 >sum+r)
statement2;
If(y3 >sum+s)
則可以減少兩個不必要的加法器
多比特
多比特的信號也往往會占用較大的資源,因為使用這些信號的操作都是對所有的比特進行的,相當于成倍使用資源,因此,對這類信號的操作也應(yīng)重視。
應(yīng)該看一看這個信號的所有比特是否都需要參與操作,如果不是,則可以只對需要的部分比特進行操作。
假設(shè):
訪問—RAM的地址有8比特,而寫入操作時從0開始,每隔32個地址寫入一個值,地址的產(chǎn)生可以有兩種寫法。
addr <= addr + 32;
和
addr[7:5] <= addr[7:5] + 1;
addr[4:0] <= addr[4:0] + 0;
邏輯優(yōu)化
針對不同的設(shè)計,還有可能有各種各樣的優(yōu)化和改進的方法,但是,歸結(jié)到一點,就是編寫代碼時,應(yīng)對操作符有足夠的重視,對有可能簡化的地方盡量簡化。 邏輯簡化往往在減少面積的同時也減少了延遲 ,因此,是值得花費一些時間的。
在RTL編碼中考慮功耗
考慮電路割點的功耗:
在RTL設(shè)計中無法改變負載電容和 工作電壓 ,所以在RTL級主要考慮盡量降低電路的翻轉(zhuǎn)頻率
主要措施包括如下:
- 門控時鐘,門控時鐘是電路設(shè)計最常用也是最有效的方法,在邏輯綜合階段可以讓綜合工具自行插入。
- 增加使能信號,使得部分電路只有在需要工作時才工作;
- 對芯片各個模塊進行控制,在需要工作時才工作;
- 除了有用信號和時鐘的翻轉(zhuǎn)會消耗功耗,組合邏輯產(chǎn)生的毛刺也會大量消耗功耗。但是,毛刺在設(shè)計中無法避免,因此,只有盡呈減少毛刺在電路中的傳播,才可以減少功耗。即在設(shè)計中,盡量把產(chǎn)生毛刺的電路放在傳播路徑的最后。另外,可以使用一些減少毛刺的技術(shù)。
- 對于有限狀態(tài)機,可以通過低功耗編碼來減少電路的翻轉(zhuǎn)。比如對4比特狀態(tài)編碼:
更改狀態(tài)編碼后:
總的來說,使用這些技術(shù)時,應(yīng)首先
- 考慮全局的功耗控制
- 在RTL編碼中,注意消耗功率較多的電路,如狀態(tài)機、譯碼器、多路選擇器等。
- 在綜合中,使用門控時鐘和其他減少功耗的優(yōu)化技術(shù)。
- 這里要注意下門控時鐘和增加使能控制的區(qū)別。增加使能僅僅是使得電路的信號不在翻轉(zhuǎn),但是時鐘每個周期還會繼續(xù)翻轉(zhuǎn)。而門控時鐘則是直接關(guān)掉時鐘,這種方法效果更好。
在RTL編碼中考慮布線問題
布線(routing)是芯片設(shè)計中 最后的流程 ,其功能是根據(jù)門級網(wǎng)表的描述實現(xiàn)各個單元的連接
布局(placement)是芯片設(shè)計中 最關(guān)鍵的因素 ,但即使使用最好的布局工具,還是可能出現(xiàn)無法布通的情況
-> 如果可以在RTL編碼階段考慮代碼可能對布線產(chǎn)生的影響,就可能避免最后出現(xiàn)無法布通的情況。
布線階段,通常熱點是一個影響布線質(zhì)量的問題。
熱點是指設(shè)計的功能需要在一個面積內(nèi)占用大量的布線資源:
熱點產(chǎn)生原因:RTL編碼時使用了特定的結(jié)構(gòu),如很大的MUX:
- 這種結(jié)構(gòu)產(chǎn)生的熱點,在綜合的時候,導致的延遲是看不出來 只有到了布線階段才能給看到它的負面影響。因此,我們在RTL階段應(yīng)該重視這種電路,及早發(fā)現(xiàn)可能在布線階段產(chǎn)生的問題。
- 如果設(shè)計的功能中確實需要采用大的mux,可以通過其他方式改變他的結(jié)構(gòu)。其基本的思路是將一個大的mux分解為多級較小的mux。
-
FPGA設(shè)計
+關(guān)注
關(guān)注
9文章
428瀏覽量
26518 -
比較器
+關(guān)注
關(guān)注
14文章
1651瀏覽量
107221 -
RTL
+關(guān)注
關(guān)注
1文章
385瀏覽量
59797 -
觸發(fā)器
+關(guān)注
關(guān)注
14文章
2000瀏覽量
61159 -
多路選擇器
+關(guān)注
關(guān)注
1文章
22瀏覽量
6529
發(fā)布評論請先 登錄
相關(guān)推薦
評論