在RTL編碼中考慮時(shí)延
分if-else,case 的各種情況分開(kāi)討論,主要目的是將分支支路中 晚到的信號(hào)放到離輸出最近的一級(jí)中.
對(duì)多if語(yǔ)句:
代碼
為下面代碼為多if語(yǔ)句
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
對(duì)應(yīng)的硬件結(jié)構(gòu)為有優(yōu)先級(jí)的級(jí)聯(lián)多路選擇器
如果有個(gè)別信號(hào)到來(lái)的比較晚。應(yīng)該要盡可能把這個(gè)延遲較大的分支單獨(dú)拿出來(lái),放到離出口最近的選擇器中。假設(shè)b信號(hào)的延遲較大,可以在不影響邏輯功能的前提下,將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
此時(shí)如果僅將if (sel[1])z=b;直接放下會(huì)使原來(lái)的邏輯功能改變。修改后的電路:
對(duì)單if語(yǔ)句
代碼:
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 到來(lái)延遲較大,此時(shí)就會(huì)把這個(gè)延遲較大的分支單獨(dú)拿出來(lái),放到離出口最近的選擇器中:
具體的修改代碼是這樣的,先將原來(lái)的if打散,再在后面出口做一個(gè)選擇,單獨(dú)處理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中有一個(gè)支路到達(dá)比較晚,其電路結(jié)構(gòu)為:
此時(shí)與單if相似,將這條通路往外提:
代碼與單if-else結(jié)構(gòu)的相似,去掉了case分支,單獨(dú)判斷這個(gè)分支:
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
“先加后選”和“先選后加”
注意“先加后選”和“先選后加”兩種方法對(duì)數(shù)據(jù)通道延遲的影響,對(duì)以下代碼:
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è)控制信號(hào)到達(dá)比較晚 ,則需要改為先加后選:
代碼修改如下
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;
復(fù)制數(shù)據(jù)路徑將CONTROL信號(hào)放到最后
調(diào)整計(jì)算順序
在下例中,包含一個(gè)加法器和比較器:
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信號(hào)到來(lái)較晚,此時(shí)調(diào)整A的計(jì)算路徑,原來(lái)的計(jì)算順序?yàn)?
通過(guò)調(diào)整代碼:
always@(A,B,C,D) begin
if(A 24-B)Z<=C;
else Z<=D;
end
A將少過(guò)一個(gè)減法器,此時(shí)電路結(jié)構(gòu)變?yōu)?
在RTL編碼中考慮面積
- 隨著芯片工藝的進(jìn)步和生產(chǎn)成本的降低,面積顯得沒(méi)有時(shí)序問(wèn)題重要。
- 減少設(shè)計(jì)面積可以
- 成本降低、功耗降低,
- 特別是對(duì)于FPGA的設(shè)計(jì),直接決定FPGA的選型。
- 一般綜合過(guò)程中可以對(duì)面積進(jìn)行優(yōu)化,但在RTL編碼中如果注意節(jié)約設(shè)計(jì)面積,往往可以達(dá)到事半功倍的效果。
- 減少設(shè)計(jì)的面積
- 估計(jì)設(shè)計(jì)使用資源的數(shù)量
- 知道設(shè)計(jì)中那些部分占用了較大的面積(觸發(fā)器,加法器,乘法器)
- 觸發(fā)器的資源估計(jì)
- 觸發(fā)器的數(shù)量:觸發(fā)器的數(shù)量由功能決定,很難減少
- 觸發(fā)器的面積:比較好估計(jì)
操作符優(yōu)化
所以優(yōu)化目標(biāo)大頭放在 組合邏輯 中,其對(duì)應(yīng)著RTL代碼中的各種操作符 RTL代碼屮的一個(gè)“+“可能對(duì)應(yīng)著一個(gè)64位的加法器。以下這些操作符都可能產(chǎn)生較大的組合邏輯,使用時(shí)應(yīng)加以重視,如“+”、“-”、“×”、“/”以及 條件語(yǔ)句的比較運(yùn)算 。對(duì)于這些操作,首先應(yīng)該 判斷其必要性 ,是否能用更簡(jiǎn)單的運(yùn)算代替。
比如考慮
if(A< 32)
可以將其修改為
if(A[5]==1'b1)
通過(guò)這種方式即可節(jié)省一個(gè)6bit的比較器
此處例子中,需要考慮A的自身位寬,未必適合于所有設(shè)計(jì),對(duì)所有定值比較都可以這樣考慮
資源共享
如果,必須使用復(fù)雜的運(yùn)算符,則應(yīng)考慮是否可以 資源共享 。盡管電路邏輯綜合工具也會(huì)在綜合的過(guò)程中采用資源共享的方法進(jìn)行優(yōu)化,但是,綜合器的策略是有限的,因此在編寫(xiě)RTL的時(shí)候,應(yīng)該盡量考慮共享,而不是把這項(xiàng)工作完全留給綜合工具。
比如對(duì)以下代碼:
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)
則可以減少兩個(gè)不必要的加法器
多比特
多比特的信號(hào)也往往會(huì)占用較大的資源,因?yàn)槭褂眠@些信號(hào)的操作都是對(duì)所有的比特進(jìn)行的,相當(dāng)于成倍使用資源,因此,對(duì)這類信號(hào)的操作也應(yīng)重視。
應(yīng)該看一看這個(gè)信號(hào)的所有比特是否都需要參與操作,如果不是,則可以只對(duì)需要的部分比特進(jìn)行操作。
假設(shè):
訪問(wèn)—RAM的地址有8比特,而寫(xiě)入操作時(shí)從0開(kāi)始,每隔32個(gè)地址寫(xiě)入一個(gè)值,地址的產(chǎn)生可以有兩種寫(xiě)法。
addr <= addr + 32;
和
addr[7:5] <= addr[7:5] + 1;
addr[4:0] <= addr[4:0] + 0;
邏輯優(yōu)化
針對(duì)不同的設(shè)計(jì),還有可能有各種各樣的優(yōu)化和改進(jìn)的方法,但是,歸結(jié)到一點(diǎn),就是編寫(xiě)代碼時(shí),應(yīng)對(duì)操作符有足夠的重視,對(duì)有可能簡(jiǎn)化的地方盡量簡(jiǎn)化。 邏輯簡(jiǎn)化往往在減少面積的同時(shí)也減少了延遲 ,因此,是值得花費(fèi)一些時(shí)間的。
在RTL編碼中考慮功耗
考慮電路割點(diǎn)的功耗:
在RTL設(shè)計(jì)中無(wú)法改變負(fù)載電容和 工作電壓 ,所以在RTL級(jí)主要考慮盡量降低電路的翻轉(zhuǎn)頻率
主要措施包括如下:
- 門(mén)控時(shí)鐘,門(mén)控時(shí)鐘是電路設(shè)計(jì)最常用也是最有效的方法,在邏輯綜合階段可以讓綜合工具自行插入。
- 增加使能信號(hào),使得部分電路只有在需要工作時(shí)才工作;
- 對(duì)芯片各個(gè)模塊進(jìn)行控制,在需要工作時(shí)才工作;
- 除了有用信號(hào)和時(shí)鐘的翻轉(zhuǎn)會(huì)消耗功耗,組合邏輯產(chǎn)生的毛刺也會(huì)大量消耗功耗。但是,毛刺在設(shè)計(jì)中無(wú)法避免,因此,只有盡呈減少毛刺在電路中的傳播,才可以減少功耗。即在設(shè)計(jì)中,盡量把產(chǎn)生毛刺的電路放在傳播路徑的最后。另外,可以使用一些減少毛刺的技術(shù)。
- 對(duì)于有限狀態(tài)機(jī),可以通過(guò)低功耗編碼來(lái)減少電路的翻轉(zhuǎn)。比如對(duì)4比特狀態(tài)編碼:
更改狀態(tài)編碼后:
總的來(lái)說(shuō),使用這些技術(shù)時(shí),應(yīng)首先
- 考慮全局的功耗控制
- 在RTL編碼中,注意消耗功率較多的電路,如狀態(tài)機(jī)、譯碼器、多路選擇器等。
- 在綜合中,使用門(mén)控時(shí)鐘和其他減少功耗的優(yōu)化技術(shù)。
- 這里要注意下門(mén)控時(shí)鐘和增加使能控制的區(qū)別。增加使能僅僅是使得電路的信號(hào)不在翻轉(zhuǎn),但是時(shí)鐘每個(gè)周期還會(huì)繼續(xù)翻轉(zhuǎn)。而門(mén)控時(shí)鐘則是直接關(guān)掉時(shí)鐘,這種方法效果更好。
在RTL編碼中考慮布線問(wèn)題
布線(routing)是芯片設(shè)計(jì)中 最后的流程 ,其功能是根據(jù)門(mén)級(jí)網(wǎng)表的描述實(shí)現(xiàn)各個(gè)單元的連接
布局(placement)是芯片設(shè)計(jì)中 最關(guān)鍵的因素 ,但即使使用最好的布局工具,還是可能出現(xiàn)無(wú)法布通的情況
-> 如果可以在RTL編碼階段考慮代碼可能對(duì)布線產(chǎn)生的影響,就可能避免最后出現(xiàn)無(wú)法布通的情況。
布線階段,通常熱點(diǎn)是一個(gè)影響布線質(zhì)量的問(wèn)題。
熱點(diǎn)是指設(shè)計(jì)的功能需要在一個(gè)面積內(nèi)占用大量的布線資源:
熱點(diǎn)產(chǎn)生原因:RTL編碼時(shí)使用了特定的結(jié)構(gòu),如很大的MUX:
- 這種結(jié)構(gòu)產(chǎn)生的熱點(diǎn),在綜合的時(shí)候,導(dǎo)致的延遲是看不出來(lái) 只有到了布線階段才能給看到它的負(fù)面影響。因此,我們?cè)赗TL階段應(yīng)該重視這種電路,及早發(fā)現(xiàn)可能在布線階段產(chǎn)生的問(wèn)題。
- 如果設(shè)計(jì)的功能中確實(shí)需要采用大的mux,可以通過(guò)其他方式改變他的結(jié)構(gòu)。其基本的思路是將一個(gè)大的mux分解為多級(jí)較小的mux。
-
FPGA設(shè)計(jì)
+關(guān)注
關(guān)注
9文章
428瀏覽量
26487 -
比較器
+關(guān)注
關(guān)注
14文章
1636瀏覽量
107103 -
RTL
+關(guān)注
關(guān)注
1文章
385瀏覽量
59706 -
觸發(fā)器
+關(guān)注
關(guān)注
14文章
1996瀏覽量
61053 -
多路選擇器
+關(guān)注
關(guān)注
1文章
22瀏覽量
6517
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論