Verilog HDL 编程规范
文章目錄
目錄
前言
一、文件聲明
二、命名
三、注釋
四、模塊
五、wire、reg
六、表達(dá)式
七、條件語句
八、可綜合性
九、可重用性
十、同步設(shè)計
十一、循環(huán)語句
十二、約束
十三、PLL、DCM
十四、關(guān)于對齊
參考聲明
前言
????????本專欄的博文都是關(guān)于Verilog HDL 語法。目前(2021/9/7),本人接觸FPGA和Verilog HDL 語法也差不多有近半年的時間了。對于一些常規(guī)的模塊編寫、IP核配置、仿真等沒有太大問題。但是如果涉及到特別復(fù)雜的邏輯設(shè)計時,也會出現(xiàn)較多的語法空白需要填補。所以我準(zhǔn)備以博客的形式重新整理相關(guān)的Verilog HDL 語法,做到知識的沉淀。
????????有很多從事FPGA數(shù)字設(shè)計的人都說過,掌握Verilog HDL 的基礎(chǔ)語法就能夠編寫將近90%的邏輯,盡管事實確實如此。但是全面一些我覺得會更好。因為設(shè)計的正確性和最優(yōu)性是兩個不同的概念。掌握基本的語法足夠讓你做到正確性,但是要想做到最優(yōu)設(shè)計,必須要對語法有比較全面、透徹的認(rèn)識。
????????Verilog HDL 編程風(fēng)格和編程規(guī)范程度都很重要。規(guī)范的編程不僅是有助于自己排錯查錯,也利于別人理解。盡量在初學(xué)階段就逐漸形成自己規(guī)范的編程風(fēng)格。
????????本文主要介紹一種規(guī)范的編程方式,供借鑒。
一、文件聲明
每個文件的開始,最好有說明該文件的文字段。主要包括:
1、公司、版權(quán)
2、文件名
3、作者
4、日期
5、版本號
6、概述(此部分包括模塊的功能描述、注意事項、關(guān)鍵點等)
如果后期對該模塊進(jìn)行版本修改、升級、維護(hù)等,在原本的聲明文字后再添加對應(yīng)版本修改信息。方便后期整理維護(hù)。
文件聲明具體格式參考:
//----------------文件的相關(guān)說明-------------------//// 公司版權(quán):// 文件名稱: // 功能說明:// 作 者: // 設(shè)計日期: // 版 本:// 相關(guān)參考://----------------- 版 本 修 改--------------------//// 改后版本: // 修改日期: // 修改作者:// 修改原因:二、命名
1、模塊(module)命名
? ? ? ? 一個 Verilog 文件只能包含一個?module ,module 的名稱統(tǒng)一小寫或者大寫。盡量不要大小寫混著用。因為大小寫切換麻煩。這只是命名,不是設(shè)置密碼,模塊(module)的名稱要能夠有一定的功能、參數(shù)代表性。要做到見名識義。
2、parameter 命名
? ? ? ? 參數(shù) parameter 的命名統(tǒng)一大寫。本地參數(shù) localparam 也統(tǒng)一用大寫命名。建議用 parameter 、localparam 參數(shù)類型命名一些諸如數(shù)據(jù)位寬、版本號、狀態(tài)值等有意義的常數(shù),方便程序改版升級。
3、信號命名
? ? ? ? 輸入信號、輸出信號、內(nèi)部信號等的命名同一大寫或者小寫,不要混合使用(除了復(fù)位信號)。信號名稱最好能見名識義。最好在信號名稱最前面添加信號性質(zhì)或者類型標(biāo)識,方便使用。信號名稱不應(yīng)過長(盡量小于20個字符)。信號名稱縮寫要有一定的通用性,不能過于生僻。
? ? ? ? 命名舉例:
input I_SYS_CLK, //系統(tǒng)時鐘 input I_ARst_n, //異步復(fù)位信號 低電平有效 input I_Rst_n, //同步復(fù)位信號 低電平有效 input I_ARst, //異步復(fù)位信號 高電平有效 input [15:0] I_FFT_DATA_RE,//FFT計算輸入數(shù)據(jù)實部 input [15:0] I_FFT_DATA_IM,//FFT計算輸入數(shù)據(jù)虛部output [15:0] O_FFT_RES_RE,//FFT計算結(jié)果實部 output [15:0] O_FFT_RES_IM,//FFT計算結(jié)果虛部 output O_VALID, //輸出有效信號wire W_READ_FLAG;//讀標(biāo)志信號 wire [11:0] W_FIR_RES; //FIR濾波器輸出結(jié)果reg R_1_VALID; //valid 信號打一拍 reg R_2_VALID; //valid 信號打二拍 reg [15:0] R_COUNTER; //計數(shù)器三、注釋
????????用 // 注釋單獨的一行,用 /* */ 注釋多行。注釋的內(nèi)容不要冗長。
四、模塊
? ? ? ? 模塊的例化名要做到統(tǒng)一,且有規(guī)律可循。IP 核的例化也是一樣。
? ? ? ? 一條語句占一行。
? ? ? ? 模塊的接口信號按照輸入(input)、雙端口(inout)、輸出(output)的順序定義。
? ? ? ? 多bit信號定義按照【width-1:0】的方式定義。
? ? ? ? 不能用向量方式定義一組時鐘信號。如 input? ?[2:0]? ?CLK
? ? ? ? module內(nèi)不能存在無驅(qū)動源的多余信號,也不能存在無驅(qū)動的輸出信號。
? ? ? ? 頂層模塊中,除了例化模塊和它們之間彼此的連線,避免出現(xiàn)其他的邏輯。
? ? ? ? 子模塊的輸出建議用寄存器輸出。
? ? ? ? 子模塊內(nèi)避免雙向端口(inout),最好在頂層模塊處理雙向總線。
? ? ? ? 子模塊內(nèi)禁止用三態(tài)邏輯(除非子模塊的三態(tài)邏輯輸出直接供頂層模塊使用),頂層模塊可以用三態(tài)邏輯。
? ? ? ? 模塊內(nèi)避免存在未連接的端口。
? ? ? ? 為邏輯升級等準(zhǔn)備的端口、信號,現(xiàn)階段先注釋掉。
五、wire、reg
? ? ? ? 禁止鎖存器和觸發(fā)器在不同的always塊中被賦值,形成多重驅(qū)動。
? ? ? ? always 語句實現(xiàn)時序邏輯用 非阻塞賦值語句,實現(xiàn)組合邏輯用 阻塞賦值語句。同一種信號的賦值不能既是阻塞賦值 又是 非阻塞賦值。
? ? ? ? 所定義的wire 、 reg 類型的信號不能未使用。
? ? ? ? 建議不要使用 integer 類型的寄存器。
? ? ? ? 寄存器類型(reg)的信號要初始化。
? ? ? ? 除了移位寄存器,一個always語句塊中只對一個信號賦值、運算。?
六、表達(dá)式
? ? ? ? 表達(dá)式內(nèi)多用小括號()表示運算優(yōu)先級。
? ? ? ? 設(shè)計中用到的邏輯電平值用基數(shù)表示。如:1’b0、8‘b0101_1111、16’hA89B
? ? ? ? 進(jìn)行端口聲明、信號賦值、變量比較時,一定注意位寬匹配。
七、條件語句
? ? ? ? if 、 else if 語句要有 else 語句與之相對應(yīng)。
? ? ? ? case 語句要有default。
? ? ? ? if 語句的條件表達(dá)式不能是常數(shù)。
????????不建議5級以上的 if-else 嵌套。
? ? ? ? 條件表達(dá)式必須為 1 bit 。如:
// 異步復(fù)位信號 低電平有效 if (I_ARst_n == 1'b0) // 不建議的寫法: if (I_ARst_n == 0) if (!I_ARst_n)八、可綜合性
? ? ? ? 避免使用 include 語句;
? ? ? ? 應(yīng)采用復(fù)位方式初始化,仿真時可用 initial 語句初始化;
? ? ? ? 不要使用 specify 模塊;
? ? ? ? 不要使用 === 、!== 等不可綜合的操作符;
? ? ? ? 除仿真外不要使用 fork-join 語句、while 語句、repeat 語句、forever 語句、force 語句、release語句、named events 語句、系統(tǒng)任務(wù)($);
? ? ? ? 不能在連續(xù)賦值語句中引入 驅(qū)動強(qiáng)度 和 延時;
? ? ? ? 禁止用 trireg 型線網(wǎng);
? ? ? ? 禁止用tri1、tri0、triand、trior、型連接;
? ? ? ? 禁止位驅(qū)動型(supply0、supply1)線網(wǎng)賦值;
? ? ? ? 禁止在RTL代碼中實例化門級單元,如:CMOS/RCMOS/NMOS/PMOS/RNMOS/RPMOS
/trans/rtrans/tranif0/tranif1
九、可重用性
? ? ? ? 進(jìn)口信號盡量少,接口時序盡量簡單;
? ? ? ? 將狀態(tài)機(jī)電路與其他電路分開,異步電路與同步電路分開,便于后續(xù)的綜合、約束;
? ? ? ? 頂層模塊中將 I/O 端口、邊界測試電路、邏輯設(shè)計相區(qū)分;
十、同步設(shè)計
? ? ? ? 同一個模塊內(nèi),時序電路應(yīng)在時鐘的同一個邊沿動作。如果有的部分需要用到上升沿而有的部分需要用到下降沿,那么就要用兩個模塊來設(shè)計。
? ? ? ? 頂層模塊中,時鐘信號必須可見,不要再模塊內(nèi)部生成時鐘信號。要用PLL/MMCM等生成。
? ? ? ? 避免使用門控時鐘、門控復(fù)位。
? ? ? ? 對于同步復(fù)位電路,建議在同一時鐘域使用單一的全局同步復(fù)位電路;對于異步復(fù)位電路,建議使用單一全局異步復(fù)位電路。
? ? ? ? 不要在時鐘、復(fù)位路徑上添加任何 buffer。
? ? ? ? 避免使用latch(鎖存器)。
? ? ? ? 寄存器的異步復(fù)位和置位不能同時有效。
? ? ? ? 避免使用組合反饋邏輯。
? ? ? ? 復(fù)雜電路將組合邏輯和時序邏輯分成獨立的 always 塊描述。
十一、循環(huán)語句
? ? ? ? 不建議使用循環(huán)語句,必要時可用 for 語句。
十二、約束
? ? ? ? 對全部的時鐘頻率、占空比進(jìn)行約束。
? ? ? ? 對全局時鐘的 skew 進(jìn)行約束。
? ? ? ? 根據(jù)輸入輸出信號特性進(jìn)行上下拉約束。
? ? ? ? 綜合設(shè)置,建議將 fanout 設(shè)置為30。
? ? ? ? 布局布線報告中 IOB、LUTs、RAM等資源利用率低于80%。
十三、PLL、DCM
? ? ? ? 使用FPGA內(nèi)部PLL/DCM資源時,應(yīng)保證輸入時鐘抖動小于300ps,以防止失鎖。
? ? ? ? 輸入時鐘出現(xiàn)瞬斷,必須復(fù)位PLL/DCM。
十四、關(guān)于對齊
? ? ? ? 代碼對齊用空格,盡量不用 Tab 。
參考聲明
【1】Verilog 紅寶書編程規(guī)范。
【2】Verilog 編程規(guī)范。?
歡迎提出寶貴意見~
文末推薦
掌握了基本的Verilog語法,不去實戰(zhàn)練習(xí)的話很難有大的突破。牛客網(wǎng)可以為大家提供一個免費的刷題練習(xí)的平臺。非常推薦大家使用。
?鏈接如下:牛客網(wǎng)-Verilog專項https://www.nowcoder.com/link/pc_csdncpt_zls_verilog這個里面有很多代碼題目練習(xí),對于新手來說可以快速掌握Verilog編程的基本語法,對于老手來說也可以鞏固自己的編程能力。不用付費免費試用哦。基本是每個即將找工作的人必備的刷題網(wǎng)站。快行動起來吧!
總結(jié)
以上是生活随笔為你收集整理的Verilog HDL 编程规范的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 双目摄像头立体成像(二)畸变矫正与立体校
- 下一篇: AMCL介绍