Verilog代碼編寫規範

admin @ 2014-03-26 , reply:0

概述
 一.強調Verilog代碼編寫風格的必要性。   強調Verilog代碼編寫規範,經常是一個不太受歡迎的話題,但卻是非常有必要的。每個代碼編寫者都有自己的編寫……

 一. 強調Verilog代碼編寫風格的必要性。
    強調Verilog代碼編寫規範,經常是一個不太受歡迎的話題,但卻是非常有必要的。
每個代碼編寫者都有自己的編寫習慣,而且都喜歡按照自己的習慣去編寫代碼。與自己編寫風格相近的代碼,閱讀起來容易接受和理解。相反和自己編寫風格差別較大的代碼,閱讀和接受起來就困難一些。
    曾有編程大師總結說,一個優秀的程序員,能維護的代碼長度大約在1萬行數量級。代碼的整潔程度,很大程度上影響著代碼的維護難度。
    遵循代碼編寫規範書寫的代碼,很容易閱讀、理解、維護、修改、跟蹤調試、整理文檔。相反代碼編寫風格隨意的代碼,通常晦澀、凌亂,會給開發者本人的調試、修改工作帶來困難,也會給合作者帶來很大麻煩。
    (實際上英文Coding Style有另一層涵義,更偏重的是,某一個電路,用那一種形式的語言描述,才能將電路描述得更準確,綜合以後產生的電路更合理。本文更偏重的是,編寫Verilog代碼時的書寫習慣。)

二. 強調編寫規範的宗旨。
縮小篇幅
提高整潔度
便於跟蹤、分析、調試
    增強可讀性,幫助閱讀者理解
    便於整理文檔
    便於交流合作

三. 變數及信號命名規範。
1.     系統級信號的命名。
系統級信號指複位信號,置位信號,時鐘信號等需要輸送到各個模塊的全局信號;系統信號以字元串Sys開頭。

2.     低電平有效的信號后一律加下劃線和字母n。如:SysRst_n;FifoFull_n;

3.     經過鎖存器鎖存后的信號,后加下劃線和字母r,與鎖存前的信號區別。如CpuRamRd信號,經鎖存后應命名為CpuRamRd_r。
低電平有效的信號經過鎖存器鎖存后,其命名應在_n后加r。如CpuRamRd_n信號,經鎖存后應命名為CpuRamRd_nr
多級鎖存的信號,可多加r以標明。如CpuRamRd信號,經兩級觸發器鎖存后,應命名為CpuRamRd_rr。

4.    模塊的命名。
    在系統設計階段應該為每個模塊進行命名。命名的方法是,將模塊英文名稱的各個單詞首字母組合起來,形成3到5個字元的縮寫。若模塊的英文名只有一個單詞,可取該單詞的前3個字母。各模塊的命名以3個字母為宜。例如:
    Arithmatic Logical Unit模塊,命名為ALU。
    Data Memory Interface模塊,命名為DMI。
    Decoder模塊,命名為DEC。

5.    模塊之間的介面信號的命名。
所有變數命名分為兩個部分,第一部分表明數據方向,其中數據發出方在前,數據接收方在後,第二部分為數據名稱。
兩部分之間用下劃線隔離開。
第一部分全部大寫,第二部分所有具有明確意義的英文名全部拼寫或縮寫的第一個字母大寫,其餘部分小寫。
舉例:CPUMMU_WrReq,下劃線左邊是第一部分,代表數據方向是從CPU模塊發向存儲器管理單元模塊(MMU)。下劃線右邊Wr為Write的縮寫,Req是Request的縮寫。兩個縮寫的第一個字母都大寫,便於理解。整個變數連起來的意思就是CPU發送給MMU的寫請求信號。
        模塊上下層次間信號的命名也遵循本規定。
    若某個信號從一個模塊傳遞到多個模塊,其命名應視信號的主要路徑而定。

6. 模塊內部信號:
模塊內部的信號由幾個單詞連接而成,縮寫要求能基本表明本單詞的含義;
單詞除常用的縮寫方法外(如:Clock->Clk, Write->Wr, Read->Rd等),一律取該單詞的前幾個字母( 如:Frequency->Freq, Variable->Var 等);
每個縮寫單詞的第一個字母大寫;
若遇兩個大寫字母相鄰,中間添加一個下劃線(如DivN_Cntr);
舉例:SdramWrEn_n;FlashAddrLatchEn;

四. 編碼格式規範。
1. 分節書寫,各節之間加1到多行空格。如每個always,initial語句都是一節。每節基本上完成一個特定的功能,即用於描述某幾個信號的產生。在每節之前有幾行註釋對該節代碼加以描述,至少列出本節中描述的信號的含義。

2. 行首不要使用空格來對齊,而是用Tab鍵,Tab鍵的寬度設為4個字元寬度。行尾不要有多餘的空格。

3. 註釋。
使用//進行的註釋行以分號結束;
使用/* */進行的註釋,/*和*/各佔用一行,並且頂頭;
例:
// Edge detector used to synchronize the input signal;

4. 空格的使用:
不同變數,以及變數與符號、變數與括弧之間都應當保留一個空格。
Verilog關鍵字與其它任何字元串之間都應當保留一個空格。如:
Always @ (......)
使用大括弧和小括弧時,前括弧的後邊和后括弧的前邊應當留有一個空格。
邏輯運算符、算術運算符、比較運算符等運算符的兩側各留一個空格,與變數分隔開來;單操作數運算符例外,直接位於操作數前,不使用空格。
使用//進行的註釋,在//后應當有一個空格;註釋行的末尾不要有多餘的空格。
例:
assign SramAddrBus = { AddrBus[31:24], AddrBus[7:0] };
assign DivCntr[3:0] = DivCntr[3:0] + 4'b0001;
assign Result = ~Operand;

5. 同一個層次的所有語句左端對齊;Initial、always等語句塊的begin關鍵詞跟在本行的末尾,相應的end關鍵詞與Initial、always對齊;這樣做的好處是避免因begin獨佔一行而造成行數太多;
例:
always @ ( posedge SysClk or negedge SysRst ) begin
if( !SysRst ) DataOut <= 4'b0000;
else if( LdEn ) begin
DataOut <= DataIn;
End
else DataOut <= DataOut + 4'b0001;
end

6. 不同層次之間的語句使用Tab鍵進行縮進,每加深一層縮進一個Tab;

8.    在endmodule,endtask,endcase等標記一個代碼塊結束的關鍵詞後面要加上一行註釋說明這個代碼塊的名稱;

9.    在task名稱前加tsk以示標記。在function的名稱前加func以示標記。例如:
task tskResetSystem;
......
endtask    //of tskResetSystem

五.小結:
    以上列出的代碼編寫規範無法覆蓋代碼編寫的方方面面,還有很多細節問題,需要在實際編寫過程中加以考慮。並且有些規定也不是絕對的,需要靈活處理。並不是律條,但是在一個項目組內部、一個項目的進程中,應該有一套類似的代碼編寫規範來作為約束。
總的方向是,努力寫整潔、可讀性好的代碼。




[admin via 研發互助社區 ] Verilog代碼編寫規範已經有3884次圍觀

http://cocdig.com/docs/show-post-43531.html