差别

这里会显示出您选择的修订版和当前版本之间的差别。

到此差别页面的链接

后一修订版
前一修订版
硬禾实战营verilog代码规范 [2016/08/03 16:08]
zhijun 创建
硬禾实战营verilog代码规范 [2020/01/17 08:50] (当前版本)
gongyu [2.模板示例]
行 1: 行 1:
 +### 1.RTL CODE 规范
  
-====1.RTL CODE 规范==== 
 ------ ------
-===1.1标准的文件头===+#### 1.1标准的文件头 
 ------ ------
 +
 在每一个版块的开头一定要使用统一的文件头,其中包括作者名,模块名,创建日期,概要,更改记录,版权等必要信息。 在每一个版块的开头一定要使用统一的文件头,其中包括作者名,模块名,创建日期,概要,更改记录,版权等必要信息。
 统一使用以下的文件头:其中*为必需的项目 统一使用以下的文件头:其中*为必需的项目
 +
 <code verilog> <code verilog>
 //​******************************************************** //​********************************************************
行 14: 行 17:
 //   File name       : ​  ​MODULE_NAME.v //   File name       : ​  ​MODULE_NAME.v
 //   ​Module name     : ​  ​MODULE_NAME //   ​Module name     : ​  ​MODULE_NAME
-//   ​Author ​         :   tony-ning+//   ​Author ​         :   STEP
 //   ​Description ​    ​:  ​ //   ​Description ​    ​:  ​
 //   ​Email ​          : ​  ​Author’s email //   ​Email ​          : ​  ​Author’s email
行 23: 行 26:
 // //
 //   ​Modification history //   ​Modification history
-//   ---------------------------------------------------------------------------- +// Version ​      ​Data(2016/08/01)   V1.0 
-//   Version ​        : +// Description
-//   Data(yyyy/mm/dd)   +
-//   Name            : +
-//   Description ​    :+
 // //
 //​************************************************************* //​*************************************************************
 </​code>​ </​code>​
  
-===1.2 标准的module格式 ​===(module 整体结构) +--- 
------- +#### 1.2标准的module格式
-对于模块的书写采用统一的格式便于项目内部成员的理解和维护,我们用批处理建立了一个MODULE模块,其内容解释如下:<​br>​ +
-<​br>?​端口定义按照输入,输出,双向的顺序: +
-?​模块名、模块例化名统一,例化名前加大写U_以区分 ( 多次例化另加标识 ),三者关系: +
-文件名 :xxx .v    (小写) +
-模块名 :XXX ​  ​(大写) +
-例化名 :U_XXX ​ (大写) +
-IP 内部所有的模块名都要加IP名或者IP名简称作前缀,如USB_CTRL、USB_TX_FIFO。+
  
 +对于模块的书写采用统一的格式便于项目内部成员的理解和维护,我们用批处理建立了一个MODULE模块,其内容解释如下:
 +\\ 端口定义按照输入,输出,双向的顺序:
 +\\ 模块名、模块例化名统一,例化名前加大写U_以区分 ( 多次例化另加标识 ),三者关系:
 +\\ 文件名 :xxx .v    (小写)
 +\\ 模块名 :XXX ​  ​(大写)
 +\\ 例化名 :U_XXX ​ (大写)
 +\\ IP 内部所有的模块名都要加IP名或者IP名简称作前缀,如USB_CTRL、USB_TX_FIFO。
 +
 +<code verilog>
 // ***************************** // *****************************
 //  DEFINE MODULE PORT  // //  DEFINE MODULE PORT  //
 // ****************************** // ******************************
 // //
-module ​ MODULE_NAME ​ ​ //​模块名一行 +module ​ MODULE_NAME ​  //​模块名一行 
- ​ //​括号顶格,端口部分换行 + ​ //​括号顶格,端口部分换行 
- // INPUT  ​ //​尽量先输入,后输出定义 + // INPUT   //​尽量先输入,后输出定义 
- input_port_1, ​ //​可同时按接口对象等分类,一行一个+ input_port_1, ​ //​可同时按接口对象等分类,一行一个
  
  input_port_m, ​  input_port_m, ​
行 58: 行 60:
  output_port_m, ​  output_port_m, ​
 ); );
- 
  // *****************************  // *****************************
  //  DEFINE PARAMETER ​   //  DEFINE PARAMETER ​
  // ******************************  // ******************************
- parameter… ​ //​参数名采用大写+ parameter… ​ //​参数名采用大写
  
  // ******************************  // ******************************
  // DEFINE INPUT  // DEFINE INPUT
  // ******************************  // ******************************
