0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

Verilog編寫規(guī)范

FPGA設計論壇 ? 來源:FPGA設計論壇 ? 2025-04-11 09:36 ? 次閱讀

1.命名規(guī)則

用有意義而有效的名字

有效的命名有時并不是要求將功能描述出來,如:

for(i =0;i 

用連貫的縮寫
采用縮寫時應該主義同一信號在模塊中的一致性.如:

 Addraddress  Pntrpointer   Clkclock  Rstreset

用最右邊的字符下劃線代表低電平有效,高電平有效的信號不得以下劃線表示,短暫的有效信號建議采用高電平有效.如:

  Rst_   Trdy_   Irdy_

大小寫原則
名字一般首字符大寫,其余小寫(但是parameter/integer定義的數(shù)值名可以全部大寫),兩個單詞之間用下劃線連接.如:

  Data_in  Mem_wr   Rd_req   Sensor_ctrl

全局信號名中應包含信號來源的信息.

如:D_addr[7:2],這里的"D"指明了地址是解碼模塊(Decoder module)的地址.

同一信號在不同層次應保持一致性

自己定義的常數(shù)和類型等用大寫表示.如:

  parameter CYCLE=100;

避免使用保留字

如:in,out,x,z等不能夠作為變量,端口或模塊名

添加有意義的后綴,使信號名更加明確,常用的后綴有:

 _Clk  時鐘信號  _next 寄存前的信號  _z   連到三態(tài)輸出的信號  _f   下降沿有效的寄存器  _xi  芯片原始輸入信號  _xo  芯片原始輸出信號  _xod  芯片的漏極開路輸出  _xz  芯片的三態(tài)輸出   -xbio  芯片的雙向信號

2.Modules

頂層模塊應知識內部模塊間的互聯(lián)

Verilog設計一般都是層次性的設計,也就是在設計中會出現(xiàn)一個或多個模塊,模塊間的調用在所難免.可把設計比喻成樹,被調用的模塊就是輸液,沒被調用的模塊就是樹根,那么在這個樹根模塊中,除了內部的互聯(lián)和模塊的調用外,盡量避免再做邏輯,如不能再出現(xiàn)對reg變量賦值等.這樣做的目的是為了更有效的綜合,因為在頂層模塊VS出現(xiàn)中間邏輯,Synopsys的Design Compiler就不能把子模塊中的邏輯綜合到最優(yōu).

每個模塊應該在開始處注明文件名,功能描述,引用模塊,設計者,設計時間,以及版權信息等.如:

 /*==============================================================================================*/    Filename      :  RX_MUX.v     Author       :  Dongyi Lin     Description     :      Called by      : Top module     Revision History  : 22-05-27    Revision      : 1.0    Email       :  lindongyi@163.com    Company      :  Hunan Institute of Advanced SensingandInformation Technology,                 Xiangtan Univeristy    Copyright     : 2022, Xiangtan University, All right reserved  /*==============================================================================================*/

不要對Input進行驅動,在module內不要存在沒有驅動的信號,更不能在端口模塊出現(xiàn)沒有驅動的輸出信號,避免再仿真或綜合時產生warning,干擾錯誤定位.

每行應限制在80個字符以內,以保持代碼的清晰,沒關和層次感.

一條語句占用一行,如果超過80個字符則要換行.

電路中調用的module名用Uxx表示.向量大小要表示清晰,采用基于名字的(name_based)調用,而非基于順序的(order_based).

Instance  Uinstance2(         .DataOut    (DOUT   ),         .DataIn     (DIN    ),         .Cs_      (Cs_),       );

時鐘的上升沿或下降沿采樣信號,不能一會上升沿,一會用下降沿.如果既要用上升沿又要用下降沿,應該分成兩個模塊設計.建議在頂層模塊中對Clock做一個not門,
在層次模塊中如果要用時鐘下降沿就可以用not門產生的Posedge Clk_,這樣的好處是在整個設計中采用同一種時鐘出發(fā),有利于綜合.

在模塊中增加注釋.

對信號,參量,引腳,模塊,函數(shù)及進程等加以說明,便于閱讀與維護.

Module名稱要用大寫表示,且應該與文件名保持一致.如:

  module DFF_ADSYNC_RST(              Reset,              Clk,              Data,              Qout   );

要嚴格芯片級模塊的劃分

只有頂層包括IO引腳(pads),中間層是時鐘產生模塊,JTAG,芯片的內核(CORE),這樣便于對每個模塊加以約束仿真,對時鐘也可以仔細仿真.

模塊輸出寄存器化

對所有的模塊的數(shù)據(jù)加以寄存,使得輸出的驅動強度和輸入的延遲可以預測,從而使得模塊的綜合過程更簡單.

3.Net and Register

一個reg變量只能在一個always語句中賦值

向量有效位順序一邊為從大到小
推薦Data[4:0]這種格式的定義.

對net和register類型的數(shù)據(jù)要做聲明(在PORT中).

4.Expressions

用括號表示執(zhí)行的優(yōu)先級,對讀者更情緒,更有意義,如:

 if(alpha =delta)...就不如下面的更好  if((alpha =delta))

用函數(shù)(function)來代替表達式的多次重復

這樣在以后的版本升級時更便利,而且經(jīng)常使用的一組描述可以寫到一個任務(task)中

5.IF語句

向量比較時,比較的向量要相等

在向量比較時,verilog將位數(shù)小的向量做0擴展以使得他們的長度相匹配,它的自動擴展是隱式的.建議采用顯式擴展.如:

  reg Abc[7:0];   reg Bca[3:0];   ......  if(Abc == {4'b0,Bca})begin   ......  if(Abc ==8'b0)begin

每一個if都應該有一個else與之對應
沒有else可能會使得綜合出的邏輯和RTL級的邏輯不同,如果條件為假時不盡興任何操作,則使用一條空語句,如:

  always@(Cond)begin    if(Cond)      DataOut <= DataIn; ? ? end ? ?//以上語句DataOut會綜合出鎖存器.

如果變量在if-else語句或case語句中沒有被完全賦值,則應該提前給變量一個缺省值,即:

  V1 =2'b00;   V2 =2'b00;   V3 =2'b00; //給V1,V2,V3缺省值,在后面賦值變量時有一個默認值在  if(a == b)begin    V1 =2'b01;     V2 =2'b10; //V3isnotassigned, so thedefaultvalueofV3is2'b00;  end  elseif(a == c)begin    V2 =2'b10;     V3 =2'b11; //V1isnotassigned, so thedefaultvalueofV1is2'b00;  end  ...

6.case語句

case語句通常被綜合為一級多路復用器,而if-then-else語句則綜合為優(yōu)先編碼的串接的多個多路復用器.通常case語句比if語句快,有限編碼結果在信號到達時有先后.case語句仿真比條件語句快.

所有的case語句都應該有一個default case,且允許空語句出現(xiàn)如:

default:;

7.Function

在function的最后給function賦值,如:

 functionCompareVectors;  input[199:0]Vector1;  input[199:0]Vector2;  input[31:0]Length;  //local variables  integeri;  regEqual;     begin    i =0;     Equal =1;//給Equal賦初值    while((i < Length)&& Equal)begin? ? ? ? ? ? ?if(Vector2[i] !==?1'bx)begin? ? ? ? ? ? ? ? ?if(Vector1[i] !== Vector2[i])  ? ? ? ? ? ? ? ? ? ?Equal =?0; ? ? ? ? ? ? ? ?else; ? ? ? ? ? ?end? ? ? ? ? ? ?i = i +?1; ? ? ? ?end? ? ? ? ?CompareVectors = Equal;?//賦值放在function的最后? ? ?endendfunction

在function中避免使用全局變量

否則容易引起HDL行為及仿真和門級仿真的差異.如:

 functionByteCompare;    input [15:0] Vector1;    input [15:0] Vector2;    input [7:0]  Length;    begin      if(ByteSel)//ByteSel是全局變量,如果在其他位置無意修改了,可能導致函數(shù)結果錯誤,            //所以最好在端口加以定義        ...      else        ...    end  endfunction

注意,函數(shù)與任務的調用均為靜態(tài)調用.

8.Assignment

Verilog有兩種賦值方式:過程賦值(procedural)和連續(xù)賦值(continuous).過程復制用于過程代碼(initial,always,task,function)中給reg和integer變量,time ealtime eal復制,而連續(xù)賦值一般給wire變量賦值.

always@(敏感表),敏感表要完整,如果不完整,將會引起仿真和綜合結果不一致,如:

 always@(dorClr)    if(Clr)       q =1'b0;    elseif(e)       q = d;  //以上語句在行為及仿真時e的變化不會使仿真器進入該always塊,導致仿真結果錯誤.

assign/deassign僅用于仿真加速,僅對寄存器有用.

force/release僅用于debug,對寄存器和線網(wǎng)型都有用.

避免使用disable

對任何reg賦值,都用非阻塞賦值(<=)代替阻塞賦值(=),reg的非阻塞賦值要加單位延遲,但異步復位可加可不加.如:

  always@(posedge Clk or negedge Rst_)begin    if(!Rst_)begin      Rega <=?0; ?//non_blocking assignment ? ? ? ? ? ? Regb <=?0; ? ? ? ?end? ? ? ? ?else?if(Soft_rst_all)begin? ? ? ? ? ? ?Rega <=?#u_dly ?0; ?//add unit delay? ? ? ? ? ? ?Regb <=?#u_dly ?0;? ? ? ? ?end? ? ? ? ?else?if(Load_init)begin? ? ? ? ? ? ?Rega <=?#u_dly ?init_rega;? ? ? ? ? ? ?Regb <=?#u_dly ?init_rega;? ? ? ? ?end? ? ? ? ?else?begin? ? ? ? ? ? ?Rega <=?#u_dly ?Rega << 1; ? ?? ? ? ? ? ? ?Rega <=?#u_dly ?St_1; ? ?? ? ? ? ?end? ? ?end?//end?Rega,Regb assignment

9.Combinatorial vs Sequential Logic

如果一個事件持續(xù)幾個時鐘周期,設計時就用時序邏輯代替組合邏輯. 如:

 wireCt_24_e4; //Ct_24_e4 last over several clock cycles  assign Ct_24_e4 = (count8bit[7:0] >=8'h24) & (count8bit[7:0] <=?8'he4);

這種設計將綜合處兩個8bit加法器,而且會產生毛刺,對于這種電路,要采用時序設計,代碼如下:

 regCt_24_e4;    always@(posedgeClkornegedgeRst_)begin    if(!Rst_)       Ct_24_e4 <=?1'b0; ? ? ? ?else?if(count8bit[7:0] >8'he4)       Ct_24_e4 <= #u_dly ?1'b0; ? ? ? ?else?if(count8bit[7:0] >8'h23)       Ct_24_e4 <= #u_dly ?1'b1; ? ? ? ?else? ? ; ? ?end

內部總線不要懸空.在default狀態(tài),要把他上拉或下拉.

 wire  OE_default;  assign OE_default = !(oe1 | oe2 | oe3);  assign bus[31:0] = oe1 ? Data1[31:0]:             oe2 ? Data2[31:0]:             oe3 ? Data3[31:0]:             OE_default ?32'h0000_0000://如果bus不等于oe1,oe2,oe3中的任何一個,                          //若等于OE_default,則bus為32'h0即拉低,否則拉高為高阻態(tài).            32'hzzzz_zzzz;

10.Macros 宏指令

為了保持代碼的可讀性常用`define做常數(shù)聲明

把`define放在一個獨立的文件中

參數(shù)(parameter)必須在一個模塊中定義,不要傳遞參數(shù)到模塊(仿真測試向量例外);

define可以在任何地方定義,要把所有的define定義在一個文件中(極少的一個兩個define就不用了吧),在編譯源代碼時首先把這個文件讀入.

如果希望宏的作用于僅在一個模塊中,就用參數(shù)來代替.

11.Comments

對更新的內容要做注釋

在語法塊的結尾做標記

每一個模塊都應該在模塊開始處做模塊級的注釋(參考前面的標準模塊頭)

在端口列表中出現(xiàn)的端口信號,都應該做簡要的功能描述.

12.FSM 狀態(tài)機

狀態(tài)機的狀態(tài)分配

Verilog描述狀態(tài)機時必須有parameter分配好狀態(tài).

組合邏輯和時序邏輯分開用不同的進程

組合邏輯包括狀態(tài)譯碼和輸出,時序邏輯則是狀態(tài)寄存器的切換

必須對所有狀態(tài)都處理,不能出現(xiàn)無法處理的狀態(tài),使狀態(tài)機時空

Mealy狀態(tài)機輸出不僅取決于當前狀態(tài),還與輸入有關;Moore狀態(tài)機輸出僅與當前狀態(tài)有關.

Mealy狀態(tài)機的例子如下:

  ...  regCurrentState,NextState,Out1;  parameterS0 =0, S1 =1;  always@(posedgeClkornegedgeRst_)    if(!Rst_)       CurrentState <= S0; ? ? ? ?else? ? ? ? ? ? ?CurrentState <= #u_dly NextState; ? ?always@(In1?or?In2?or?CurrentState) ? ? ? ?case(CurrentState) ? ? ? ? ? ? S0:begin? ? ? ? ? ? ? ? ?NextState <= #u_dly S1; ? ? ? ? ? ? ? ? Out1 <= #u_dly?1'b0; ? ? ? ? ? ?end? ? ? ? ? ? ?S1:begin? ? ? ? ? ? ? ? ?if(In1)begin? ? ? ? ? ? ? ? ? ? ?NextState <= #u_dly S0; ? ? ? ? ? ? ? ? ? ? Out1 <= #u_dly !In2; ? ? ? ? ? ? ? ?end? ? ? ? ? ? ?end? ? ? ? ?endcase

13.Module 編寫示例

/*==============================================================================================*/  Filename      :  module_name.v  Author       :  Dongyi Lin   Description     :    Called by      :  Topmodule  Revision History  : 22-05-27  Revision      : 1.0  Email        :  lindongyi@163.com  Company       :  Hunan Institute of Advanced SensingandInformation Technology,               Xiangtan Univeristy   Copyright      : 2022, Xiangtan University, All right reserved/*==============================================================================================*/modulemodule_name(           Output_ports,   //comment:port description          Input_ports,    //comment:port description          Io_ports,     //comment:port description          Clk_port,     //comment:port description          Rst_port      //comment:port description);//port declarations  output   [31:0]   Dataout;  input   [31:0]   Datain;  inout         Bi_dir_siginal;  input         input1;               input2;     //interrnal wire/reg declarations  wire    [31:0]   internal_data;  reg          output_enable;     //module instantiations, Self-build module  module_name1 Uinstance_name1(                  .port1(...);                  .port2(...);   );     module_name2 Uinstance_name2(                  .port1(...);                  .port2(...);   );    //TSC4000 cell  DTC12V1(      .Clk(Clk),      .CLRZ(Clr),      .D(Data),      .Q(Qout)   );//always block  always@(input2)begin    ...  end//function and task definitions  function[function_type] function_name;     declarations_of_inputs;     [declarations_of_local_variables];    begin      behavirol_statement;       function_name = function_express;    end  endfunction  endmodule

14.Testbench 編寫示例

下面是一個格雷碼的測試模塊:

  module TB_GRAY;   reg       Clock;   reg       Reset;   wire  [7:0]  Qout;   integer fout;      //輸出文件指針   parameter CYC = 20;   GRAY DUT(         .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#(CYC)Clock = ~Clock;   //輸出數(shù)據(jù)到文件gray.dat   always@(posedge Clock)begin     $fwrite(fout,"%d %b
", Qout, Qout);   end endmodule

在testbench中避免使用絕對的時間,如#20,#15或#(CYC + 15)等,應該在文件前端使用parameter定義一些常量,使得時間的定義像#(CYC + OFF0)這樣的形式,便于修改;

觀測結果可以輸出到波形文件GRAY.shm,或數(shù)據(jù)文件gray.dat.生成波形文件可以使用simwave或gtkwave觀測結果,比較直觀;而生成數(shù)據(jù)文件則既可以快速定位,也可以通過編寫的小程序工具對它進行進一步的處理;

對大的設計的頂層方針,一般不要對所有信號進行跟蹤,大的設計波形文件會很大,仿真時間也會延長,可以有選擇的觀測一些信號.

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權轉載。文章觀點僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報投訴
  • 模塊
    +關注

    關注

    7

    文章

    2777

    瀏覽量

    49192
  • Verilog
    +關注

    關注

    28

    文章

    1364

    瀏覽量

    111595
  • 波形
    +關注

    關注

    3

    文章

    386

    瀏覽量

    32043

原文標題:Verilog編寫規(guī)范

文章出處:【微信號:gh_9d70b445f494,微信公眾號:FPGA設計論壇】歡迎添加關注!文章轉載請注明出處。

收藏 人收藏

    評論

    相關推薦
    熱點推薦

    【分享】verilog代碼書寫規(guī)范

    FPGA verilog代碼書寫規(guī)范,很好的借鑒
    發(fā)表于 05-21 11:36

    Verilog HDL代碼書寫規(guī)范

    :① 邏輯功能正確,②可快速仿真,③ 綜合結果最優(yōu)(如果是hardware model),④可讀性較好。2. 范圍本規(guī)范涉及Verilog HDL編碼風格,編碼中應注意的問題, Testbench的編碼
    發(fā)表于 12-08 14:36

    Verilog代碼書寫規(guī)范

    Verilog代碼書寫規(guī)范規(guī)范的目的是提高書寫代碼的可讀性、可修改性、可重用性,優(yōu)化代碼綜合和仿真的結果,指導設計工程師使用
    發(fā)表于 04-15 09:47 ?106次下載

    verilog代碼規(guī)范

    verilog代碼規(guī)范,學會寫代碼還不行,我們需要更加的規(guī)范。
    發(fā)表于 03-25 14:43 ?24次下載

    華為_VERILOG語言編寫規(guī)范

    verilog代碼規(guī)范,學會寫代碼還不行,我們需要更加的規(guī)范。
    發(fā)表于 03-25 14:36 ?34次下載

    Verilog程序編寫規(guī)范

    適合verilog初學者的教程,可以好好參考學習。
    發(fā)表于 03-25 14:06 ?12次下載

    Verilog編寫的基于SPARTAN板的VGA接口顯示程序

    Xilinx FPGA工程例子源碼:Verilog編寫的基于SPARTAN板的VGA接口顯示程序
    發(fā)表于 06-07 14:54 ?10次下載

    Verilog編寫的信道估計

    Xilinx FPGA工程例子源碼:Verilog編寫的信道估計
    發(fā)表于 06-07 14:54 ?38次下載

    華為的verilog編碼規(guī)范

    華為的verilog編碼規(guī)范
    發(fā)表于 11-01 08:41 ?41次下載
    華為的<b class='flag-5'>verilog</b>編碼<b class='flag-5'>規(guī)范</b>

    Verilog程序編寫規(guī)范

    在實際工作中,許多公司對Verilog程序編寫規(guī)范都有要求。在公司內部統(tǒng)一Verilog程序編寫規(guī)范
    的頭像 發(fā)表于 09-15 09:35 ?4207次閱讀

    verilog語言編寫規(guī)范

    規(guī)范的目的是提高書寫代碼的可讀性 可修改性 可重用性 優(yōu)化代碼綜合和仿真的結 果 指導設計工程師使用VerilogHDL規(guī)范代碼和優(yōu)化電路 規(guī)范化公司的ASIC設計輸入從而做到。
    的頭像 發(fā)表于 11-23 17:28 ?1402次閱讀

    基于verilog編寫99秒計數(shù)器

    Verilog語言編寫,通過模塊化設計的99秒技術器
    發(fā)表于 02-16 16:16 ?0次下載

    如何使用參數(shù)化編寫可重用的verilog代碼

    我們將介紹如何使用verilog參數(shù)和generate語句來編寫可重用的verilog 代碼。 與大多數(shù)編程語言一樣,我們應該嘗試使盡可能多的代碼可重用。這使我們能夠減少未來項目的開發(fā)時間
    的頭像 發(fā)表于 05-11 15:59 ?1356次閱讀

    FPGA的Verilog代碼編寫規(guī)范

      注:以R起頭的是對編寫Verilog代碼的IP設計者所做的強制性規(guī)定,以G起頭的條款是建議采用的規(guī)范。每個設計者遵守本規(guī)范可鍛煉命名規(guī)范
    的頭像 發(fā)表于 08-15 16:23 ?2667次閱讀

    IC設計之Verilog代碼規(guī)范

    Verilog規(guī)范對于一個好的IC設計至關重要。
    的頭像 發(fā)表于 08-17 10:14 ?1942次閱讀
    IC設計之<b class='flag-5'>Verilog</b>代碼<b class='flag-5'>規(guī)范</b>

    電子發(fā)燒友

    中國電子工程師最喜歡的網(wǎng)站

    • 2931785位工程師會員交流學習
    • 獲取您個性化的科技前沿技術信息
    • 參加活動獲取豐厚的禮品