Verilog编码规范
- 格式:doc
- 大小:210.50 KB
- 文档页数:28
/article.php?type=blog&itemid=781规则#1: 建立时序逻辑模型时,采用非阻塞赋值语句。
规则#2: 建立latch模型时,采用非阻塞赋值语句。
规则#3: 在always块中建立组合逻辑模型时,采用阻塞赋值语句。
规则#4: 在一个always块中同时有组合和时序逻辑时时,采用非阻塞赋值语句。
规则#5: 不要在一个always块中同时采用阻塞和非阻塞赋值语句。
规则#6: 同一个变量不要在多个always块中赋值。
规则#7: 调用$strobe系统函数显示用非阻塞赋值语句赋的值。
规则#8: 不要使用#0延时赋值。
组合逻辑1,敏感变量的描述完备性Verilog中,用always块设计组合逻辑电路时,1.1在赋值表达式右端参与赋值的所有信号都必须在always @(敏感电平列表)中列出, 1.2always中if语句的判断表达式必须在敏感电平列表中列出。
1.3**如果在赋值表达式右端引用了敏感电平列表中没有列出的信号,在综合时将会为没有列出的信号隐含地产生一个透明锁存器。
注:这是因为该信号的变化不会立刻引起所赋值的变化,而必须等到敏感电平列表中的某一个信号变化时,它的作用才表现出来即相当于存在一个透明锁存器,把该信号的变化暂存起来,待敏感电平列表中的某一个信号变化时再起作用,纯组合逻辑电路不可能作到这一点。
综合器会发出警告。
Example1:input a,b,c;reg e,d;always @(a or b or c)begine=d&a&b; /*d没有在敏感电平列表中,d变化时e不会立刻变化,直到a,b,c中某一个变化*/d=e |c;endExample2:input a,b,c;reg e,d;always @(a or b or c or d)begine=d&a&b; /*d在敏感电平列表中,d变化时e立刻变化*/d=e |c;end2, 条件的描述完备性如果if语句和case语句的条件描述不完备,也会造成不必要的锁存器。
Verilog编码规范!一. 强调Verilog代码编写风格的必要性。
强调Verilog代码编写规范,经常是一个不太受欢迎的话题,但却是非常有必要的。
每个代码编写者都有自己的编写习惯,而且都喜欢按照自己的习惯去编写代码。
与自己编写风格相近的代码,阅读起来容易接受和理解。
相反和自己编写风格差别较大的代码,阅读和接受起来就困难一些。
曾有编程大师总结说,一个优秀的程序员,能维护的代码长度大约在1万行数量级。
代码的整洁程度,很大程度上影响着代码的维护难度。
遵循代码编写规范书写的代码,很容易阅读、理解、维护、修改、跟踪调试、整理文档。
相反代码编写风格随意的代码,通常晦涩、凌乱,会给开发者本人的调试、修改工作带来困难,也会给合作者带来很大麻烦。
(实际上英文Coding Style有另一层涵义,更偏重的是,某一个电路,用那一种形式的语言描述,才能将电路描述得更准确,综合以后产生的电路更合理。
本文更偏重的是,编写Verilog代码时的书写习惯。
)二. 强调编写规范的宗旨。
缩小篇幅提高整洁度便于跟踪、分析、调试增强可读性,帮助阅读者理解便于整理文档便于交流合作三. 变量及信号命名规范。
1. 系统级信号的命名。
系统级信号指复位信号,置位信号,时钟信号等需要输送到各个模块的全局信号;系统信号以字符串Sys开头。
2. 低电平有效的信号后一律加下划线和字母n。
如:SysRst_n;FifoFull_n;3. 经过锁存器锁存后的信号,后加下划线和字母r,与锁存前的信号区别。
如CpuRamRd信号,经锁存后应命名为CpuRamRd_r。
低电平有效的信号经过锁存器锁存后,其命名应在_n后加r。
如CpuRamRd_n信号,经锁存后应命名为CpuRamRd_nr多级锁存的信号,可多加r以标明。
如CpuRamRd信号,经两级触发器锁存后,应命名为CpuRamRd_rr。
4. 模块的命名。
在系统设计阶段应该为每个模块进行命名。
命名的方法是,将模块英文名称的各个单词首字母组合起来,形成3到5个字符的缩写。
VerilogHDL编码规范1 目的为了FPGA、芯片IP核开发设计和验证人员之间更好地进行交流,提高代码的可读性,可维护性,特制定本规范,作为程序编写的指导文件。
本规范包括强制性规范和推荐性规范。
2 适用范围FPGA、芯片IP核逻辑设计和仿真验证。
编程语言采用Verilog语言。
3 相关规定1.本规范内容为逻辑设计岗位、仿真验证岗位员工必备基础知识,新员工入职时必须通过参加相关培训掌握本规范。
2.本规范的掌握、执行情况是新员工转正考核的重要内容。
在新员工见习阶段,其内部导师每月须抽查代码并将审核结果填入代码审查表。
3.项目经理应不定期抽查项目成员的代码,并将编程规范执行情况填入代码审查表作为项目成员考核依据。
4.本规范为内部职称晋升考试内容。
1目录1. 严格级别定义 (4)2. 工程规则 (5)2.1. 工程规则表 (5)2.2. 工程规则详细说明 (5)3. 命名规则 (6)3.1. 命名规则表 (6)3.2. 命名规则详细说明 (6)4. 文件头规则 (10)4.1. 文件头规则表 (10)4.2. 文件头示例 (10)4.3. 结构头示例 (12)5. 注释规则 (14)5.1. 注释规则表 (14)5.2. 注释规则详细说明 (14)6. 编码规则 (16)6.1. 编码规则表 (16)6.2. 编码规则详细说明 (16)7. 综合规则 (23)7.1. 综合规则表 (23)7.2. 综合规则详细说明 (23)8. 静态时序分析规则 (27)8.1. 静态时序分析规则表 (27)8.2. 静态时序分析规则详细说明 (27)9. 仿真规则 (31)9.1. 仿真规则表 (31)9.2. 仿真规则详细说明 (31)10. 设计风格规则 (34)210.1. 设计风格规则表 (34)10.2. 设计风格规则详细说明 (34)11. 重用化设计 (38)11.1. 层次设计和模块划分 (38)11.2. 参数化 (40)12. 常用缩写表 (42)31.严格级别定义⏹Mandatory 1(M1)——必须遵守。
Verilog编码规范(仅供内部使用)拟制: xxx 日期:xxx审核:审核者日期:yyyy-mm-dd 批准:批准者日期:yyyy-mm-dd版权所有侵权必究修订记录目录基本原则:简单,一致,可重用。
简单指尽量使用简单的语句,尽量使用简单的设计,尽量使用简单的时钟,尽量使用简单的复位。
一致指尽量保持代码风格一致,尽量保持命名一致。
可重用指有成熟的IP尽量使用IP,设计的代码要尽量可重用。
1命名规范给信号命名就像给孩子取名字一样,有区别,有根源,有深度,还有一点,要简单,别冗长。
有区别指取名字不要一样,假如大家只有一个手机号码,那这个号码还能有什么用处有根源指取名字要能象姓氏一样,让人一看就直到是张家的后代而不是李家的。
有深度就是取名字要有涵义,张一,张二,张三虽然也是名字,但是请考虑一下被取名字人的感受。
简单点,几十个字母长的名字,打字的和看字的都累。
大小写规则:只有parameter,`define和module名称才能享受大写。
Module 名应与文件名保持一致(文件名是小写),假如不想在设计后面遇到麻烦的话。
不要尝试使用任何保留字,因为他们已经被保留了。
不要重复使用同样的名字去命名不同的数据。
(建议)对module名加”_LVx”的后缀,增强module名称的结构层次含义如:设计顶层为TOP LEVEL,即LEVEL1,命名为QTRxxxx_LV1;时钟模块,IO_PAD,CORE,为LEVEL2,命名为CLK_PROC_LV2等等;CORE内子模块为LEVEL3,然后以此类推。
对于来自同一驱动源的所有时钟信号使用相同的名字。
对于低电平有效的信号,应该以_n结尾。
模块间相连端口名称要一致。
(建议)使用下表所列的命名缩写方式。
全称名称clock Clkreset rstclear clraddress addrdata_in din全称名称memory memregister reg(建议)使用下列后缀命名方式全称添加后缀active low_nenable_enselect_selflag_flgdelay_dly信号命名的两个词之间用下划线间隔,如ram_addr,cnt_ctrl 等等信号命名尽量不要使用孤立的、小写的英文字母L2代码编写规范2.1版面语句独立成行,增加可读性和可维护性。
ASIAN MICROELECTRONICS CO.LTDVerilog编码规范From:项目管理部文档编号:AM-PMD038本规范规定了Verilog编码规范,即采用Verilog设计时的代码书写规范,本规范适用于逻辑芯片开发中使用Verilog语言作为RTL级设计语言电路描述规则(注释部分)关键词:Verilog HDL、注释摘要:本文档规定了在用Verilog HDL描述电路时注释要求。
一、在使用Verilog HDL描述电路时,为了增加电路的可读性,必须在电路中加入注释。
为了统一和规范设计,制定该规则。
二、Verilog HDL 模块结构:在用Verilog HDL描述电路时,基本结构如下:{注释1}module [模块名(端口名列表)][参数定义] //{注释2}[端口类型说明]//{注释3}[数据类型说明]//{注释4}{注释5}[描述体部]//{注释6}endmodule三、各部分注释具体要求:1. 注释1:在module 语句以前;建立时间和设计人;ASIAN MICROELECTRONICS CO.LTD修改时间和修改人列表;描述模块的功能;仿真文件名;2. 注释2:参数定义以后。
每行只能定义一个参数;参数的含义;正常情况的取值;3. 注释3:端口类型说明以后。
每行只能说明一个端口;端口的信号含义;4. 注释4:数据类型说明以后。
每行只能说明一个数据;数据的具体含义;修改时间和修改人列表;5. 注释5:在每个always前;描述该块语句完成的功能;6. 注释6:关键的判断语句后;简单描述语句的功能;四、说明:1. 不得使用中文注释;2. 需要时使用参数化设计;3. 模块、端口和变量命名尽可能统一,且意义明确;4. 各描述体功能尽可能明确和单一;5. 对任何需存档的修改必须记录在设计文挡中。
ASIAN MICROELECTRONICS CO.LTD 电路描述规则(代码部分) 大类 编号规则要素 1低电平有效的信号,信号名后缀“_n ” 2模块名小写 // 对AM0202不作要求。
一、工程建立规范:1、工程的组成:(1)一个顶层文件夹(2)顶层文件夹下,至少包括以下四个子文件夹a)project文件夹:存放ISE工程文件,包括ise、bit、mac等文件b)source文件夹:存放verilog源文件c)explain文件件:存放注释说明文档d)test文件夹:存放测试程序代码,可进一步分为软件调试程序、硬件调试程序2、工程的命令:(3)定层文件夹命令为top_xxx,xxx为工程的识别名称(4)顶层文件夹的子文件夹分别命名为:project、source、explain、test二、RTL CODE 规范1.标准的文件头在每一个版块的开头一定要使用统一的文件头,其中包括作者名,模块名,创建日期,概要,更改记录,版权等必要信息。
统一使用以下的文件头:// **************************************************************// COPYRIGHT(c)2005, Hislicon Technologies Co, Ltd// All rights reserved.//// IP LIB INDEX : IP lib index just sa UTOPIA_B// IP Name : the top module_name of this ip, usually, is same// as the small ip classified name just as UTOPIA// File name : file_name of the file just as “tx_fifo.v”// Module name : module_name of this file just as “TX_FIFO”// Full name : complete Emglish nme of this abbreviated//// Author : Athor/ID// Email : Author‟s email// Data :// Version : V 1.0////Abstract :// Called by : Father Module//// Modification history// ------------------------------------------------------------------------------------------------------// //// $Log$//// *********************************************************************2. 标准的module 格式(module 整体结构)对于模块的书写采用统一的格式便于项目内部成员的理解和维护,我们用批处理建立了一个MODULE模块,其内容解释如下:●端口定义按照输入,输出,双向的顺序:●模块名、模块例化名统一,例化名前加大写U_以区分(多次例化另加标识),三者关系:文件名:xxx .v (小写)模块名:Xxx (首字母大写)例化名:U1_xxx (首字母大写)IP 内部所有的模块名都要加IP名或者IP名简称作前缀,如USB_CTRL、USB_TX_FIFO。
VerilogHDL编码规范目录Table of Contents1 范围 (3)2 综述 (3)3 详述 (4)3.1基本格式 (4)3.1.1标准文件头 .......................................................................... 错误!未定义书签。
3.1.2 include (4)3.1.3缩进格式 (4)3.1.4注释 (4)3.1.5保留字 (4)3.2模块与端口 (4)3.2.1模块命名 (4)3.2.2模块例化 (4)3.2.3端口定义 (4)3.2.4输入与输出寄存 (4)3.3信号与变量 (5)3.3.1信号命名 (5)3.3.2向量 (5)3.3.3数据流向 (5)3.3.4 Integer类型 (5)3.3.5位宽匹配 (5)3.3.6内部寄存 (5)3.4时钟与复位 (5)3.4.1时钟复位命名 (5)3.4.2时钟可见性 (6)3.4.3时钟不可做数据输入 (6)3.4.4门控时钟和门控复位 (6)3.4.5全局复位 (6)3.4.6时钟产生 (6)3.5设计风格 (6)3.5.1 if与case (6)3.5.2调试寄存器 (6)3.5.3异步复位 (7)3.5.4时钟事件 (7)3.5.5顶层 (7)3.5.6电路分级 (7)3.5.7资源共享 (7)3.5.8 for语句 (7)3.5.9标准模块 (7)3.5.10参数使用 (7)3.5.11避免SnakePath (8)3.6状态机 (8)3.6.1状态机命名 (8)3.6.2初始状态 (8)3.6.3双进程 (8)3.6.4状态分配 (8)3.6.5无效状态 (8)3.6.6状态机编码 (8)3.7赋值 (8)3.7.1阻塞与非阻塞赋值 (8)3.7.2避免Latch (8)3.7.3一个信号对应一个always (9)3.8 always (9)3.8.1敏感变量 (9)3.8.2边沿触发 (9)3.8.3单时钟(沿) (9)3.8.4避免Latch (9)3.8.5单(组)信号 (9)3.9可靠性 (9)3.9.1异步处理 (9)3.9.2亚稳态 (9)3.9.3异步反馈环路 (9)3.9.4避免Lacth (10)3.10综合 (10)3.10.1综合器开关 (10)3.10.2 for语句 (10)3.10.3运算符 (10)3.10.4移位变量 (10)3.10.5 PLI和TASK (10)3.10.6不可综合的语句 (10)参考文献............................................................................................ 错误!未定义书签。
Verilog编码规(仅供部使用)拟制: xxx 日期:xxx审核: 审核者日期:yyyy-mm-dd 批准: 批准者日期:yyyy-mm-dd所有侵权必究修订记录目录1命名规 (8)2代码编写规 (11)2.1 版面 (11)2.2 编写代码规 (12)3电路设计规则 (26)3.1 时钟 (26)3.2 复位 (27)3.3 避免LATCH (28)3.4 避免组合反馈 (29)3.5 赋值语句 (29)3.6 case语句和if-then-else语句 (29)3.7 状态机 (30)3.8 异步逻辑 (33)4模块划分 (33)5提高可移植性的编码风格 (34)5.1 采用参数化设计 (34)5.2 采用独立于工具平台和工艺库的设计 (35)5.3 尽量使用已经得到验证的IP (36)6其他一些设计建议 (36)7附件 (39)8参考文档: (46)基本原则:简单,一致,可重用。
●简单指尽量使用简单的语句,尽量使用简单的设计,尽量使用简单的时钟,尽量使用简单的复位。
●一致指尽量保持代码风格一致,尽量保持命名一致。
●可重用指有成熟的IP尽量使用IP,设计的代码要尽量可重用。
1命名规给信号命名就像给孩子取名字一样,有区别,有根源,有深度,还有一点,要简单,别冗长。
有区别指取名字不要一样,假如大家只有一个手机,那这个还能有什么用处?有根源指取名字要能象姓氏一样,让人一看就直到是家的后代而不是家的。
有深度就是取名字要有涵义,一,二,三虽然也是名字,但是请考虑一下被取名字人的感受。
简单点,几十个字母长的名字,打字的和看字的都累。
♦大小写规则:只有parameter,`define和module名称才能享受大写。
♦Module 名应与文件名保持一致(文件名是小写),假如不想在设计后面遇到麻烦的话。
♦不要尝试使用任何保留字,因为他们已经被保留了。
♦不要重复使用同样的名字去命名不同的数据。
♦(建议)对module名加”_LVx”的后缀,增强module名称的结构层次含义如:设计顶层为TOP LEVEL,即LEVEL1,命名为QTRxxxx_LV1;时钟模块,IO_PAD,CORE,为LEVEL2,命名为CLK_PROC_LV2等等;CORE子模块为LEVEL3,然后以此类推。
Verilog编码规范(仅供内部使用)拟制: xxx 日期:xxx审核: 审核者日期:yyyy-mm-dd 批准: 批准者日期:yyyy-mm-dd版权所有侵权必究修订记录目录1命名规范 (8)2代码编写规范 (11)2.1 版面 (11)2.2 编写代码规范 (12)3电路设计规则 (26)3.1 时钟 (26)3.2 复位 (27)3.3 避免LATCH (28)3.4 避免组合反馈 (29)3.5 赋值语句 (29)3.6 case语句和if-then-else语句 (29)3.7 状态机 (30)3.8 异步逻辑 (33)4模块划分 (33)5提高可移植性的编码风格 (34)5.1 采用参数化设计 (34)5.2 采用独立于工具平台和工艺库的设计 (35)5.3 尽量使用已经得到验证的IP (36)6其他一些设计建议 (36)7附件 (39)8参考文档: (46)基本原则:简单,一致,可重用。
●简单指尽量使用简单的语句,尽量使用简单的设计,尽量使用简单的时钟,尽量使用简单的复位。
●一致指尽量保持代码风格一致,尽量保持命名一致。
●可重用指有成熟的IP尽量使用IP,设计的代码要尽量可重用。
1命名规范给信号命名就像给孩子取名字一样,有区别,有根源,有深度,还有一点,要简单,别冗长。
有区别指取名字不要一样,假如大家只有一个手机号码,那这个号码还能有什么用处?有根源指取名字要能象姓氏一样,让人一看就直到是张家的后代而不是李家的。
有深度就是取名字要有涵义,张一,张二,张三虽然也是名字,但是请考虑一下被取名字人的感受。
简单点,几十个字母长的名字,打字的和看字的都累。
♦大小写规则:只有parameter,`define和module名称才能享受大写。
♦Module 名应与文件名保持一致(文件名是小写),假如不想在设计后面遇到麻烦的话。
♦不要尝试使用任何保留字,因为他们已经被保留了。
♦不要重复使用同样的名字去命名不同的数据。
Verilog编码规范(仅供内部使用)拟制: xxx 日期:xxx审核: 审核者日期:yyyy-mm-dd 批准: 批准者日期:yyyy-mm-dd版权所有侵权必究修订记录目录1命名规范 (6)2代码编写规范 (8)2.1 版面 (8)2.2 编写代码规范 (8)3电路设计规则 (16)3.1 时钟 (16)3.2 复位 (17)3.3 避免LATCH (18)3.4 避免组合反馈 (18)3.5 赋值语句 (18)3.6 case语句和if-then-else语句 (18)3.7 状态机 (19)3.8 异步逻辑 (20)4模块划分 (21)5提高可移植性的编码风格 (21)5.1 采用参数化设计 (21)5.2 采用独立于工具平台和工艺库的设计 (22)5.3 尽量使用已经得到验证的IP (22)6其他一些设计建议 (22)7附件 (24)8参考文档: (28)基本原则:简单,一致,可重用。
●简单指尽量使用简单的语句,尽量使用简单的设计,尽量使用简单的时钟,尽量使用简单的复位。
●一致指尽量保持代码风格一致,尽量保持命名一致。
●可重用指有成熟的IP尽量使用IP,设计的代码要尽量可重用。
1命名规范给信号命名就像给孩子取名字一样,有区别,有根源,有深度,还有一点,要简单,别冗长。
有区别指取名字不要一样,假如大家只有一个手机号码,那这个号码还能有什么用处?有根源指取名字要能象姓氏一样,让人一看就直到是张家的后代而不是李家的。
有深度就是取名字要有涵义,张一,张二,张三虽然也是名字,但是请考虑一下被取名字人的感受。
简单点,几十个字母长的名字,打字的和看字的都累。
♦大小写规则:只有parameter,`define和module名称才能享受大写。
♦Module 名应与文件名保持一致(文件名是小写),假如不想在设计后面遇到麻烦的话。
♦不要尝试使用任何保留字,因为他们已经被保留了。
♦不要重复使用同样的名字去命名不同的数据。
用于命名的字符集为:字母A ~Z 和a ~z,数字0~9以及下划线组成。
例如:data_busdata_widthclk_48M48M_clkdata__busdata*bus 命名字符集名称不能以数字开头数据总线48M 时钟信号数据位宽不能连续使用下划线不能包含非字母符号*使用有意义的名字,以利于望文生义参数(parameter )、常量(constant )和块标号(block label )名必须一致采用大写;而信号,变量和结构名(construct )以及实例标号(instance )必须一致采用小写。
有利于在仿真时,区分不变和变化的数据。
大小写规则module display_led(clk_48M,//时钟ledout//LED 输出);input clk_48M;//48M 系统时钟output [7:0] ledout;//LED 输出控制reg [22:0] count;//计数器reg [7:0] led_reg;//LED 输出缓存区wire led_clk;//LED 显示时钟控制parameter COUNTER=100;assign led_clk = count[22]; //LED 显示时间控制模块标号小写变量小写常量大写在不区分大小写的情况下,名字必须唯一。
例如,名字state和State不能同时出现在同一设计中,这是因为有的EDA工具不区分大小写。
名字必须唯一module casestatement (a,State,state,dout);input a;input State;input [2:0] state;output dout;reg dout; parameter STATE = 3'bx11; always @(a or b or state)case(state & State)3'b001: dout=a&b;3'b010: dout=a|b;endcaseendmodule 输入信号参数输入信号不同类型的信号命名习惯如果一个名字由多个字组成,则使用下划线连接,用以增加名字的可读性。
版本1.0修改内容初始文档修改人赵文哲时间2022-08维护人:赵文哲E-mail :verilog 语言编码规范本编码规范由西安交通大学人机所电视组全体学生和创芯公司全体员工共同编写和维护。
以此来维护DTV 系列芯片的verilog 源码的可读性,茁壮性和易维护性。
该文档主要致力于verilog 语言的编码标准化,同时也合用于其他相似的硬件描述语言,如VHDL 等。
使代码易于管理的方法之一是增强代码的一致性,让别人读懂自己的代码是非常重要的事情。
因此,保持自己的代码符合统一的规范是一个编码者的基本素质。
如果自己的编码风格与本文档的规定实在不同,无法忍受,请与维护者联系,在组内会议上统一讨论解决方案。
此外,如其他人对该编码规范有任何建议和批评,欢迎联系该规范的维护者。
维护者的联系方式详见首页的维护列表。
关于本文档读者,文档主要规范了verilog 语言的写法和格式,并不介绍verilog 语言的语法。
请读者自己学习verilog 语言的基础知识。
普通而言,项目的文件需要统一的存放在一个统一的文件夹下。
根据各自功能不同,分门别类的存放。
以项目proj-xx 为例,其文件存储方式如表1 所示。
proj-xx|--doc|--datasheet|--specification|--inc|--ip|--sim_utility|--altera_utility|--xilinx_utility|--dc_utility|--rtl|--sim|--proj_sim|--subproj_sim|--softcode|--adc|--dac|--ddr|--probe|--dc|--pt|--fp|--pr|--synplifyverilog 语言编码规范doc:存放项目相关的文档,包括该项目用到的datasheet,芯片规格书(specification) 等等。
inc:存放项目所用到的头文件。
主要是整个项目所用到的整体的定义。
Verilog语⾔编程规范前⾔.................................................................... IV 1范围 (1)2术语 (1)3代码标准 (1)3.1命名规范 (1)3.1.1⽂件命名 (1)3.1.2HDL代码命名总则 (2)3.2注释 (4)3.2.1⽂件头 (4)3.2.2其它注释 (5)3.3编程风格 (7)3.3.1编写代码格式要整齐 (7)3.3.2使⽤⼆到四个空格符缩排 (7)3.3.3⼀⾏⼀条Verilog语句 (7)3.3.4⼀⾏⼀个端⼝声明 (7)3.3.5在定义端⼝时,按照端⼝类型或端⼝功能定义端⼝顺序。
(8) 3.3.6保持端⼝顺序⼀致。
(8)3.3.7声明内部net (8)3.3.8在⼀个段内声明所有内部net (8)3.3.9每⾏长度不超过80字符....................... 错误!未定义书签。
3.3.10代码流中不同结构之间⽤⼀空⾏隔开 (8)3.4模块划分和重⽤ (10)3.4.1不能访问模块外部的net和variable (10)3.4.2不使⽤`include编译指令 (10)3.4.3建议模块的端⼝信号尽可能少。
(10)3.4.4时钟产⽣电路单独构成⼀个模块 (10)3.4.5划分时钟域 (10)3.4.6物理和逻辑边界的匹配 (10)3.4.7特定应⽤代码要单独划分出来 (10)3.4.8关键时序逻辑划分 (10)3.4.9数据流逻辑划分 (11)3.4.10异步逻辑划分 (11)3.4.11状态机划分 (11)3.4.12控制逻辑和存储器划分 (11)3.5逻辑设计经验 (11)3.5.1时钟域要尽可能少,所⽤时钟尽可能加全局BUFF (11) 3.5.2异步接⼝信号同步化 (11)3.5.3避免寄存器的数据与时钟异步 (11)3.5.4使⽤⽆⽑刺的门控时钟使能信号 (11)3.5.5直接作⽤信号⽆⽑刺 (11)3.5.6初始化控制存储元件 (12)3.5.7使⽤同步设计 (12)3.5.8避免组合反馈环 (12)3.6常⽤编程技巧 (12)3.6.1条件表达式的值必须是⼀个单bit值 (12)3.6.2总线位顺序按⾼到低保持⼀致 (12)3.6.3不要给信号赋x值 (12)3.6.4寄存器变量只能在⼀个always语句中赋值 (12)3.6.5对常量使⽤参数⽽不使⽤⽂本宏 (12)3.6.6不能重复定义参数 (12)3.6.7不能重复定义⽂本宏 (12)3.6.8保持常量之间的联系 (12)3.6.9状态编码的参数使⽤ (13)3.6.10`define、`undef配合使⽤ (13)3.6.11⽤基地址+地址偏移量⽣成地址 (13)3.6.12使⽤⽂本宏表⽰寄存器字段位置和值 (13)3.6.13`ifdef的嵌套限制在三层以内 (13)3.6.14操作数的位宽必须匹配 (13)3.6.15模块调⽤时端⼝要显式引⽤ (14)3.6.16⽮量端⼝和net/variable声明的位宽要匹配 (14)3.6.17避免inout类型的端⼝ (14)3.6.18在复杂的表达式中使⽤括号 (14)3.7常⽤综合标准 (14)3.7.1always 的敏感列表要完整 (14)3.7.2⼀个 always 的敏感列表中只能有⼀个时钟 (14)3.7.3只使⽤可综合的结构 (15)3.7.4组合逻辑的条件需完备 (15)3.7.5循环结构中禁⽤disable语句 (15)3.7.6避免⽆界循环 (15)3.7.7端⼝连接禁⽤表达式 (15)3.7.8禁⽤Verilog primitive (15)3.7.9边沿敏感结构中使⽤⾮阻塞赋值(<=) (15)3.7.10Latch使⽤⾮阻塞赋值 (15)3.7.11模块闲置的输⼊端不要悬空 (15)3.7.12连接模块闲置的输出端 (16)3.7.13函数中不要使⽤锁存器 (16)3.7.14禁⽤casex (16)3.7.15多周期路径的信号使⽤单周期使能信号 (16)3.7.16三态元件建模 (16)3.7.17避免顶层胶合逻辑 (16)3.7.18在case语句中使⽤default赋值语句 (16)3.7.19full_case综合命令的使⽤ (16)附录1 HDL编译器不⽀持的Verilog结构 (18)附录2 Verilog和VHDL关键词列表 (19)前⾔编写本标准的⽬的是为了统⼀部门内部FPGA\EPLD设计⽤verilog语⾔编程风格,提⾼Verilog设计源代码的可读性、可靠性和可重⽤性,减少维护成本,最终提⾼产品⽣产⼒;并且以此作为代码⾛查的标准。
一、信号命名规则信号命名规则在团队开发中占据着重要地位,统一、有序的命名能大幅减少设计人员之间的冗余工作,还可便于团队成员代码的查错和验证。
比较著名的信号命名规则当推Microsoft公司的“匈牙利”法,该命名规则的主要思想是“在变量和函数名中加入前缀以增进人们对程序的理解”。
例如所有的字符变量均以ch 为前缀,若是常数变量则追加前缀c。
信号命名的整体要求为:命名字符具有一定的意义,直白易懂,且项目命名规则唯一。
对于HDL设计,设计人员还需要注意以下命名规则。
1.系统级信号的命名系统级信号指复位信号,置位信号,时钟信号等需要输送到各个模块的全局信号。
系统信号以字符串sys或syn开头;时钟信号以clk开头,并在后面添加相应的频率值;复位信号一般以rst或reset开头;置位信号为st或set开头。
典型的信号命名方式如下所示:wire [7:0] sys_dout, sys_din;wire clk_32p768MHz;wire reset;wire st_counter;2.低电平有效的信号命名低电平有效的信号后一律加下划线和字母n。
如:wire SysRst_n;wire FifoFull_n;3.过锁存器锁存后的信号经过锁存器锁存后的信号,后加下划线和字母r,与锁存前的信号区别。
如:信号CpuRamRd信号,经锁存后应命名为CpuRamRd_r。
低电平有效的信号经过锁存器锁存后,其命名应在_n后加r。
如:CpuRamRd_n信号,经锁存后应命名为CpuRamRd_nr多级锁存的信号,可多加r以标明。
如:CpuRamRd信号,经两级触发器锁存后,应命名为CpuRamRd_rr。
二、模块命名规则HDL语言的模块类似于C语言中的函数,可采用C语言函数的大多数规则。
模块的命名应该尽量用英文表达出其完成的功能。
遵循动宾结构的命名法则,函数名中动词在前,并在命名前加入函数的前缀,函数名的长度一般不少于2个字母。
Verilog编码规范2.编写可综合的RTL级Verilog 模块代码时必须遵守的要点:2.1 不允许在代码中出现的语句要点:⚫不允许在可综合的设计代码中使用`Define 来定义参数, 应该使用参数Parameter来定义。
`Define只用于编写不可综合的仿真测试模块。
⚫不允许使用UDP ( 用户定义的原语元件)⚫不允许在可综合代码中出现逻辑反馈环路,否则会生成不可预知的逻辑电路。
⚫只允许用Verilog2001 中的always (*) 来生成组合逻辑,其他Verilog 2001语法在可综合模块中目前都不建议采用。
2.2 建议尽量采用的要点⚫用高电平有效的硬件异步复位reset。
⚫用高电平有效的同步软件复位reset。
⚫尽可能使用高电平有效信号,不使用低电平有效信号(除某些总线、器件有特殊要求外)。
只有复位信号reset 在特定情况下可以设置为低电平有效信号。
⚫尽可能使用assign语句设计组合逻辑。
⚫模块之间数据交换总线应该尽量用多路器实现。
尽量不使用三态总线。
三态总线只用于对外接口或者顶层内部总线。
⚫模块中的每个输出信号原则上必须通过寄存器输出。
任何不通过寄存器输出的信号必须加以注释,注意防止出现反馈回路。
⚫尽量合并源代码,使其简洁明了,不要试图依靠综合器的功能。
⚫case语句和if else语句必须保证其完整性,即所有分支项应该完全列出,case语句应该加缺省项(default),if语句应该有对应的else项。
⚫使用参数(parameter)作为可变化的常数,例如总线的位宽。
⚫端口声明的顺序--在保证先输入再输出的基础上按如下顺序clocks,resets,control signals,address bus,data bus⚫端口和连接端口的信号尽量同名。
⚫注释应尽量靠近被注释的语句。
大段的注释必须用由注释符号组成的边框/////////////// 围绕。
⚫代码中的所有常数都应该使用参数(parameter),将这些参数的定义放在一个独立的文件中,然后在设计模块中用`include 宏命令将其包含。
verilog语言代码设计规范2022年12月目录一、规范适用范围-----------------------------------------错误!未定义书签。
1.1项目适用范围-----------------------------------------------错误!未定义书签。
1.2人员适用范围-----------------------------------------------错误!未定义书签。
1.3编码设计的成果形式-----------------------------------错误!未定义书签。
二、代码书写规范------------------------------------------------------------------32.1模块说明书写规范-----------------------------------------------------------------32.1模块注释书写规范-----------------------------------------------------------------32.3变量名称书写规范-----------------------------------------------------------------42.4代码结构书写规范-----------------------------------------------------------------5三、使用verilog语言的语法范围------------------------------------------63.1设计RTL代码的语法范围-----------------------------------------------------63.2设计仿真代码的语法范围-----------------------------------------------------8四、使用verilog语言的结构范围------------------------------------------94.1系统设计文件的形式与使用方法-----------------------------------------94.2模块结构划分的标准------------------------------------------------------------104.3组合逻辑的代码风格----------------------------------------------------------114.4时序逻辑的代码风格------------------------------------------------------------194.5仿真代码的代码风格------------------------------------------------------------25五、使用受限范围内的语法或结构要进行的申请过程错误!未定义书签。
Verilog编码规范(仅供内部使用)拟制: xxx 日期:xxx审核: 审核者日期:yyyy-mm-dd 批准: 批准者日期:yyyy-mm-dd版权所有侵权必究修订记录目录1命名规范 (6)2代码编写规范 (8)2.1 版面 (8)2.2 编写代码规范 (8)3电路设计规则 (16)3.1 时钟 (16)3.2 复位 (17)3.3 避免LATCH (18)3.4 避免组合反馈 (18)3.5 赋值语句 (18)3.6 case语句和if-then-else语句 (18)3.7 状态机 (19)3.8 异步逻辑 (20)4模块划分 (21)5提高可移植性的编码风格 (21)5.1 采用参数化设计 (21)5.2 采用独立于工具平台和工艺库的设计 (22)5.3 尽量使用已经得到验证的IP (22)6其他一些设计建议 (22)7附件 (24)8参考文档: (28)基本原则:简单,一致,可重用。
●简单指尽量使用简单的语句,尽量使用简单的设计,尽量使用简单的时钟,尽量使用简单的复位。
●一致指尽量保持代码风格一致,尽量保持命名一致。
●可重用指有成熟的IP尽量使用IP,设计的代码要尽量可重用。
1命名规范给信号命名就像给孩子取名字一样,有区别,有根源,有深度,还有一点,要简单,别冗长。
有区别指取名字不要一样,假如大家只有一个手机号码,那这个号码还能有什么用处?有根源指取名字要能象姓氏一样,让人一看就直到是张家的后代而不是李家的。
有深度就是取名字要有涵义,张一,张二,张三虽然也是名字,但是请考虑一下被取名字人的感受。
简单点,几十个字母长的名字,打字的和看字的都累。
♦大小写规则:只有parameter,`define和module名称才能享受大写。
♦Module 名应与文件名保持一致(文件名是小写),假如不想在设计后面遇到麻烦的话。
♦不要尝试使用任何保留字,因为他们已经被保留了。
♦不要重复使用同样的名字去命名不同的数据。
♦(建议)对module名加”_LVx”的后缀,增强module名称的结构层次含义如:设计顶层为TOP LEVEL,即LEVEL1,命名为QTRxxxx_LV1;时钟模块,IO_PAD,CORE,为LEVEL2,命名为CLK_PROC_LV2等等;CORE内子模块为LEVEL3,然后以此类推。
♦对于来自同一驱动源的所有时钟信号使用相同的名字。
♦对于低电平有效的信号,应该以_n结尾。
♦模块间相连端口名称要一致。
♦(建议)使用下表所列的命名缩写方式。
•(建议)使用下列后缀命名方式•信号命名的两个词之间用下划线间隔,如ram_addr,cnt_ctrl等等•信号命名尽量不要使用孤立的、小写的英文字母L2代码编写规范2.1版面♦语句独立成行,增加可读性和可维护性。
♦行的长度保持每行小于或等于72个字符。
因为有的终端或打印机每行不能超过80个字符。
规定72个字符是为了留出边空,提高可读性。
还有一个原因是为象vi这样的编辑器留有显示行号的地方。
用回车来分割超过72个字符的行,并且在下一行用缩进来表示该行是前一行的继续。
♦缩进。
用缩进来提高续行和嵌套循环的可读性。
缩进采用4个空格。
避免使用TAB键。
不同的编辑器或用户环境使得TAB的位置差别很大,造成缩进的混乱。
有一些工具可以将TAB替换成空格。
♦(建议)使用注释使用注释来解释端口、信号、信号组、always块、函数等。
注释应该放在它所描述的代码的附近。
注释应该简明扼要,并足够说明问题。
避免注释杂乱。
显而易见的功能不用加注释。
注释关键是说明设计意图。
2.2编写代码规范♦在源文件中要有文件头在源文件、script文件的开始应包含一个文件头。
文件头至少应包含下列信息:文件名、作者、模块的功能描述和关键特征的列表、文件产生的日期、更改记录(日期、更改者、更改的内容)。
(参见代码模板sample.v)♦模块名称用大写,例如:module MEM_CTRL。
♦端口声明时每行声明一个端口,并有注释(最好在同一行),也可对同一类型的一组端口加注释。
对于时钟,复位以及其他控制信号,需要注释有效工作沿或者有效工作值建议用下述顺序声明端口。
//INPUTsclocks , // posedge activeresets , // active highenables , // active highother control signals ,Data and address lines ,//OUTPUTsclocks ,resets ,enables ,other control signals ,data♦在输入和输出两类端口之间留一个空行来提高可读性。
如上例所示。
♦端口列表之后,使用parameter定义内部信号宽度以及其他参数化设置。
♦IO信号申明和内部信号申明要单独成行,参考sample.v文件♦使用简单的语句,一般使用if … else…和case就能满足大部分需求,不要使用复杂的语句♦常量(1)一位的控制信号采用二进制表达方式,如1'b0;(2)常数位宽不可缺省;如:Bad:if ((rst_n == 0) && (cnt_addr == 15))Good:if ((rst_n == 1'b0) && (cnt_addr == 5'd15))•变量(1)Net and Register(a)一位位宽的wire信号的声明不可缺省(b)一个reg变量只可以在一个always语句中赋值(c)(建议)任一register的赋值加上单位延迟,对异步复位同样加上单位延迟;(d)向量有效位顺序的定义采用倒序格式,如:Data[4:0](2)Memory代码中不建议使用Memory(存储器阵列),Memory只用于Testbench中,访问存储器阵列中某一向量的某一位或几位,需要通过中间变量进行。
例:reg[15:0] mem[0:255];temp = mem[33]; //temp gets data at addr 333_bit_reg = temp[8:6]; //get three bits of addr 33•运算符及表达式(1)表达式(a)用括号来表示执行的优先级,尽管操作符本身有优先顺序,但用括号表示优先级对读者更清晰,更有意义如:Bad: A + B ? C : D;Good: (A + B) ? C : D;(b)适当使用括号适当使用括号可以控制生成的电路结构,如Z = A + B + C + D,综合结果可能为三级加法器,而变换为Z = (A + B) + (C + D),综合结果则可能为两级加法器;(c)注意资源共享需要资源共享的部分一定要放在同一个模块的同一个always语句中,不同模块不同always语句之间的代码不能实现资源共享。
如:always @(...)if (...) d0 = A + B;else d0 = C + D;中,DC可能只会生成一个加法器。
条件算子中不存在资源共享如:z = (cond==1’b1)? (a+b) : (c+d);必须使用两个加法器;而等效的条件if-else语句可以资源共享,如:if (cond==1’b1)z = (a+b);elsez = (c+d);只要加法器的输入端复用,就可以实现加法器的共享,使用一个加法器实现。
(d)尽量采用公共子表达式如:x=a+b+cy=d+a+b改为:z=a+bx=z+cy=d+z(2)算符(a)条件运算符r1 = gate? r2 : r3;避免使用条件嵌套:r1 = (aa = 0)? ((bb == 0)? r2 : r3) : r4; orr1 = {aa,bb} == 0? r2:{aa,bb} == 0? r3:{aa,bb} == 0? R4:r4;(b)逻辑操作符在if(),while(),()?A:B 之类的表达式中,括号中的表达式应该是一个逻辑表达式,相应的操作符应该用逻辑操作符。
如:wire x,A,B;(x) ? A:B 与 (x == 1'b1) ? A:BIf(A&B) 与 if((A&&B)==1’b1)While(A=B) 与 while(A==B)操作结果相同,但显然前者不规范。
(c)乘法运算符“*”对于一个变量data与常数constant相乘data * constant,如果常数不是2的整数次幂,建议先将其分解,如constant= 53 = 32 + 16 + 4 + 1 = 2^5+ 2^4 + 2^2 + 2^0,这样乘积就可以表示为变量data移位结果的相加。
对于乘法运算符“*”,综合后通常得到的是乘法器,时延较大。
•赋值语句(1)不要在信号列表中进行运算操作如:Bad: addr(a,b,d&e);Good: addr(a,b,c); c=d&e;(2)BLOCK赋值和NON-BLOCK赋值的使用(a)组合逻辑采用BLOCK赋值(=)如:always @(dat)i_dat = dat;(b)非组合逻辑(主要是寄存器)采用NON-BLOCK赋值并加delay以保证前仿真和后仿真的一致如:always @(posedeg clk)q <= #`DEL d;(3)在同一块语句中不允许同时出现阻塞赋值和非阻塞赋值•条件语句(1)IF语句(a)向量比较时,比较的向量长度要相等,同样向量和常量比较时长度也要求匹配,长度不同时要求进行显式位扩展(verilog对位数小的向量做0扩展以使它们的长度相匹配,该扩展是隐式的)如:reg [7:0] abc;reg [3:0] def;.......if (abc == {4'b0,def}) begin.......if (abc == 8'h0) begin(b)不要采用if表达式的简写形式例如:if (variable) 等同于 if (variable != 0)if (!variable) 等同于 if (variable == 0)但后者才合乎规范(c)每个if都应该有一个else与之相对应,如果条件为假时不进行任何操作,则用一条空语句else;避免产生latch(d)if...else if...else if...else的代码书写格式如下,要注意优先级if (...)begin......endelsebeginif (...)......else (...)if (...)else (...)end(d)如果变量在if-else语句中非完全赋值,则应给变量一个缺省值如:if (a == b)beginv1 = 2'b01;v2 = 2'b10; //v3 is not assignedendelse if (a == c)beginv2 = 2'b10;v3 = 2'b11; //v1 is not assignedendelse //default赋值beginv1 = 2'b00;v2 = 2'b00;v3 = 2'b00;end(2)CASE语句(a)所有的case语句都应该有一个default语句,避免产生Latch (b)(建议)不要使用casex、casez语句,综合工具不支持•循环语句(1)forever语句(2)repeat语句(3)while语句(4)for语句在可以用其它语句描述电路时,建议不要采用循环语句来描述。