- input rst_n ​  ; ​   // reset, (active low) . //​input到寄存器名之间四个tab键,注意对齐 + input rst_n ​  ; ​   // reset, (active low) . //​input到寄存器名之间四个tab键,注意对齐 
- input clk_* ​  ; ​   // clock signal , 50M . //​注意注释的格式,简洁有力,尽量使用英文 + input clk_* ​  ; ​   // clock signal , 50M . //​注意注释的格式,简洁有力,尽量使用英文 
- input ​ [n:0] a_din   ; ​   // ***** //​此处是在模块名部分没有声明端口类型时用 + input ​ [n:0]         ​a_din   ; ​   // ***** //​此处是在模块名部分没有声明端口类型时用 
- input ​ [k:0] b_din   ; ​   // ***** //​注释尽量不要挨到前面,然后全左对齐+ input ​ [k:0]         ​b_din   ; ​   // ***** //​注释尽量不要挨到前面,然后全左对齐
  
  // ******************************  // ******************************
- // DEFINE OUTPUT  ​//+ // DEFINE OUTPUT  ​
  // ******************************  // ******************************
- output ​ [m:0]    a_dout ​  ; ​   // ***** //​位宽定义和output之间加一个tab或空格,统一即可+ output ​ [m:0]    a_dout ​  ; ​   // ***** //​位宽定义和output之间加一个tab或空格,统一即可
  output ​ [i:0]    b_dout ​  ; ​   // *****  output ​ [i:0]    b_dout ​  ; ​   // *****
  
  // ******************************  // ******************************
- // OUTPUT ATRRIBUTE  ​//+ // OUTPUT ATRRIBUTE  ​
  // ******************************  // ******************************
  // REGS  // REGS
行 88: 行 89:
  
  // ******************************  // ******************************
- // INSTSNCE MODULE ​  //+ // INSTSNCE MODULE ​  
  // ******************************  // ******************************
- MODULE_NAME_A ​ U_MODULE_NAME_A( //​例化名从和模块名相距四个tab,括号后换行 + MODULE_NAME_A ​ U_MODULE_NAME_A( //​例化名从和模块名相距四个tab,括号后换行 
- .A (A ), //​端口和例化名对齐,后3个tab再括号连线 + .A (A ),​ //​端口和例化名对齐,后3个tab再括号连线 
- .B (B ), //​括号内3个tab的宽度,全对齐 + .B (B ),​ //​括号内3个tab的宽度,全对齐 
- .C (C ),+ .C (C ),​
  ); …  ); …
  
  // ******************************  // ******************************
- //MAIN CODE  ​//+ //MAIN CODE  ​
  // ******************************  // ******************************
  … …  … …
行 103: 行 104:
  … …  … …
  // ****************************** ​ //  // ****************************** ​ //
-endmodule //​结尾顶格,中间部分均从一个tab开始+endmodule //​结尾顶格,中间部分均从一个tab开始 
 +</​code>​
  
 +---
 +#### 1.3一致的排版
  
-3.一致的排版 +\\ A. 一致的缩排 
-A. 一致的缩排+ 
 +<code verilog>
  //​统一的缩排取4个空格宽度  //​统一的缩排取4个空格宽度
  //​输入输出信号的宽度定义与关键字之间,信号名与宽度之间要用tab分开;所有宽度定义对所有信号名对齐,代码风格统一如下:  //​输入输出信号的宽度定义与关键字之间,信号名与宽度之间要用tab分开;所有宽度定义对所有信号名对齐,代码风格统一如下:
     ​     ​
- input   ​[3:​0] ​  ​ input_a ​ ;    // ***** +    ​input   ​[3:​0] ​  ​ input_a ​ ;    // ***** 
-    input input_b ​ ;    // *****+    input input_b ​ ;    // *****
        …        …
-    output ​ [128:0] output_a ; +    output ​ [128:0] output_a ; 
- output ​ [15:​0] ​ output_b ; +    output ​ [15:​0] ​ output_b ; 
- output output_c ;+    output output_c ; 
 +</​code>​
   
-B.一致的 begin end 书写方式+\\ B.一致的 begin end 书写方式
  
 +<code verilog>
  //always 中,一定要用begin end 区分,格式和代码风格统一如下:  //always 中,一定要用begin end 区分,格式和代码风格统一如下:
  always @ (postedge clk or negedge rst_n)  always @ (postedge clk or negedge rst_n)
行 133: 行 140:
  end  end
  end  end
- //if else 中仅有一个语句行时,不要使用begin end; 如果有多个语句行时,begin end和if ()或else ()空四个格。 + //if else 中仅有一个语句行时,不要使用begin end; 如果有多个语句行时,begin end和if ()或else ()空四个格。 格式如下:
- 格式如下:+
  if  (…)  if  (…)
  
