1. 程式人生 > >Verilog HDL程式碼書寫規範

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