值得收藏的FPGA代码命名规范?

本文转载自:FPGA技术联盟

命名规范

随者FPGA设计的日益复杂,设计实践、方法和流程逐渐成为重要的成功因素。良好的设计能有效影响FPGA设计的性能和逻辑利用,使系统可靠性显著提高,产品可以更快投入到市场。相反,不良的设计可能会导致系统成本较高、性能较低,错过了项目进度,导致设计的不可靠。

持续关注,本篇及随后会提供一些Verilog命名、编码风格及FPGA综合的规则与准则。其指导原则是改善代码的可读性和可移植性,促进代码在不同项目中的复用。

为了提高有效性,规则和准则必须建立正式文档并分发给整个设计团队,还要定期检查代码和审查设计。文件所设计的范围可能会有所不同,对于一家小公司,它是个可接受的命名规范和编码风格的简要说明。在一个大型成熟的公司,它是一套覆盖不同方面的设计实践、方法、过程的文件集。在对可靠性要求极高的设计任务重,如军事或医学应用程序,强调的是严格的编码标准和流程,以防止所有可能的设计失误。该文档对于设计过程的仿真、综合、物理实现及生产等不同阶段都是有用的

该文档的目标具有双重性,一是不同的设计者在同一个项目或者公司内书写的代码具有一致性和相同的外观与感觉,而不管他们的背景和经验。二是提高代码的可读性和清晰度,有助于减少缺陷或错误的数量。

Part 1文件头

很难估计每个源代码和脚本文件中包含文件头的重要性,文件头必须包含正确的版权信息和生命。如果需要,他可以包含简短说明、设计工程师的名字和电子邮箱、版本及对该文件进行更改的列表。文件头存在的最重要原因是版权问题。源代码或脚本文件属于知识产权。文件头表明了所有权,在诉讼、专利纠纷或版权仲裁过程中可用于法庭证据。

下面是一个文件头的例子:


/*--------------------------------------------------------------------------------


Copyright (C) 2011   OutputLogic.com


This source file may be used and distribu ted without


restriction provided that this copyright statement is not


removed from the file and that any deriva tive wOrk contains


the original copyright notice and the associated disclaimer.


THIS SOURCE FILE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS


OR IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE


IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A


PARTICULAR PURPOSE


Filename: top. V


Engineer: John Doe


Description: top-level module


Part 2. Verilog文件组织


在一个文件中实现一个Verilog模块,这是一个良好的设计习惯如下面的代码所示:


// file: my_module.V


module my module;


// module implementation...


endmodule / /  my module


模块的名称应与文件名相匹配。按照这一原则,可以更容易处理和管理项目。例外情况是一个库文件通常包含多个小模块。

Part 3. 文件和目录名

虽然Linux 和 Windows操作系统允许文件和目录名中包括空格和其他特殊字符,但这不是一个良好的设计习惯。使用空格会导致工具软件和脚本语言中出现混乱。Linux的命令行和 shell 用空格分隔字段值,而不是作为文件或信录名的一部分,因此,使用这些实用程序和 shell工具时也应遵守此规则。文件名中包含空格和特殊字符并不总是能工作的,例如当此文件名要通过多个subshell和 pipe 时。

作为规则,文件和目录名中应只使用字母、数字和带下画线的字符。

应尽量给出有助于描述文件内容并且是唯一的文件和目录名。

Part 4. 大写和小写

Verilog和 SystemVerilog语言中的网表、变量、模块、实例和其他名称是区分大小写的。综合工具默认情况下执行该规则。然而,有几个工具选项允许有一定的灵活性。例如,XST提供-case选项,它决定写入最后网表的名称是否使用小写或大写字母,或维持源代码的大小写不变。这个选项是

xst run -case {upper  l  lower  I  maintain}

建议命名参数、宏、常量、类属和枚举类型值时使用大写字母,模块、义件、凶数、实例和任务名称可以是小写字母,不要在名称中将大小写字母混合使用

Part 5. 注释

为了提高代码的可读性,并帮助了解设计意图,鼓励使用有意义的和并非显而易见的注释。注释一致性是一个重要的要求(如观察最大行的大小)。Verilog 允许单行和多行注释。

reg my req;// this is a single-line comment


/*


this is a multi-line comment


/*


例如/***/ 这样的注释风格可用于不同风格中,从而提取文档中使用的注释。


Part 6. 使用tab进行代码缩进


tab主要是用于代码缩进。然而,不同计算机系统上的tab显示方式是不同的。建议配置代码编辑器,以便将tab替换为空格。通常使用4个空格字符代替一个 tab。


Part 7. 换行符


在Windows 操作系统中,代码编辑器使用回车和移行(CR/LF)字符对表示换行。这与UNIX/Linux系统不同,后者只使用LF字符。这种差异会导致在 Windows 中开发的CR字符在UNIX/Linux中显示为^M。此外,一些工具和脚本语言可能由于这些额外字符而导致不正确的结果。


一些代码编辑器提供了 对于换行符只使用LF字符的选项。此外,还有名为dos2unix的实用工具,可用来刪除多余的CR字符。


Part 8. 限制行宽


大部分终端、编辑器和打印机的标准行宽为80个字符。对于不同系统,将行宽限制为80个字符,以使代码更具有可读性。


Part 9. 标识符


两种最流行的HDL标识符的编码风格如下:


1. 大小写混合,没有下画线。每一个字从大写字母开始,连续两个或两个以上的大写字母是不允许的。


reg  MyRegister;


wire MyNet;


wire DataFromCPu; //不正确:连续大写


letters .


2. 全部小写,字与字之间使用下画线。


reg my_ register;


wire my_ net;


wire data_ from cpu;


