1、VerilogHDL程序编写规范2Verilog HDL程序编写规范 版本号: 1.0编写者: 刘兆庆状态: 试用发布日期: 2008年 月 日摘要 本文定义了VerilogHDL RTL编码规则和指南,按照本文介绍的方法进行编码,有助于使VerilogHDL RTL代码具有良好的可读性、可修改性和可重用性,同样也有助于综合和仿真。文档控制表表1 文档控制表文档标题:版本号:发行号:VerilogHDL程序编写规范V1.0实行日期:关键词2008年6月1日编辑工具名称Microsoft Office Word 2003模板:作者情况原作者:刘兆庆协作者:罗杰俊校对:审核: 文档状态表表2 文档
2、状态表标题 VerilogHDL程序编写规范ID号版本号发行号日期更改原因1.002008.03.20试发布1.012008.06.01补充内容目录1 概述 11.1 目的 11.2 所面向的对象 11.3 文档的组织结构 22基本编码规范 22.1命名规范: 22.2源文件中信息头书写规范 42.3注释书写规范 52.4代码书写规范 52.5端口声明规范 62.6端口映射和常量映射 82.7立即数的使用 82.8编辑器 92.9语法规则 92.9.1模块 92.9.2变量 102.9.3参数 112.9.4 function和task 122.9.5其他规则 123时钟和复位信号设计规范 1
3、33.1避免使用混合时钟沿 133.2避免使用时钟缓冲器 143.3避免使用门控时钟 143.4避免在模块内部产生时钟 153.5门控时钟和低功耗设计 153.6避免在模块内部产生复位信号 163.7复位逻辑功能 173.8一位同步器 173.9多位同步器 174可综合性编码规范 184.1寄存器描述 184.2避免产生锁存器 184.3避免产生组合电路反馈。 194.4完整的敏感量列表 204.5阻塞和非阻塞赋值 214.6 case语句和if-else语句 234.7时序逻辑电路的描述 244.8对关键信号的描述 254.9避免使用延时语句 255可综合划分规范 255.1所有输出采用寄存
4、器输出 255.2将相关的组合逻辑放在同一模块 265.3将具有不同设计目标的部分分配到不同模块中 275.4异步逻辑 275.5避免时序设计中的例外情况 275.6消除顶层模块中的胶连逻辑电路 281 概述本文的编码指南基于几个基本原则。最基本的目标是,要求开发出来的RTL代码简单,而且规范。简单且规范的结构比复杂的结构更容易设计、编码、验证和综合。在满足功能和性能的前提下,这个可重用设计的目标是尽可能简单。编码指南详细描述了以下几个值得推荐的建议。 使用简单结构、基本类型和简单的时钟规划; 使用一致的编码方式,一致的命名习惯,一致的过程和状态机; 使用规则的划分方法,所有模块采用寄存器输出
5、,模块大小尽量一致; 为了让RTL代码容易理解,编码中使用注释,使用有意义的命名方式,使用常用或参数代替立即数。在这些原则指导下,开发者能够更容易编码,达到理想的性能、功能、时序、功耗和面积。1.1 目的本文档的目的是定义一个VerilogHDL编码标准,编写VerilogHDL代码时必须遵循该标准的规定。这一标准的提出,可以为VerilogHDL编程者提供以下便利: 避免犯低级错误 便于不同程序员的维护 便于程序的移植和复用 便于阅读和理解 具有一致的书写风格另外请注意,本文档都不能替代VerilogHDL的编程书籍。1.2 所面向的对象本文档面向哈尔滨工业大学自动化测试与控制研究所所有从事
6、VerilogHDL RTL程序编写的人员。1.3 文档的组织结构 文档组织如下:1. 概述;2. 基本编码规范,同时给出解释和例子;3. 时钟和复位信号设计规范,同时给出解释和例子;4. 可综合性编码规范,同时给出解释和例子;5. 可综合划分规范,同时给出解释和例子;2基本编码规范2.1命名规范:在整个设计中一直遵守命名习惯有助于提高代码的可读性,同样也有助于代码的调试、检查、维护和修改。具体规范如下:规则为设计开发命名习惯。以文档的形式规定下来,并在整个设计中一直遵守命名习惯。 指南变量名、模块名、参数和端口名使用小写字母。 指南常数(define)使用大写字母。 指南信号、端口、函数和参
7、数命名时采用有意义的名称。例如,不要用ra命名RAM地址,而应该用ram_addr。 指南对时钟信号使用一致的命名方式,例如clk。如果有一个以上的时钟信号,使用clk作为所有时钟信号的前缀(例如:clk1、clk2或clk_interface等)。 指南对于低有效信号,信号名称尾部用下划线加小写字母n,如_n。 指南对复位信号使用一致的命名方式,如rst。如果复位信号是低有效的,则可以使用诸如rst_n的名称。 规则在描述多个总线时,使用由大到小的位排列顺序。即x : 0或0 : x。使用一致的位排列顺序有助于提高代码可读性,减少总线连接时偶尔发生的位排列顺序不一致的情况,如例1.1所示。例
8、1.1 使用x : 0端口声明 module DW_addinc #( parameter width = 8) ( input width-1 : 0 a, input width-1 : 0 b, input ci, input width-1 : 0sum, output width-1 : 0 co ); endmodule 指南连接的端口与信号使用相同或类似的名称(例如,a = a;或 a = a_int)。 指南模块的端口命名必须根据不同类型选择不同的后缀,命名格式为“*_后缀”,后缀如表1所示。表1 信号命名习惯后缀用法*_a异步信号(例如,addr_strobe_a)*_pn第
9、n段中使用的信号(例如,enable_p2)*_nxt数据在被寄存到相同名称的寄存器之前*_i输入信号*_o输出信号*_n低电平或下降沿有效的信号 如果端口信号具有多个属性,则后缀为多个后缀的任意顺序组合。例如:输入输出信号的后缀应选为“io”或“oi”,模块端口命名的其他规则,和变量命名相同。2.2源文件中信息头书写规范规则在每一个源文件的开始,都必须包含一段注释,信息头部分。脚本文件也是如此。信息头部分必须包含:a. 法律声明,包括机密性、版权、复制时的限制b. 文件名c. 作者d. 模块功能和主要特征描述e. 文件创建日期f. 修改历史记录,包括日期、修改者姓名及对变化的描述例1.2展示
10、了一个源文件头。例1.2 一个VerilogHDL源文件头 / This confidential and proprietary software may be used only as / authorized by a licensing agreement from Synopsys Inc. / In the event of publication, the following notice is applicable. / / COPYRIGHT 1996 SYNOPSYS INC. / ALL RIGHTS RESERVED / / The entire notice abov
11、e must be reproduced on all authorized copies. / / Filename : DWpci_core.v / Author : 张三 / Date : 09/17/96 / Version : 0.1 / Abstract : This file has the entity, architecture and configuration / of the PCI 2.1 MacroCell core module. / The core module has the interface, config, initiator, / and targe
12、t top-level modules. / / Modification History: / Date By Version Change Description /= / 09/17/96 JDH 0.1 Original / 11/13/96 JDH Last pre-Atria changes / 03/04/97 SKC changes for ism_ad_en_ffd_n / and tsm_data_ffd_n / /=2.3注释书写规范 规则使用注释大概地解释一下过程、函数和声明类型。如例1.3所示。例l.3 对子类型声明注释 / Create subtype INTEGE
13、R_256 for built-in error / checking of legal values. subtype INTEGER_256 is type integer range 0 to 255;指南用注释解释端口、信号、变量或一组信号或变量。注释应该放在靠近被解释的代码附近。指南注释采用简单容易理解的英文,不能使用中文(不同的编译器支持的中文字符不同,会产生不能识别的现象)指南全部使用单行注释,只有在开发调试过程中需要注释大段代码时才使用多行注释指南/*/* */.*/ 这种注释在第一个*/处结束,第二个被忽略,而且会产生语法错误,禁止出现此类注释。指南注释应遵循简洁、精炼的原则
14、,禁止使用“注释段”。 指南一些很明显的功能不需要注释,在代码后面,对关键内容注释。指南对过程的注释,放在整个过程的前面,而不是插入过程中,这样可以不中断代码的连贯性。2.4代码书写规范 规则代码按照规定格式书写,可提高代码的可读性和可维护性。指南每行只能写一条代码(声明或语句)。指南每行代码长度最好不要超过72个字符,对于超过72个字符的代码,使用回车符进行分割,在下一行中继续书写上一行的代码。指南使用缩进格式书写条件和循环部分代码,如例1.4所示。例1.4 一个嵌套if语句的缩进格式 if ( bit_width( m + 1) = 2) begin for (i = 0; i bit_w
15、idth(m + 1); i = i +1)begin spin_j = 0; for ( j = i ; j spin_j) begin if (matrix(m)(i - 1)(j) != wht) begin if (j = m & matrix (m)(i)(j) = wht) begin matrix(m)(i)(j) = j; else begin for ( k = j+1; k m; k = k + 1) begin if (matrix(m)(i-1)(k) != wht) begin matrix(m)(i)(k) = j; spin_j = k; end end / k
16、end end end end / j end / iend 指南推荐使用两个空格的缩进格式,如果缩进比较大(例如8格),那么在书写多层嵌套时,可能会遇到每行字长的限制。指南避免使用Tab键,在不同的编辑器中对Tab的设置不一致,可能会引起代码的某种混乱。指南begin必须与if,while,always,initial,for等词同行,end必须另起一行,beginend之间的代码必须具有缩进关系指南在RTL源文件中,不要使用HDL保留字命名任何信号或变量。2.5端口声明规范规则在声明端口时应遵循逻辑顺序,并且在整个设计中保持一致的声明顺序指南每行声明一个端口,紧跟着注释的内容(注释最好在同
17、一行内)。指南对于每个接口,端口声明的顺序如下: 输入(input): 时钟(Clocks) 复位(Resets) 使能(Enables) 其它控制信号(Other control signals) 数据和地址线(Data and address lines) 输出(output): 时钟(Clocks) 复位(Resets) 使能(Enables) 其它控制信号(Other control signals) 数据(Data)例1.5 端口排列顺序 module DW_usbd( / External Clock Generator: Inputs refclk, / Main Referen
18、ce Clock /Scan Test Interface: Inputs scan_mode, / For scan testing / UTMI PHY (type 2/3) Interface: Inputs / Enables phy23_rxvalid, / Specifies the valid data LSB phy23_rxvalidh, / Specifies the valid data on MSB phy23_txready, / Valid data will be polled / Other control signals phy23_linestate, /
19、Current state of dp, dm lines phy23_rxerror, / Error in received data phy23_rxactive, / PHY needs to transmit data / Data and address lines phy23_rx_data, / 16_bit unidir receive data bus / UTMI PHY (type2/3) Interface: Outputs / Reset phy23_reset, / Reset signal to the PHY / Enables phy23_suspend_n
20、, / Suspend signal to the PHY phy23_xcvr_select, / Select HS or FS transceriver / Application Interface: Inputs / Resets app_rst_n, / Asynchronous reset app_test_mode, / Bypassing USB reset / APP Register R/W Interface: Inputs / Enables app_16bit, / APP 16_bit r/w access app_reg_sel, / APP Register
21、Interface select / Other control signals app_rd_n, / APP register-read command app_wr_n, / APP register-write command / Data and address lines app_addr, / APP Register address bus app2usb_data, / APP Write-data bus / APP Register R/W Interface: Outputs / Other control signals usb2app_drdy, / Data re
22、ady indication from / DW_usbd to APP / Data and address lines usb2app_data, / APP Read-Data bus / / / ); / DW_usbd2.6端口映射和常量映射规则使用显式的方式映射端口和常量,保持端口名称之间一一对应,不能使用顺序映射方法。如例1.5所示。例1.6 使用名称对应的映射方法 DW_ram_r_w_s_dff #(.ram_width( ram_data_width + ram_be_data_width), .fifo_depth(fifo_depth), .tco(1) U_int_t
23、xf_ram( .clk (refclk), .rst_n (txfifo_ram_reset_n), .cs_n (1b0), .wr_n (txfifo_wr_en_n), .rd_addr (txfifo_rd_addr), .wr_addr (txfifo_wr_addr), .data_in (txfifo_wr_data), .data_out (txf_ram_data_out) );2.7立即数的使用 指南在设计中,除0和1以外,不能使用立即数值,而使用参数或常量赋值,如例2.1中所示。参数或常量赋值有以下优点, 对于一个设计具有更多的灵活性; 参数或常量值只需要在一个地方修改
24、; 参数可以在实例化时重载,提高模块的可重用性; 编译器可能只支持常量类型,不支持立即数。例1.7 使用参数赋值,不要使用立即数赋值 parameter bus_size = 8; wire bus_size 1 : 0 my_in_bus; reg bus_size 1 : 0 my_out_bus;2.8编辑器 指南建议使用Source Insight软件。2.9语法规则2.9.1模块 指南模块声明使用如下样式:例1.8 模块声明样式 module waveform_generator #( parameter period = 100, /注意缩进两个字符 parameter type
25、= sine )( /注意括号 input hold_i, /注意端口命名 output reg 63:0 value_o ); 指南模块命名与普通变量命名类似指南模块实例的命名建议以模块名的一部分为前缀指南模块实例化时,不能采用按顺序匹配输入输出的方式,而必须使用“.端口名(端口信号)”的方式,参数也必须使用“.参数名(参数值)”方式重新设置参数值,因此模块实例化的格式和其声明的格式相似,例如:例1.9 waveform_generator #( .period (100), .type (sine) ) wg_chnnal_1( .hold_i (hold), .value_o (valu
26、e) ); 指南每一个可以被调用的模块的最后(endmodule之前)必须给出实例化本模块的典型代码,以方便调用者复制,注释形式为/* . */,如:例1.10 /* waveform_generator #( .period (100), .type (sine) ) wg_chnnal_1( .hold_i (hold), .value_o (value) ); */ 指南每一个模块(可综合或行为模块,包括FPGA顶层设计)必须由与之对应的testbench文件,testbench文件命名必须和模块文件名相同,扩展名使用.vt,testbench的顶层模块建议命名为“被测模块名_tb”。指
27、南可综合的模块必须放在一个单独的文件里,且这个文件的文件名必须和这个模块的名字完全相同。只有仿真文件里可以放多个模块,此时文件名应按文件作用取名,命名方法参见变量命名。指南所有模块的仿真时间单位和精度都规定为1ns/1ps,即所有文件的第一条语句必须为“timescale 1ns/1ps”。2.9.2变量 指南每一行至多只能定义一个变量指南变量必须以小写字母打头,只能包含小写字母和数字和用于分隔单词“_”指南变量命名中使用完整单词,除约定缩写以外,约定缩写如下表完整形式缩写OscillatoroscResetrstSynchronoussyncConditionconfManufacturemanfParameterparamClockclkControlctrlConditioncondCountercntrConfigureconfig/cfgInstanceinstchip_selectcs有待添加 指南如果变量的使用范围较大,建议使用对不同类型的变量使用不同的前缀,即以“前缀_”打头,如下表:类型前缀integerirealrrealtimerttimeteventevgenvargvregreg 指南命名必须使用有意义的英文,不得使用拼音指南状态机变量命名建议以“state_”打头,如果模块内
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1