Verilog HDL程式碼書寫規範
1. 目的
本規範的目的是提高書寫程式碼的可讀性、可修改性、可重用性,優化程式碼綜合和模擬的結
果,指導設計工程師使用VerilogHDL規範程式碼和優化電路,規範化可程式設計技術部的FPGA設計輸
入,從而做到:①邏輯功能正確,②可快速模擬,③綜合結果最優(如果是hardware>
Mem[I] <= 32’>
y避免使用保留字
如:in,out,x,z等不能夠做為變數、埠或模組名
y新增有意義的字尾,使訊號名更加明確,常用的字尾如下:
寄存後的訊號 _reg
晶片的雙向訊號 -xbio
晶片的三態輸出 _xz
晶片的漏極開路輸出 _xod
晶片原始輸出訊號 _xo
晶片原始輸入訊號 _xi
下降沿有效的暫存器 _f
連到三態輸出的訊號 _z
寄存前的訊號 _next
時鐘訊號 _Clk
意義字尾
y一個module一個檔案,且檔名能與module名對應起來
4.1.2. Modules
y頂層模組應只是內部模組間的互連。
Verilog設計一般都是層次型的設計,也就是在設計中會出現一個或多個模組,模組間的呼叫
在所難免。可把設計比喻成樹,被呼叫的模組就是樹葉,沒被呼叫的模組就是樹根,那麼在這個
樹根模組中,除了內部的互連和模組的呼叫外,儘量避免再做邏輯,如不能再出現對reg變數賦值
等。這樣做的目的是為了更有效的綜合,因為在頂層模組中出現中間邏輯,Synopsys 的design
compiler 就不能把子模組中的邏輯綜合到最優。
y每一個模組應在開始處註明檔名、功能描述、引用模組、設計者、設計時間及版權資訊等。代
碼中的所有說明、註釋必須均為英文。需要特別說明的是,必須對Revision History要格外重視,必
須將每次版本修改的資訊按照時間一一詳加敘述,以保持版本的可讀性與繼承性。
如:/* ========================*\
Filename ﹕RX_MUX.v
Author ﹕
Description ﹕
Called>
If (alpha <>
y用一個函式(function)來代替表示式的多次重複
如果程式碼中發現多次使用一個特殊的表示式,那麼就用一個函式來代替,這樣在以後的版本升級
時更便利,這種概念在做行為級的程式碼設計時同樣使用,經常使用的一組描述可以寫到一個任務
(task)中。
4.1.5.IF 語句
y向量比較時,比較的向量要相等。
當比較向量時,verilog將對位數小的向量做0 擴充套件以使它們的長度相匹配,它的自動擴充套件為隱
式的。建議採用顯示擴充套件,這個規律同樣適用於向量同常量的比較。
Reg Abc [7:0];
Reg Bca [3:0];
......
If (Abc = = {4’>
y每一個If 都應有一個else 和它相對應
在做硬體設計時,常要求條件為真時執行一種動作而條件為假時執行另一動作,即使認為條件
為假不可能發生。沒有else可能會使綜合出的邏輯和RTL級的邏輯不同。如果條件為假時不進行任
何操作,則用一條空語句。
always @(Cond)
begin
if (Cond)
DataOut <= DataIn;
Else :;
end
以上語句DataOut會綜合成鎖存器.
y應注意If ..else>
else>
end
以上語句在行為級模擬時e的變化將不會使模擬器進入該程序,導致模擬結果錯誤
yAssign/deassign 僅用於模擬加速
yForce/release 僅用於debug
y避免使用Disable
y對任何reg賦值用非阻塞賦值代替阻塞賦值
4.1.9Combinatorial Vs Sequential Logic
y如果一個事件持續幾個時鐘週期,設計時就用時序邏輯代替組合邏輯
如: Wire Ct_24_e4; //it>
那麼這種設計將綜合出兩個8 位元的加法器,而且會產生毛刺,對於這樣的電路,要採用時序
設計,程式碼如下:
Reg Ct_24_e4;
Always @(poseddge Clk>
Else>
Ct_24_e4 <= 1’>
Ct_24_e4 <= 1’>
Assign bus[31:0] =>
begin
....
End //>
//style 2 --->
begin //drive>
always @(posedge Clk>
else
CurrentState <= NextState;
end
always @(In1>
Out1 <= 1'b0;
end
S1:
begin
if (In1)
begin
NextState <= S0;
Out1 <= In2;
end
Else
begin
NextState <= S1;
Out1 <= !In2;
end
Endcase
end
endmodule
4.2 程式碼編寫中容易出現的問題
y在for-loop中包括不變的表示式,浪費運算時間
for (i=0;i<4;i=i+1)
begin
Sig1 = Sig2;
DataOut[i] = DataIn[i];
end
for-loop中第一條語句始終不變,浪費運算時間.
y資源共享問題
條件運算元中不存在資源共享,如
z = (cond) ? (a +>
else
z =>
else
Count <= Count + 1;
End //end>
End //end>
else
Count <= Count + 1;
End //end>
End //end>
end
else>
begin
If (Z == 3'd7)
begin
Z <= 1'b0;
End
Else
begin
Z <= Z + 1'b1;
end
End
Else ;
End //end>
always @(posedge GATED_Clk>
end
Else
begin
if (Z == 3'd7)
begin
Z <= 1'b0;
end
Else
begin
Z <= Z + 1'b1;
end
End //end>
等效於
c[3:0] =>
c[2] =>
c[0] =>
c[i] =>
end
y避免使用門控時鐘
使用門控時鐘(Gated>
always @(posedge GATED_Clk>
end
Else
begin
if (Qout == 3'd7)
begin
Qout= 1'b0;
end
Else
begin
Qout = Qout + 1'b1;
end
end
end
endmodule
module COUNT (Reset,Enable,Clk,Qout);
input Reset,Enable,Clk;
output [2:0] Qout;
reg [2:0] Qout;
always @(posedge Clk)
begin
if (Reset)
begin
Qout = 1'b0;
end
else>
begin
if (Qout == 3'd7)
begin
Qout = 1'b0;
end
Else
begin
Qout = Qout + 1'b1;
end
end
end
endmodule