5.2 代碼編寫中容易出現(xiàn)的問(wèn)題
- 在for-loop中包括不變的表達(dá)式 浪費(fèi)運(yùn)算時(shí)間
for(i=0;i<4;i=i+1)
begin
Sig1=Sig2;
DataOut[i]=DataIn[i];
end
for-loop中第一條語(yǔ)句始終不變,浪費(fèi)運(yùn)算時(shí)間.
- 資源共享問(wèn)題 條件算子中不存在 資源共享 ,如
z=(cond)?(a+b):(c+d);
必須使用兩個(gè)加法器; 而等效的條件if-then-else語(yǔ)句則可以資源共享 如
if(Cond)
z=a+b;
else
z=c+d;
只要加法器的輸入端復(fù)用,就可以實(shí)現(xiàn)加法器的共享,使用一個(gè)加法器實(shí)現(xiàn)。
- 由于組合邏輯的位置不同而引起過(guò)多的觸發(fā)器綜合 如下面兩個(gè)例子
moduleCOUNT(AndBits,Clk,Rst);
OutputAndbits;
InputClk,
Rst;
RegAndBits;
//internalreg
Reg[2:0]Count;
always@(posedgeClk)begin
begin
if(Rst)
Count<=#u_dly0;
else
Count<=?#u_dly?Count?+?1;
End//endif
AndBits<=?#u_dly?&?Count;
?End?//endalways
endmodule
在進(jìn)程里的變量都綜合成觸發(fā)器了,有4個(gè);
moduleCOUNT(AndBits,Clk,Rst);
OutputAndBits;
InputClk,
Rst;
RegAndBits;
//internalreg
Reg[2:0]Count;
always@(posedgeClk)begin//synchronous
if(Rst)
Count<=?#u_dly?0;
else
Count<=?#u_dly?Count?+?1;
End//endalways
always@(Count)begin//asynchronous
AndBits=&Count;
End//endalways
Endmodule//endCOUNT
組合邏輯單開(kāi),只有3個(gè)觸發(fā)器.
- 謹(jǐn)慎使用異步邏輯
moduleCOUNT(Z,Enable,Clk,Rst);
Output[2:0]Z;
InputRst,
Enable,
Clk;
reg[2:0]Z;
always@(posedgeClk)begin
if(Rst)begin
Z<=#u_dly1'b0;
end
elseif(Enable==1'b1)begin
If(Z==3'd7)begin
Z<=#u_dly1'b0;
End
elsebegin
Z<=?#u_dly?Z?+?1'b1;
end
End
Else;
End//endalways
Endmodule//endCOUNT
是同步邏輯,而下例則使用了組合邏輯作時(shí)鐘,以及異步復(fù)位.實(shí)際的運(yùn)用中要加以避免.
moduleCOUNT(Z,Enable,Clk,Rst);
Output[2:0]Z;
InputRst,
Enable,
Clk;
Reg[2:0]Z;
//internalwire
wireGATED_Clk=Clk&Enable;
always@(posedgeGATED_ClkorposedgeRst)begin
if(Rst)begin
Z<=#u_dly1'b0;
end
elsebegin
if(Z==3'd7)begin
Z<=#u_dly1'b0;
end
elsebegin
Z<=?#u_dly?Z?+?1'b1;
end
End//endif
End//endalways
Endmodule//endmodule
- 對(duì)組合邏輯的描述有多種方式 其綜合結(jié)果是等效的
c=a&b;
等效于
c[3:0]=a[3:0]&b[3:0];
等效于
c[3]=a[3]&b[3];
c[2]=a[2]&b[2];
c[1]=a[1]&b[1];
c[0]=a[0]&b[0];
等效于
for(i=0;i<=3;i=i+1)
c[i]=a[i]&b[i];
可以選擇簡(jiǎn)潔的寫法.- 考慮綜合的執(zhí)行時(shí)間
- 避免點(diǎn)到點(diǎn)的例外
- 避免偽路徑(False path)
- 避免使用Latch
- 當(dāng)你必須使用Latch時(shí) ,為了提高可測(cè)性, 需要加入測(cè)試邏輯。
always@(Cond)
begin
if(Cond)
DataOut<=DataInend
- 避免使用門控時(shí)鐘
使用門控時(shí)鐘(Gated clock)不利于移植 ,可能引起毛刺, 帶來(lái)時(shí)序問(wèn)題 ,同時(shí)對(duì)掃描鏈的形成帶來(lái)問(wèn)題。門控鐘在低功耗設(shè)計(jì)中要用到 ,但通常不要在模塊級(jí)代碼中使用 。可以借助于Power compiler來(lái)生成 ,或者在頂層產(chǎn)生。
- 避免使用內(nèi)部產(chǎn)生的時(shí)鐘
在設(shè)計(jì)中最好使用同步設(shè)計(jì)。如果要使用內(nèi)部時(shí)鐘 ,可以考慮使用多個(gè)時(shí)鐘。因?yàn)槭褂脙?nèi)部時(shí)鐘的電路要加到掃描鏈中比較麻煩,降低了可測(cè)性, 也不利于使用約束條件來(lái)綜合。
- 避免使用內(nèi)部復(fù)位信號(hào)。
模塊中所有的寄存器最好同時(shí)復(fù)位。如果要使用內(nèi)部復(fù)位, 最好將其相關(guān)邏輯放在單獨(dú)的模塊中, 這樣可以提高可閱讀性。
- 如果確實(shí)要使用內(nèi)部時(shí)鐘, 門控時(shí)鐘 ,或內(nèi)部的復(fù)位信號(hào) ,將它們放在頂層。
將這些信號(hào)的產(chǎn)生放在頂層的一個(gè)獨(dú)立模塊, 這樣所有的子模塊分別使用單一的時(shí)鐘和復(fù)位信號(hào)。一般情況下內(nèi)部門控時(shí)鐘可以用同步置數(shù)替代。
6 附錄
6.1 Module 編寫示例
/**
Filename﹕
Author﹕
Description﹕
Calledby﹕
RevisionHistory﹕mm/dd/yy
Revision1.0
Email﹕M@sz.huawei.com.cn
Company﹕HuaweiTechnology.Inc
Copyright(c)1999,HuaweiTechnologyInc,Allrightreserved
**/
Modulemodule_name(
Output_ports,//comment;portdescription
Input_ports,//comment;portdescription
Io_ports,//comment;portdescripttion
Clk_port,//comment;portdescription
Rst_port//comment;portdescription
);
//portdeclarations
Output[31:;0]Dataout;
Input[31:0]Datain;
InoutBi_dir_signal;
Inputinput1,
Input2;
//interrnalwire/regdeclarations
Wire[31:0]internal_data;
Regoutput_enable;
//moduleinstantiations,Self-buildmodule
Module_name1Uinstance_name1(...);
Module_name2Uinstance_name2(...);
//TSC4000cell
DTC12V1(.Clk(Clk),.CLRZ(Clr),.D(Data),.Q(Qout));
//continuousassignment
AssignData_out=out_enable?Internal_data:32’hz;
//alwaysblock
Always@(input2)
Begin
...
End
//functionandtaskdefinitions
Functiom[function_type]function_name;
Declarations_of_inputs;
[declarations_of_local_variables];
Begin
Behavirol_statement;
Function_name=function_express;
End
Endfunction//endfunction_name
Endmodule//endmodule_name
6.2 testbench編寫示例
下面是一個(gè)格雷碼的測(cè)試模塊,
moduleTB_GRAY;
regClock;
regReset;
wire[7:0]Qout;
integerfout;//輸出文件指針
parameterCYC=20;
GRAYDUT(.Clock(Clock),.Reset(Reset),.Qout(Qout));
initial
begin
Clock=1'b0;
Reset=1'b1;
#(5*CYC)Reset=1'b0;
#(5*CYC)Reset=1'b1;
#(5000*CYC)
$fclose(fout);
$finish;
end
initial
begin
$shm_open("GRAY.shm");
$shm_probe("AS");
fout=$fopen("gray.dat");
end
always#CYCClock=~Clock;
//輸出數(shù)據(jù)到文件gray.dat
always@(posedgeClock)
begin
$fwrite(fout,"%d%b
",Qout,Qout);
end
endmodule
-
在testbench中避免使用絕對(duì)的時(shí)間,如#20,#15或#(CYC+15)等,應(yīng)該在文件前面使用parameter定義一些常量,使得時(shí)間的定義象#(CYC+OFF0)的形式,便于修改。
-
觀測(cè)結(jié)果可以輸出到波形文件GRAY.shm ,或數(shù)據(jù)文件gray.dat 。生成波形文件可以用simwave觀測(cè)結(jié)果 ,比較直觀。而生成數(shù)據(jù)文件則既可以快速定位 ,也可以通過(guò)編寫的小程序工具對(duì)它進(jìn)行進(jìn)一步的處理。
-
對(duì)大的設(shè)計(jì)的頂層仿真 ,一般不要對(duì)所有信號(hào)跟蹤, 波形文件會(huì)很大, 仿真時(shí)間延長(zhǎng),可以有選擇的觀測(cè)一些信號(hào)。
審核編輯:郭婷
-
Verilog
+關(guān)注
關(guān)注
28文章
1351瀏覽量
110182 -
代碼
+關(guān)注
關(guān)注
30文章
4807瀏覽量
68800
原文標(biāo)題:【華為】verilog語(yǔ)言編寫規(guī)范(三)
文章出處:【微信號(hào):ZYNQ,微信公眾號(hào):ZYNQ】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論