第二种编码风格越来越普遍,大多数工具和IP核供应商包括Xilinx都采用了这种风格。对于设计者来说, 重要的是在所有开发工具和不同项目中都按照同种风格来书写代码。


Part 10. 转义标识符


Verilog标准提供了一种将任何 可打印ASCII字符包含在标识符中的方法。这样的标识符从反斜线转义字符(\)开始,以空格、tab或换行符结束。前面的反斜线和最后的空格不是标识符的一部分。


转义标识符可用于在标识符中使用特殊字符的自动代码生成器、ASIC 网表及其他CAD工具,广泛应用于各种Xilinx内核生成的代码中。FPGA设计者应注意避免使用转义标识符,因为它们会降低代码的可读性,并导致很难找到错误,如键入错误的尾随空格。


下面是一个Xilinx移位寄存器核使用转义标识符的例子。其中在标识符结束与分号或括号之间还有一个空格。


module shift_ ram coregen (input sclr,ce,c1k,


input [0 : 0] d,


output[0:0]q);


wire \BU2/sinit ;


wire \BU2/sset ;


wire \BU2/U0/i bb inst/Mshreg_ fl.only_ clb.srl_ _sig 62_  1 _ 9;


wire \BU2/U0/i bb inst/Mshreg_ fl.only_ clb.srl_ _sig 62_  0 _ 8;


wire \BU2/U0/i_ _bb_ inst/N1 ;


wire \BU2/U0/i_ _bb_ inst/NO;


wire \BU2/00/1 bb inst/f1.only_ clb.srl siq 62 _5 ;


wire NLW_ VCC_ P_ UNCONNECTED;


wire NLW GND G_ UNCONNECTED:


wire[0:0]d_2;


wire [0: 0] q_3;


wire [3 : 0] \BU2/a;


assign d _2[0] = d[0], g[0] = q_ 310];


VCC_0 (.P(NIW vCc P UNCONNECTED) )


GND GND_1 (.G(NLW GND G _UNCONNECTED)


FDE #(.INIT ( 1'b0 ))


\BU2/U0/i_ bb. inst/f1.only. clb. sr1


_sig_ 62(.C(clk) .


.CE(ce),


. D(\BU2/00/i_ bb_ inst/Mshreg_ f1.only_ clb.sr1 sig 62_ 1 _9 ),


.Q(\BU2/00/i_ bb_ inst/fl.only cib.srl sig 62_ 5 ) ) ;


endmodule


Part 11. 前缀名


可以使用一个有特定含义的名称前缀,对信号、寄存器或其他标识符进行分类。例如,所有存储器控制器中的信号可以用“mem_”作为名称前缀。


Part 12. 后缀名


后缀名可以用来为信号、寄存器或其他标识符提供相关的额外信息。例如,“p”或“n”后缀可以表示正极性或负极性。表1提供了几个后缀名的例子。


Part 13. 时钟名称


时钟信号的名称要能描述出对象的特征,包括频率和其他特征,如单端或差分时钟。作为惯例,将“clk”"用做时钟名称的部分。以下是几个时钟信号名称的例子。


wire clk50; //单端50 MHz时钟


wire clk_ 200_ _P,clk_ 200 n; //200 MHz差分时钟


wire clk_ _en; //时钟使能


wire clk_ 333_ mem; // 333 MHz存储器控制器时钟


Part 14. 复位信号名称


复位信号名称可以包括复位极性(高或低有效)、同步或异步、全局或局部信息。以下是几个复位信号名称的例子。


reg reset, phy_ reset; // 高电平有效复位


reg reset_ n, reset_ _b; // 低电平有效复位


reg rst_ async; // 异步复位


Part 15. 端口名称


端口名称可用于表示端口方向,以后缀结束,如下面例子所示。


input [9:0]  addr_ i; // 输入


Input  [31:0] DataI; // 输入


output write_ enable_ o; //输出


Inout   [31:0] data_ io; //双向


Inout  [31:0] ConfigB; //双向


Part 16. 模块名称


无论模块例化在哪个层次,模块名称在整个项目中是唯的。Veilog或SystermVerilog的关键字不应该用于模块名称。


Part 17. 文字


Verilg提供了一套丰富的选项来指定文字。可以将文字指定为简单的整数。或作为带基数的整数(例如6'd32)。


指定整数的语法是


<size>' s<base><value>


字段确定文字值代表的整个位数。这是一个可选字段,如果没有给出,默认大小是32位。


“s”字段确定带符号值的 一进制补码。这是一个可选字段, 如果没有提供,认为该值是无符号数。


< base >字段确定给定的值是否为二进制、八进制、十进制或十六进制。如果没有确定,则默认文字为十进制。


< value >字段确定文字的整数值。


简单的文字整数默认为带符号数。带基数的文字整数默认为无符号数,除非明确使用“s”字段确定为带符号数。


建议描述文字时使用基本规范,以避免引人错误。例如,使用6'd32而不是32。


一个比较常见的错误是< size >和< value>不匹配。例如,使用5'd32不会造成任何综合错误,但将32(二进制’b00000)的最高有效位舍去,结果将成为0,如果比它大,将进行左扩展,如下面的例子所示。


wire [7:0] my_ value;


assign my_ value =' b0; //左扩展为8'h0o


assign my_ value = 'bl; //左扩展为8'h01


Verilog定义了用于赋值和其他操作符的不同文字位数处理的一些规则与方法。这些规则与方法避免了潜在问题的出现,参考文献[ 1]中给出了详细的介绍。


Part 18. 参考文献


[1] “Standard Gotchas: Subtleties in the Verilog and SystemVerilog Standards That EveryEngineer Should Know", by Stuart Sutherland. Published in the proceedings of SNUGBoston, 2006. 

http://www.sutherland-hdl.com/papers/2007-SNUG-SanJose gotcha again paper.pdf   

最新文章