行 149: 行 155:
      end      end
  else  else
-  + </code>
-4. 一致的信号命名风格 +
-//​简洁,清晰,有效是基本的信号命名规则,详见命名规范。+
  
 +---
 +#### 1.4 一致的信号命名风格
 +简洁,清晰,有效是基本的信号命名规则,详见命名规范。
 +^全称 ^缩写  ​       ^中文含义^
 +|acknowledge |ack |应答|
 +|adress |addr(ad)  ​       |地址|
 +|arbiter |arb |仲裁|
 +|check |chk |校验,如CRC校验|
 +|clock |clk |时钟|
 +|config |cfg |Configuration,​装置|
 +|control |ctrl |控制|
 +|count |cnt |计数|
 +|data in |din(di) |数据输入|
 +|data out |dout(do) |数据输出|
 +|decode |de |译码|
 +|decrease |dec |减一|
 +|delay |dly |
 +|disable |dis |不使能|
 +|error |err |错误(指示)|
 +|enable |en |使能|
 +|frame |frm |帧|
 +|generate |gen |生成,如CRC生成|
 +|grant |gnt |申请通过|
 +|increase |inc |加一|
 +|input |in(i) |
 +|length |len |(帧、包)长|
 +|nmport |nm |网管相关|
 +|output |out(o) |
 +|packet不推荐packet |pkt |与帧相同|
 +|priority |pri |优先级|
 +|pointer |ptr |指针|
 +|rd enable |ren |读使能|
 +|read |rd |读(操作)|
 +|ready |rdy |应答信号或准备好|
 +|receive |rx |(帧数据)接收|
 +|request |req |(服务、仲裁)请求|
 +|reset |rst |
 +|segment |seg |
 +|souce |scr |源(端口)|
 +|ststistics |stat |统计|
 +|timer |tmr |定时器|
 +|switcher |sf |Switch fabric|
 +|temporary |tmp |临时|
 +|transmit |tx |发送(帧数据)相关|
 +|Valid |vld(v) |有效、校验正确|
 +|wr enable |wen |写使能|
 +|write |wr |写操作|
  
- 写 中文含义 +\\ a.端口、信号、变量名的所有字母小写:函数名、宏定义、参数定义用大写 
- acknowledge ack 应答 +\\ b.使用简略词(加上列表) 
- adress addr(ad) 地址 +\\ c.基于含义命名(避免以数字命名的简单做法),含义可分段(最多分三段),每一小段之间加下划线”_”,​如tx_data_val;​命名长度一般限制在20个字符以内。 
- arbiter arb 仲裁 +\\ d.低电平有效信号,加后缀”_n”,​如 rst_n 
- check chk 校验,如CRC校验 +\\ e.无条件寄存的寄存信号在原信号上加ff1、ff2… 如原信号 data_in, 寄存一拍data_in_ff1,​寄存两拍data_in_ff2 
- clock clk 时钟 +\\ f.不能用 ”reg”,​作为最后的后缀名,因为综合工具会给寄存器自动加上_reg,​ 如果命名里就用_reg作为后缀名则扰乱了网表的可读性。 
- config cfg Configuration,装置 + 
- control ctrl 控制 +--- 
- count cnt 计数 +### 2.模板示例 
- data in din(di) 数据输入 + 
- data out dout(do) 数据输出 +<code verilog>​ 
- decode de 译码 +//​******************************************************** 
- decrease dec 减一 +// 
- delay dly  +//   ​Copyright(c)2016, ECBC  
- disable dis 不使能 +//   All rights reserved 
- error err 错误(指示) +// 
- enable en 使能 +//   File name       : ​  ​MODULE_NAME.v 
- frame frm 帧 +//   ​Module name     : ​  ​MODULE_NAME 
- generate gen 生成,如CRC生成 +//   ​Author ​         :   ​STEP 
- grant gnt 申请通过 +// Description :   
- increase inc 加一 +//   ​Email ​          : ​  ​Author’s email 
- input in(i)  +//   ​Data ​           :   ​2016/​08/​01 
- length len (帧、包)长 +//   ​Version ​        : ​  ​current versionjust this: v1.0 
- nmport nm 网管相关 +// 
- output out(o)  +//   ​Abstract ​       :    
- packet不推荐packet pkt 与帧相同 +// 
- priority pri 优先级 +//   ​Modification history 
- pointer ptr 指针 +//   ​---------------------------------------------------------------------------- 
- rd enable ren 读使能 +// Version ​      Data(2016/08/01  V1.0 
- read rd 读(操作) +// Description 
- ready rdy 应答信号或准备好 +// 
- receive rx (帧数据)接收 +//​************************************************************* 
- request req (服务、仲裁)请求 +//​******************* 
- reset rst  +//DEFINE(s
- segment seg  +//​******************* 
- souce scr 源(端口) + 
- ststistics stat 统计 +//​******************* 
- timer tmr 定时器 +//DEFINE(s) 
- switcher sf Switch fabric +//​******************* 
- temporary tmp 临时 +//`define UDLY 1    //Unit delay, for non-blocking assignments in sequential logic 
- transmit tx 发送(帧数据)相关 + 
- Valid vld(v) 有效、校验正确 +//​******************* 
- wr enable wen 写使能 +//DEFINE MODULE PORT 
- write wr 写操作+//​******************* 
 +module MODULE_NAME 
 +( 
 + //INPUT 
 + rest_n ​        , 
 + clk_* ​         , 
 + a_din ​         , 
 + b_din ​         , 
 + 
 + //OUTPUT 
 + a_dout ​        , 
 + b_dout 
 +); 
 + 
 + //​******************* 
 + //DEFINE PARAMETER 
 + //​******************* 
 + parameter T1S = 24_999_999;​ 
 + 
 + //​******************* 
 + //DEFINE INPUT 
 + //​******************* 
 + input ​            ​ rst_n ; ​   //reset, active low . 
 + input ​            ​ clk_* ; ​   //clock signal, 50M . 
 + input ​ [n:​0] a_din ; ​   //***** 
 + input ​ [k:0]       ​ b_din ; ​   //***** 
 + 
 + //​******************* 
 + //DEFINE OUTPUT 
 + //​******************* 
 + output ​ ​[m:​0] ​   a_dout ​     ;    //***** 
 + output ​ [i:0]     ​ b_dout ​     ;    //***** 
 + 
 + //​******************** 
 + //OUTPUT ATTRIBUTE 
 + //​******************** 
 + //REGS 
 + reg   ​[m:​0] ​    ​ a_dout ; ​   //***** 
 + 
 + //WIRES 
 + wire  [i:0]      b_dout ; ​   //***** 
 + 
 + //​********************* 
 + //INNER SIGNAL DECLARATION 
 + //​********************* 
 + //REGS 
 + reg   ​[3:​0] ​      ​ counter ​    ; ​   //***** 
 + 
 + //WIRES 
 + wire  [7:0]       ​ temp1 ; ​   //***** 
 + 
 + //​********************* 
 + //​INSTANTCE MODULE 
 + //​********************* 
 + 
 + //​************************************************************** 
 + //instance of module MODULE_NAME_A filename:​module_name_a.v 
 + //​************************************************************** 
 + MODULE_NAME_A ​ U_MUDULE_NAME_A( 
 + .A (A ), 
 + .B (B ),​ 
 + .C (C ) 
 + ); 
 + 
 + //​********************* 
 + //MAIN CORE 
 + //​********************* 
 + 
 + //​Sequential logic style 
 + always@(posedge clk_* or negedge rest_n) 
 + begin : SEQ_BLOCK_NAME 
 + if (rst_n==1’b0) 
 + counter<​=4’b0;​ 
 + else 
 + begin 
 + if (expression) 
 + counter <= #`DLY siginal_b; 
 + else; 
 + end 
 + end // SEQ_BLOCK_NAME 
 + 
 + //​Combinational logic style 
 + always@(signal_a or signal_b
 + begin:​COM_BLOCK-NAME 
 + case (expression) 
 + item1 ​   :begin 
 + signal_c=*****;​ 
 +   end 
 + item2 ​   : //​statement;​ 
 + default ​  ://​statement;​ 
 + endcase 
 + end // COM_BLOCK_NAME
   
- a.端口、信号、变量名的所有字母小写:函数名、宏定义、参数定义用大写 + assign out = expression ? (1’b0):​(1’b1)
- b.使用简称、缩略词(加上列表) + 
- c.基于含义命名(避免以数字命名的简单做法),含义可分段(最多分三段),每一小段之间加下划线”_”,​如tx_data_val;命名长度一般限制在20个字符以内。 + //​********************* 
- d.低电平有效信号,加后缀”_n”,​如 rst_n +endmodule
- e.无条件寄存的寄存信号在原信号上加ff1、ff2… 如原信号 data_in, 寄存一拍data_in_ff1,​寄存两拍data_in_ff2 +
- f.不能用 ”reg”,​作为最后的后缀名,因为综合工具会给寄存器自动加上_reg,​ 如果命名里就用_reg作为后缀名则扰乱了网表的可读性。+
  
-                 + </​code> ​