(免费)[VHDL+Verilog]良好的代码编写风格(二十五条)
- 格式:doc
- 大小:25.00 KB
- 文档页数:2
VHDL代码书写规范(定稿)文件编号:编制:审核:可靠性审核:标准化:批准:文件会签页文件历史记录文件编号现行版本V1.0 文件标题VHDL代码书写规范文件履历版次编制日期更改内容(条款)V1.0V1.0目录1.目的 (1)2.范围 (1)3.术语说明 (1)4.书写规范 (1)4.1命名规范 (1)R1.一个文件只包含一个模块,文件命名和实体命名必须相同。
文件名大写,其后缀小写。
(1)R2.顶层文件命名方式使用工程名、器件型号与_TOP结合。
顶层文件的元件实例化,后缀使用_module;第二层文件的元件实例化,后缀使用_block;第三层之后不做定义(若遇到常见的基本逻辑电路或子模块,如:SRAM、FIFO等,那么优先使用具有代表性的名称) (1)R3.代码编写之前,以文档的方式,根据功能分类,分别对FPGA的外部端口进行命名约定。
(2)R4.命名要有实际意义。
(2)R5.命名标识符的首字符必须是字母,包含多个单词的标志符单词之间使用下划线分开。
信号、变量等的命名最后字符也一定要求是字母,中间的可以是数字或者其他合法符号。
(2)R6.模块、信号、变量等的命名不大于64个字符 (2)R7.实体、结构名、端口信号、常量用大写标识 (2)R8.行为级、结构级和数据流级结构命名分别以“BEH_实体名”、“STR_实体名”和“RTL_实体名”区分。
如果是混合使用,或者是分不清使用了那一种结构,那么就是用“ARC_实体名”命名。
(3)R9.单口RAM模块命名以SPRAM作后缀;双口RAM模块命名以DPRAM作后缀;ROM模块命名以ROM作后缀;FIFO模块命名以FIFO_作后缀;数字时钟管理模块命名以DCM作后缀;锁相环模块命名以PLL作后缀;乘法模块命名以MULT作后缀;除法模块命名以DIV作后缀;加法模块命名以ADD作后缀;减法模块命名以SUB作后缀。
(3)R10.模块实例化时,采用‘Un_xx_元件名’标识,cell实例化时使用‘Mn_xx_元件名’标识。
verilog的代码规范和coding风格想要成为一名优秀的数字IC设计工程师需要哪些基本的专业知识呢?如下:1.半导体物理学、半导体器件物理学、基本的固体物理、半导体工艺与制造等物理学知识;2.电路分析、模拟电子线路、COMS模拟集成电路、专用集成电路基础等模拟IC知识;3.信号系统、数字信号处理、信道编码、通信原理等通信知识;4.C语言、汇编、C++、脚本(shell、tcl、perl)、Linux(我觉得如果懂kernel那就更好了)、体系结构、组成原理等计算机知识;5.各种EDA和编程调试工具的使用Modelsim、Debussy、quartus ii、Cadence、DC、vim等等(就数字方向而言用的最多的5种左右,模拟另当别论);另外虚拟机什么的总得玩得转吧!6.当然最重要的还是我们亲爱的--verilog,不会verilog(当然VHDL也是一样的)那你会别的也算不上优秀的Digital IC Engineer!verilog语法并不复杂,只是初学者容易犯一些“类C”错误,总会不经意间将verilog写成了C语言,或者是没有使用并行思想,或者就是多处赋值等等问题。
如果我们克服了之前的一些小毛病,在这些之外,我们想更近一步提升自己的写代码水平、研发水平,而不是只做一个码农的话那么我们要做的就是:第一步:提高代码规范性,每个企业、研究所可能都有自己的一套代码书写规范,但是总的来说都有一些共性,而且往往这些共性的地方还特别多,一个没有代码规范的程序员不可能写出非常漂亮和优秀的程序,当然有了规范的代码后也不一定就能写出漂亮和优秀的程序,这是两码事。
代码规范之后的一个境界我觉得是优良的编程风格,编程风格不同于代码规范,编程风格在verilog中特别指代那些逻辑上的风格,同样的功能,使用不同的编程风格,代码综合面积可能是几倍的关系,这一点我深有体会,另外,人们不经意间的编码习惯可能会导致许多冗余代码,在verilog综合之后,这些冗余就会成为实实在在多出来的不必要的电路,他们或者是寄存器或者是没用的组合逻辑,虽然往往DC一类的综合工具会对代码综合进行优化,并且会根据综合脚本进行最大化的优化计算,但是工具毕竟是工具,他不可代替人类,很多冗余电路综合工具并没有办法进行优化,因为工具并不知道你的本意,也不可完全进行语意预测,而不必要的电路意味着更多的流片成本,更低的work效率和更多的功耗消耗,这些都不是我们想看到的,所以一个好的coding风格本身对于企业来说就是非常大的价值!!!当然我认为要培养良好的coding风格并不是一件容易的事,本身 verilog design == 电路设计,透过代码看电路这个能力并不是一蹴而就的,这需要我们的长期的学习和思考总结,就像模拟设计一样,往往这是一种经验!。
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开发代码风格积累1、always块代码风格(1)⼀个always块内最好只对同⼀个变量进⾏赋值;(2)同⼀个信号不要在不同的always块中进⾏赋值,这样的好处是,当修改⼀个变量的赋值,不会影响其他变量,逻辑更清晰,更适⽤于代码量⼤的⼯程;当有需要时,可使⽤间接赋值的⽅法,即在⼀个always中设⼀个flag,另⼀个always中通过判断这个flag来进⾏赋值;(3)不是同⼀类的信号,最好分开在不同的always块中进⾏赋值操作,可增强代码的可维护性和可读性。
2、RTL可综合代码中尽量不⽤for循环级代码中。
每个变量独⽴占⽤寄存器资源,不能有效复⽤逻辑资源。
for循环可以⽤在描述测试激励的⽂件中,for循环不要⽤在可综合的RTL级代码中可综合电路中遇到循环算法时,通常做法是先搞清楚设计的时序要求,做⼀个reg型计数器,在每个时钟沿累加,并在每个时钟沿处判断计数器情况作出相应处理。
3、关于FPGA中乘法除法逻辑实现FPGA中,⼀般不⽤*和/实现乘法和除法,原因*乘法在FPGA综合时,⼀类是使⽤FPGA设备⾃⾝的硬件乘法实现,但是FPGA硬件乘法块个数有限,不能滥⽤;⼀类是使⽤组合逻辑以逻辑门的⽅法实现,会消耗⼤量组合逻辑资源。
可以使⽤FPGA⾃带的乘法器IP核,或者⾃⼰花费逻辑资源,使⽤硬件描述语⾔设计效率较⾼的软乘法器。
4、if条件列表中尽量少写多位宽数据if条件列表会转换成查找表(查找表是FPGA中组合逻辑实现的基本单元,查找表使⽤多了会增加组合逻辑时延),所以在if条件列表中尽量少写多位宽数据。
5、关于新旧版本的模块接⼝声明最好不⽤旧的Verilog1995版本声明输⼊输出接⼝,建议使⽤新的Verilog2001版本规范声明输⼊输出接⼝,⽐如:module fsm(input wire sclk,input wire rst_n,output reg K);6、关于变量的声明位置变量声明区域,否则可能不建议在模块内部语句的中间穿插定义/声明变量,变量的定义和声明最好都集中在紧挨接⼝下⾯的变量声明区域导致编译器编译错误。
个人总结Verilog代码编写的25条经验1、对所有的信号名、变量名和端口名都用小写,这样做是为了和业界的习惯保持一致;对常量名和用户定义的类型用大写;2、使用有意义的信号名、端口名、函数名和参数名;3、信号名长度不要太长;4、对于时钟信号使用clk 作为信号名,如果设计中存在多个时钟,使用clk 作为时钟信号的前缀;5、对来自同一驱动源的信号在不同的子模块中采用相同的名字,这要求在芯片总体设计时就定义好顶层子模块间连线的名字,端口和连接端口的信号尽可能采用相同的名字;6、对于低电平有效的信号,应该以一个下划线跟一个小写字母b 或n 表示。
注意在同一个设计中要使用同一个小写字母表示低电平有效;7、对于复位信号使用rst 作为信号名,如果复位信号是低电平有效,建议使用rst_n;8、当描述多比特总线时,使用一致的定义顺序,对于verilog 建议采用bus_signal[x:0]的表示;9、尽量遵循业界已经习惯的一些约定。
如*_r 表示寄存器输出,*_a 表示异步信号,*_pn 表示多周期路径第n 个周期使用的信号,*_nxt 表示锁存前的信号,*_z 表示三态信号等;10、在源文件、批处理文件的开始应该包含一个文件头、文件头一般包含的内容如下例所示:文件名,作者,模块的实现功能概述和关键特性描述,文件创建和修改的记录,包括修改时间,修改的内容等;11、使用适当的注释来解释所有的always 进程、函数、端口定义、信号含义、变量含义或信号组、变量组的意义等。
注释应该放在它所注释的代码附近,要求简明扼要,只要足够说明设计意图即可,避免过于复杂;12、每一行语句独立成行。
尽管VHDL 和Verilog 都允许一行可以写多个语句,当时每个语句独立成行可以增加可读性和可维护性。
同时保持每行小于或等于72 个字符,这样做都是为了提高代码得可读性;13、建议采用缩进提高续行和嵌套语句得可读性。
缩进一般采用两个空格,如西安交通大学SOC 设计中心2 如果空格太多则在深层嵌套时限制行长。
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设计源代码的可读性、可靠性和可重⽤性,减少维护成本,最终提⾼产品⽣产⼒;并且以此作为代码⾛查的标准。
最流行的硬件设计语言,VHDL和Verilog比较
当前最流行的硬件设计语言有两种,即VHDL 与Verilog HDL,两者各有优劣,也各有相当多的拥护者。
VHDL 语言由美国军方所推出,最早通过国际电机工程师学会(IEEE)的标准,在北美及欧洲应用非常普遍。
而Verilog HDL 语言则由Gateway 公司提出,这家公司辗转被Cadence所购并,并得到Synopsys的支持。
在得到这两大EDA 公司的支持后,也随后通过了IEEE 标准,在美国、日本及中国台湾地区使用非常普遍。
我们把这两种语言具体比较下:
1.整体结构
点评:
两者结构基本相似,并行语句的种类也类似;
VHDL语言需要进行大量说明,程序通常比较长;
Verilog HDL通常不进行说明,或只进行非常简短的说明,程序比较简短。
2.数据对象及类型
VHDL
常量信号变量 9种预定义类型各类用户定义类型
可描述各类不同的量
必须进行类型说明
运算时必须考虑类型的一致性和适用性
Verilog HDL
常量:数量,参量
变量:网络型寄存器型
类型种类少
运算时所受的约束少
3.运算符号。
verilog语句编译Verilog语言是一种硬件描述语言(HDL),用于描述数字系统的行为和结构。
它被广泛应用于数字电路设计、验证和仿真。
下面是一些常用的Verilog语句及其用法,以帮助读者更好地理解Verilog语言的编程技巧和应用场景。
1. 模块声明语句:module module_name(input signals, output signals);// Verilog模块的声明语句,定义模块的输入和输出信号2. 信号声明语句:reg signal_name; //定义一个寄存器信号wire signal_name; //定义一个线网信号// 信号声明语句用于定义Verilog模块中的信号类型和信号名称3. 连接语句:assign output_signal = input_signal1 & input_signal2;// 连接语句用于将输入信号与输出信号相连接,实现信号的传输和处理4. always语句:always @(posedge clk) begin// 在上升沿时执行的代码块end// always语句用于定义在特定事件发生时需要执行的代码块,常用于时钟触发的行为描述5. if语句:if (condition) begin// 条件满足时执行的代码块end else begin// 条件不满足时执行的代码块end// if语句用于根据条件执行不同的代码块,实现条件判断和分支控制6. case语句:case (signal)value1: begin// signal等于value1时执行的代码块endvalue2: begin// signal等于value2时执行的代码块enddefault: begin// signal不等于任何一个value时执行的代码块endendcase// case语句用于根据信号的取值执行相应的代码块,实现多路选择和条件判断7. for语句:for (i = 0; i < N; i = i+1) begin// 循环体内的代码块end// for语句用于实现循环执行的代码块,常用于遍历数组或执行固定次数的操作8. 常量声明语句:parameter WIDTH = 8;// 常量声明语句用于定义一个常量,常用于定义模块中的参数和宏定义9. 位拼接语句:assign output_signal = {input_signal1, input_signal2};// 位拼接语句用于将多个信号按位拼接成一个大信号,常用于数据的组合和传输10. 实例化语句:module_nameinstance_name(.input_signal1(input1), .input_signal2(input2), .output_signal(output));// 实例化语句用于在模块中实例化另一个模块,将输入和输出信号进行连接以上是一些常用的Verilog语句及其用法,通过合理的使用这些语句,可以实现复杂的数字系统设计和验证。
VHDL代码书写规范1目 次135.1.12 Comments ........................................................135.1.11.1 FSM 使用规定................................................135.1.11 FSM 有限状态机................................................135.1.10.2package 使用注意内容...........................................125.1.10.1 package 使用建议..............................................125.1.10 package ..........................................................125.1.9.1 generic 使用注意内容............................................125.1.9 类属( generics)......................................................125.1.8.2 procedure 使用注意内容..........................................125.1.8.1 procedure 使用规定..............................................125.1.8 procedure ..........................................................115.1.7.3 function 使用注意内容...........................................115.1.7.2 function 使用建议...............................................115.1.7.1 function 使用规定...............................................115.1.7 function ..........................................................115.1.6.2比较运算符规定................................................115.1.6.1 表达式书写规定................................................115.1.6 运算符(operator)....................................................115.1.5.3 VHDL 语句使用注意内容.........................................105.1.5.2 VHDL 语句使用建议............................................75.1.5.1 VHDL各语句使用规定.............................................75.1.5 语句..............................................................65.1.4.3 实体使用注意内容 ...............................................65.1.4.2 实体使用建议...................................................45.1.4.1 实体结构体使用规定 ...........................................45.1.4 实体..............................................................45.1.3.3 信号变量使用注意内容..........................................45.1.3.2 变量使用建议...................................................45.1.3.1 信号不许赋初值...............................................45.1.3 信号和变量.........................................................45.1.2.3 数据使用注意内容 ...............................................35.1.2.2 数据及数据类型使用建议 .........................................35.1.2.1类型使用规定...................................................35.1.2数据对象和类型......................................................35.1.1.6 信号命名有关建议...............................................25.1.1.5 信号名一致性规定...............................................25.1.1.4 信号名缩写的大小写规定..........................................25.1.1.3 信号名连贯缩写的规定............................................25.1.1.2标识符大小写规定................................................25.1.1.1标识符定义命名规定 ..............................................25.1.1 标识符Identifiers)命名习惯............................................15.1 VHDL 编码风格. (15)规范内容..................................................................14引用标准和参考资料.........................................................13定义.....................................................................12范围.....................................................................11目的 (2)216.5 参数化元件实例.........................................................206.4 程序包书写实例.........................................................196.3 函数书写实例..........................................................176.2 VHDL 编写范例.........................................................176.1 VHDL 保留字.. (166)附录....................................................................155.2.5 多赋值语句案例三态总线............................................155.2.4 避免使用Latch ......................................................155.2.3 考虑综合的执行时间.................................................145.2.2组合逻辑描述的多种方式..............................................145.2.1 资源共享问题......................................................145.2 代码编写中容易出现的问题................................................135.1 代码模块划分..........................................................135.1.13 TAB 键间隔.......................................................135.1.12.1 Comments 使用建议.. (3)VHDL代码书写规范1目的本规范的目的是提高书写代码的可读性可修改性可重用性优化代码综合和仿真的结果指导设计工程师使用VHDL规范代码和优化电路规范化公司的ASIC/FPGA设计输入从而做到逻辑功能正确可快速仿真综合结果最优可读性较好2范围本规范涉及VHDL编码风格规定编码中应注意的问题VHDL代码书写范例等本规范适用于所有的采用VHDL代码进行设计的项目3定义VHDL Very high speed IC Hardware Description Language, 甚高速集成电路的硬件描述语言FSM Finite Status Machine,有限状态机simulate仿真通过输入激励在计算机上验证设计是否正确包括RTL仿真和门级仿真模拟是指对一个物理器件的结构功能或其他特性如延时特性等用抽象的语言或高级语言如用C语言进行算法描述所进行的建模4引用标准和参考资料下列标准包含的条文通过在本标准中引用而构成本标准的条文在标准出版时所示版本均为有效所有标准都会被修订使用本标准的各方应探讨使用下列标准最新版本的可能性VHDL For Programmable LogicMr,Kevin ShahillUSA5规范内容以下内容中有关的保留字用黑体标识对不作为审核的内容用建议字眼标识5.1 VHDL编码风格本章节中提到的VHDL编码规则和建议适应于 VHDL的任何一级RTL behavioral,gate_level)也适用于出于仿真综合或二者结合的目的而设计的模块5.1.1 标识符Identifiers)命名习惯1标识符用于定义实体名结构体名信号和变量名等选择有意义的命名对设计是十分重要的命名包含信号或变量诸如出处有效状态等基本含义下面给出一些命名的规则包括VHDL语言的保留字5.1.1.1标识符定义命名规定y标识符第一个字符必须是字母最后一个字符不能是下划线不许出现连续两个下划线y基本标识符只能由字母数字和下划线组成y标识符两词之间须用下划线连接如Packet_addr, Data_in, Mem_wr, Mem_cey标识符不得与保留字同名VHDL保留字见附录6.15.1.1.2标识符大小写规定y对常量数据类型实体名和结构体名采用全部大写y对变量采用小写y对信号采用第一个词首字符大写y保留字一律小写5.1.1.3信号名连贯缩写的规定长的名字对书写和记忆会带来不便甚至带来错误采用缩写时应注意同一信号在模块中的一致性一致性的缩写习惯有利于文件的阅读理解和交流部分缩写的统一规定为Addr address Clk clock Clr clear Cnt counterEn enable Inc increase Lch latch Mem memoryPntr pointer Pst preset Rst resetReg register Rd reader Wr write常用多个单词的缩写ROM RAM CPU FIFO ALU CS CE自定义的缩写必须在文件头注释5.1.1.4信号名缩写的大小写规定y单词的缩写若是信号名的第一个单词则首字符大写如Addr_in中的Addr 若该单词缩写不是第一个单词则小写如Addr_en 中的eny多个单词的首字符缩写都大写不管该缩写在标识符的什么位置如RAM_addrRd_CPU_en5.1.1.5信号名一致性规定同一信号在不同层次应保持一致性5.1.1.6信号命名有关建议2y建议用有意义而有效的名字能简单包含该信号的全部或部分信息如输入输出信息Data_in总线数据输入Din单根数据线输入FIFO_outFIFO 数据总线输出如宽度信息Cnt8_q8位计数器输出信号的命名y建议添加有意义的后缀使信号名更加明确常用的后缀如下芯片的双向信号_xbio 芯片的三态输出_xz 芯片的漏极开路输出_xod 芯片原始输出信号_xo 芯片原始输入信号_xi 求反的信号_n 使能控制信号_en 实体端口信号的反馈信号_s_L 后加数字表示信号延迟时钟周期数如_L1_L 连到三态输出的信号_z寄存器的数据输出信号_q 寄存器的数据输入信号_d 时钟信号_clk 意义后缀说明1. 采用D 触发器对信号进行延迟延迟信号的命名在原信号名之后加后缀_L,若是在流水线设计中有级延迟再分别加后缀_L1_L2.....L 表示lock2. 模块内的反馈信号在原信号名之后加后缀_ss 表示 same5.1.2数据对象和类型5.1.2.1类型使用规定yVHDL 是很强的类型语言可综合的数据类型为标量类型包含可枚举类型整型浮点型物理类型和组合类型包含记录数组模拟模型的数据类型为存取类型文件型可综合的VHDL 代码的编写不采用模拟类型浮点型物理类型y不同基本类型的数据不能由另一类型赋值不同类型间的赋值需使用运算符的重载如Cnt8_q 为STD_LOGIC_VECTOR 类型若不对 ‘+’ 运算符重载则 Cnt8_q <= Cnt8_q + 1 语句在综合中将出错可通过对 + 运算符进行重载 即使用use IEEE .std_logic_arith.all 语句则上句赋值语句是正确的y常量名和数据类型必须用大写标识符表示5.1.2.2 数据及数据类型使用建议y 为改善代码的可读性建议可把常用的常量和自定义的数据类型在程序包中定义y建议使用别名来标识一组数据类型有利于代码的清晰如signal AddrSTD_LOGIC_VECTOR(31 downto 0);alias Top_addrSTD_LOGIC_VECTOR(3 downto 0) is Addr(31 downto 28)5.1.2.3 数据使用注意内容3可枚举类型的值为标识符或单个字母的字面量是区分大小写的如 Z 与z 将是两个不同的量5.1.3 信号和变量5.1.3.1信号不许赋初值5.1.3.2变量使用建议变量主要用在高层次的模拟模型建模及用于运算的用途但变量的综合较难定义对于编写可综合的VHDL模块在没有把握综合结果情况下建议不使用5.1.3.3信号变量使用注意内容y在VHDL中信号(signal)代表硬件连线因此可以是逻辑门的输入输出同时信号也可表达存贮元件的状态端口也是信号y在进程process中信号是在进程结束时被赋值因此在一个进程中当一个信号被多个信号所赋值时只有最后一个赋值语句起作用如下例Sig_p process(A B CbeginD <= A----- ignored!!X <= C or DD <= B---- overrids !!Y <= C xor Dend上面实际的结果是 B赋值给D C xor B结果赋值给X Yy变量不能表达连线或存贮元件变量的赋值是直接的非预设的变量将保持其值直到对它重新赋值如下例Ver_p process(A B Cvariable d STD_LOGICbegind = AX <= C or dd = BY <= C xor dend process实际结果是 X <= C or A Y<= C xor B5.1.4 实体5.1.4.1实体结构体使用规定y library IEEE use IEEE.std_logic_1164.all除IEEE大写外其余小写4y实体名和结构体名必须用大写标识实体名必须与文件名同名自定义的其他标识符如信号名变量名标号等不得与实体名结构体名同名y实体端口数据模式不准使用buffer模式缓冲模式主要用在实体内部可读的端口如计数器的输出为简化大型设计各模块间接口的配合要求不要使用需要反馈的信号可定义内部信号来解决如计数器端口Count 可内部定义信号 signal Cnt8_q STD_LOGIC_VECTOR(7 downto 0)Cnt8_q 该信号可在内部反馈最后通过赋值语句Count <= Cnt8_q 来实现端口的定义y实体端口数据类型规定实体端口的数据类型采用IEEE std_logic_1164 标准支持的和提供的最适合于综合的数据类型STD_ULOGIC STD_LOGIC和这些类型的数组不采用IEEE 1076 /93 标准支持和提供的BITBIT数组INTEGER及其派生类型这是为保证模拟模型和综合模型的一致性及减少转换时间和错误y一个文件只对应一个实体实体是设计文件的基本单元其书写规范要求如下y一条语句占用一行每行应限制在80个字符以内y如果较长超出80个字符则要换行y代码书写要有层次即层层缩进格式清晰美观y要有必要的注释25%y实体开始处应注明文件名功能描述引用模块设计者设计时间及版权信息等如-- Filename ﹕-- Author ﹕-- Description ﹕-- Called by ﹕Top module-- Revision History ﹕99-08-01-- Revision 1.0-- Email ﹕ M@--Company ﹕ swip Technologies .Inc--Copyright(c) 1999, swip Technologies Inc, All right reservedlibrary IEEE;use IEEE.std_logic_1164.all;entity ENTITY_NAMEport(Port1 : in STD_LOGIC;Port2 : in STD_LOGIC;5Port3 : out STD_LOGIC;..Portn : out STD_LOGIC);end ENTITY_NAME ;architecture BEHAVIOR of ENTITY_NAME isbeginStatements;end BEHAVIOR ;5.1.4.2 实体使用建议y实体名的命名建议能大致反映该实体的功能如COUNTER88位宽的计数器模块DECODER383-8线译码器模块y行为级的结构体名命名为 BEHAVIOR 结构级的结构体名命名为STRUCTURE若有多个结构体用后缀A B...... 命名如architecture BEHAVIOR of COUNTER8 isbegin.....end BEHAVIOR;y一个实体可以有多个结构体对单个结构体的实体文件要包含结构体和实体说明便于查阅对多个结构体的实体建议把常用的结构体放在文件中其余结构体用单独文件表示使用时用configuration语句进行配置y结构体的描述分为行为级描述数据流描述和结构化描述若无特殊要求建议采用行为级描述和数据流的描述不采用结构化描述或BOOLEAN数据流的描述y VHDL设计中如果可以避免采用器件厂商的专用元件库硬Core则尽量不要使用除非只有采用该库元件才能实现你设计的性能指标这是因为要充分利用VHDL独立于工艺且易于维护的优点5.1.4.3 实体使用注意内容y VHDL设计应是层级型的设计VHDL设计实体由实体说明和结构体组合而成实体是一个设计的基本单元模块即顶层的设计模块由次一级的实体构成每个次一级实体又可由再下一层次的实体构成最低层模块可以是表达式或最基本的实体模块构成这种设计方法就是Top-To-down 的设计方法y实体端口模式为in out buffer inout模式为in的信号不能被驱动模式out的信号不能用于反馈同时必须仅被一个信号所驱动缓冲模式的端口不能被多重驱动除非用决断函数解决外同时仅可以连接内部信号或另一个实体的缓冲模式的某个端口y VHDL设计各模块接口定义时要考虑模块间配合的方便如实体端口的模式端口的数据类型等65.1.5语句5.1.5.1 VHDL各语句使用规定y with-select-when语句书写规范规定with- select - when语句提供选择信号赋值是根据选定信号的值对信号赋值代码的书写规范为with selection_signal selectSelect_name <= value_a when value_1_of_selection_signalvalue_b when value_2_of_selection_signalvalue_c when value_3_of_selection_signal.......value_x when last_value_of_selection_signaly with- select - when语句的selection_signal的所有值必须具备完整性若没写完整必须有一个others语句如下三个写法其综合的效果是一致的因为S的元素不是已知的逻辑值X将不被定义但对RTL仿真而言其结果是不一致的这是因为RTL仿真支持多值元素with S selectX <= A when “00”,B when “01”,C when “10”,D when others;with S selectX <= A when “00”,B when “01”,C when “10”,D when “11”,D when others;with S selectX <= A when “00”,B when “01”,C when “10”,D when “11”,“--” when others;建议不使用第三种写方法y with- select - when语句中对有相同的支项可合并书写如X <= A when “00” | “10”y when_else语句书写规范规定7when_else 语句提供为条件信号赋值即一个信号根据条件被赋一值代码书写规范为Signal_name <= value_a when condition1 elsevalue_b when condition2 elsevalue_c when condition3 else........value_xy当条件是表达式时表达式须用括起来使代码更为清晰如when a = b and C= 1elsey if必须有一个else对应除在如下面例子的情况下可不写else语句例process( Clk,Rst)beginif ( Rst = '1') thenQ <= '0';elsif ( Clk ‘event and Clk = ‘1’) thenQ <= D;end if;end process;当没有else语句时将产生不希望的存储器y case-when语句书写规范规定该语句用于规定一组根据给定选择信号的值而执行的语句可用with-select-when语句等效代码的书写规范为case- selection_signal iswhen value1_of _selection signal =>Statements1;when value2_of _selection signal =>Statements2;....when last_value_of _selection signal =>Statements x ;when others =>Statements x;end case;y case_when语句必须有when others支项y若信号在if-else或case-when语句作非完全赋值必须给定一个缺省值y process显示敏感列表必须完整对有Clk 的 process不同综合工具有不同的要求有些只要写Clk和Rst就可建议根据具体情况简化设计书写y有clk的process的敏感列表中为方便修改敏感列表书写规范如下Lab process Clk, Rstlist1list2,....beginy每个process前须加个labley不同逻辑功能采用不同的process进程块把相同功能的放在同一进程中如触发器组进程块D_p : process(Clk,Rst,D1,D2,...,Dn)beginif (Rst = '1' ) thenQ1 <= '0' ;Q2 <= '0' ;...Qn <= Dn;elsif (Clk 'event and Clk = '1') thenQ1 <= D1;Q2 <= D2;...Qn <= Dn;end if;end process;y generate语句书写规范规定在需要重复生成多个器件如多个器件的重复例化时使用生成机构可简便代码书写如下32位总线的三态缓冲器的例化Gen_lab1: for I in 0 to 31 generateinst_lab: threestate port map(Din => Value(i),Rd => Rd,Dout => Value_out(i));end generate;y生成机构必须有一个标号如上的Gen_lab1y if-then用在生成机构中不能有else或elsif语句如下复杂的生成机构语句G1for I in 0 to 3 generateG2for j in 0 to 7 generateG3if (I <1 ) then generateUa : thrst port map( Val(j),Rd,Val_out(j));end generate;G4if (i = 1) then generate .......y port map语句书写规范规定Uxx Module_nameport mapport1 => port 1,port2 => port2,.....portn => port n)y为便于阅读port map采用名字对应=>映射方法y port map中总线到总线映射时X downto Y要写全y向量采用降序方法即 X downto Y 格式向量有效位顺序的定义为从大数到小数y port map的module 设计者自编写的entity名用Uxx标识cell如厂家提供的库元件RAM Core等名用Vxx 标识5.1.5.2 VHDL 语句使用建议y作为可综合的代码编写-值建议不用如下一个代码with tmp selectX <= A when “1---”,B when “-1--”,C when “--1-”,D when “---1”,0when others该代码在RTL级仿真中不会出错但在综合过程中可能编译出错视综合工具而定y由于不同综合工具支持能力问题建议不采用wait语句即不使用隐式敏感表5.1.5.3 VHDL 语句使用注意内容y when_else语句具有优先级第一个when条件级别最高最后一个最低可用顺序语句的if-else替代书写时必须考虑敏感路径y当信号的值为不相关的值时最好用选择信号赋值语句如多路选择器当信号的值为相关时选用when-else语句如编写优先编码器y注意If--elsif---elsif---else的优先级最后一个else 优先级最低必须把关键路径放在优先级高的语句中5.1.6 运算符(operator)5.1.6.1 表达式书写规定为便于理解用表示逻辑运算符执行的优先级如X <= ( A and B ) and ( C or not D)建议运算操作符两边都加上空格如5.1.6.2比较运算符规定向量比较时比较的向量的位宽要相等否责会引起warning或error除非重载等值比较运算符调用numeric_std 库5.1.7 function5.1.7.1 function 使用规定y function代码书写规范规定function FUNCTION_NAME (参数1参数类型参数2参数类型.......return返回类型isbegin顺序语句end实例见附录6.35.1.7.2function 使用建议y函数主要用于类型的转换或重载运算符的定义对于使用IEEE1164标准的面向综合的VHDL设计采用std_logic 类型不必考虑与bit类型的转换可调用 numeric_std 标准程序包实现类型转换和 + 运算符的重载建议少用厂家提供的函数或自定义的类型转换函数y对多次重复的表达式可用一个函数来定义5.1.7.3function使用注意内容y函数参数只能是输入类型不能被赋值修改y只能有一个返回值y定义函数必须为顺序语句且其中不能定义新的信号但可在函数说明域中说明新的变量并在定义域中对其赋值y函数在结构体说明域中或程序包中定义见附录6.35.1.8 procedure5.1.8.1 procedure使用规定y procedure 书写规范规定procedure PROCEDURE_NAME signal参数名模式类型signal参数名模式类型... isbegin过程体end procedure5.1.8.2 procedure使用注意内容y过程用于数值运算类型转换运算符重载或设计元件的最高层设计结构y过程参数缺省模式为in5.1.9 类属( generics)5.1.9.1 generic使用注意内容y类属为传递给实体的具体元件的一些信息如器件的上升下降沿的延时信息对应类属为rise fall用户定义的数据类型如负载信息对应类属为load及数据通道宽度信号宽度等y对大型设计建议使用类属来构造参数化的元件其调用的方法为Uxx : 参数化的实体名generic map实参port map (端口映射表见附录6.5y若元件的类属在定义时已经指定默认值在调用时若不改变该参数值可不用定义实参的映射即map实参可不写5.1.10 package5.1.10.1 package使用建议y对大型设计建议把全局的常量如数据宽度等指令状态编码元件组函数和子程序组分别用元素包器件包函数包来构造如通过调用元件程序包实体的结构体说明区域中就不必再对调用的器件进行component说明y程序包通过use语句使之可见可通过保留字all使包中所有单元都可见如use work..yourpacketname.all;其中yourpacketname是你的packet名5.1.10.2package使用注意内容y程序包包括程序包说明和可选包体程序包说明用来声明包中的类型元件函数和子程序包体则用来存放说明中的函数和子程序y不含有子程序和函数的程序包不需要包体见附录6.4y程序包中的类型常量元件函数和其他说明对其他设计单元是可见的5.1.11 FSM有限状态机5.1.11.1 FSM 使用规定y VHDL 的FSM为双进程的有限状态机即组合逻辑进程定义次态的取值时序逻辑进程定义时钟上升沿来时次态成为现态y VHDL的FSM 不必为状态分配而用行为级的枚举类型定义状态根据需要在综合时选择状态的分配方式如 one-hot 或二进制编码y状态机在上电时必须明确进入一个初始状态y必须包括对所有状态都处理不能出现无法处理的状态不能使状态机进入死循环5.1.12 Comments5.1.12.1 Comments 使用建议y对更新的内容尽量要做注释y模块端口信号要做简要的功能描述y语法块做简要介绍5.1.13 TAB键间隔对TAB键的间隔我们建议采用4个字符这与许多软件的缺省设置是一致的并且VHDL语言中大多数保留字也是4个字符5.1 代码模块划分模块设计的好坏直接影响着系统的设计好坏模块设计的不好会给后面的设计流程带来许多麻烦设计模块的基本原则是1.有利于模块的可重用性模块设计得好可节省大量的重复工作并且为以后的设计带来方便2.在组合电路设计中应当没有层次可提高代码的可读性另外一方面是综合的时候方便并且时序较易满足3.每个模块输出尽量采用寄存器输出形式这样设计是有利于时序的满足4.模块的按功能进行划分划分要合理5.模块大小应适中不能太大也不能太小一般为2000门左右具体情况应当依据综合工具的性能而定6.模块的层次应当至少有三级可将一个设计划分为三个层次TOP MID功能COREy TOP包括实例化的MID和输入输出定义如果用综合工具插入管脚则可不要此层次y MID由两部分组成1时钟产生电路如分频电路和倍频电路2功能CORE的实例化y功能CORE包括各种功能电路的设计一个复杂的功能可以分成多个子功能来实现即再划分子层5.2代码编写中容易出现的问题5.2.1资源共享问题资源共享的主要思想是通过数据缓冲或多路选择的方法来共享数据通路的工作单元在VHDL设计中资源共享必须与敏感路径问题进行综合考虑后采用适当的设计方法如R <= ( A + B) when (Source = ‘1’) else( C + D)综合工具可综合成以下两种情况当在综合工具选中Resource Sharing 时将资源共享一个加法器这时A B C或D到R是关键路径如果关键路径是Source 到R则不要要求资源共享需要资源共享时可改成如下写法建议采用该方式R <= A when (Source = ‘1’) elseC;S <= B when (Source = ‘1’) elseD;F <= R + S;5.2.2组合逻辑描述的多种方式对组合逻辑的描述有多种方式其综合结果是等效的以4bit的与门为例C <= A and B;等效于C3 <= A3and B3C2 <= A2and B2;C1 <= A1and B1;C0 <= A0and B0;等效于for I in 3 downto 0 loopC i< = A i and B i;end loop;可以选择简洁的写法.5.2.3 考虑综合的执行时间通常会推荐将模块划分得越小越好事实上要从实际的设计目标面积和时序要求出发好的时序规划和合适的约束条件要比电路的大小对综合时间的影响要大要依照设计的目标来划分模块对该模块综合约束的scripts也可以集中在该特性上要选择合适的约束条件过分的约束将导致漫长的综合时间最好在设计阶段就做好时序规划通过综合的约束scripts来满足时序规划这样就能获得既满足性能的结果又使得综合时间最省5.2.4 避免使用Latch使用Latch必须有所记录不希望使用Latch时应该对将条件赋值语句写全如在if语句最后加一个else case语句加others不完整的if和case语句导致不必要的latch的产生下面的语句中DataOut会被综合成锁存器如果不希望在电路中使用锁存器它就是错误process Cond)beginif (Cond = ‘1’) thenData_out <= Data_inendend process5.2.5多赋值语句案例三态总线一根总线上挂多个三态电路时必须用多个进程来表示如Tri_p1: process (Sel_a,A)beginif (Sel_a = ‘1’) thenT <= A;elseT <= ‘Z’;end if;end process;Tri_p2: process (Sel_b,B)beginif (Sel_b = ‘1’) thenT <= B;elseT <= ‘Z’;end if;end process;为什么不能在一个process中进行处理呢如下所示Error : process (Sel_a,A,Sel_b,B)beginif (Sel_a = ‘1’) thenT <= A;elseT <= ‘Z’;end if;if (Sel_b = ‘1’) thenT <= B;elseT <= ‘Z’;end if;end process;这是因为上述两个if语句彼此没有优先级又由于是对同一个信号信号T进行处理则后一个处理会覆盖前一个处理正确的做法是将这两个if语句放在两个process中进行注意只有三态电路才可以在多个process中出现其它非三态电路若是在多个process中出现的话有的综合工具会报告短路错误即多驱动问题但在语法检查时不一定报错6附录6.1 VHDL保留字VHDL语言的保留字如下absaccess after alias all and architecture array assert attribute begin block buffer bus case component configuration constantdisconnect downto else elsif end entity exit file for functiongenerate generic group guarded if impure in inertial inoutis label library linkage literal loop map mod nand new next nor not null of on open or others out package portpostponed procedure process pure range record register reject remreport return rol ror select severity signal shared sla sll sra srl subtype then to transport type unaffected units until usevariablewait when while with xnor xor另外对不同的厂家也有相应的保留字要求可参见相应厂家提供的资料6.2 VHDL 编写范例-- Filename ﹕Div5.vhd-- Author ﹕zhouzhijian-- Description ﹕Five division-- Called by ﹕Top module-- Revision History ﹕99-08-01library IEEE;use IEEE.std_logic_1164.all;use IEEE.std_logic_unsigned.all;use IEEE.std_logic_arith.all;entity DIV5 isport(Rst: in STD_LOGIC;Mclk: in STD_LOGIC;Div5_clk: out STD_LOGIC);end DIV5;architecture BEHAVIOR of DIV5 issignal Cnt3_q: STD_LOGIC_VECTOR(2 downto 0);signal Cnt3_d: STD_LOGIC_VECTOR(2 downto 0);signal Div0: STD_LOGIC;signal Div1: STD_LOGIC;beginCnt_pd : process(Cnt3_q)beginif (Cnt3_q = “100”) thenCnt3_d <= “000”;elseCnt3_d <= Cnt3_q + 1;end if;end process;Cnt_pq : process(Rst,Mclk)beginif (Rst = '1') thenCnt3_q <= "000";elsif (Mclk = '1' and Mclk'event) thenCnt3_q <= Cnt3_d;end if;end process ;Div0_P : process(Rst,Mclk)beginif (Rst = '1') thenDiv0 <= '1';elsif( Mclk = '1' and Mclk'event ) thenif (Cnt3_q = "100") thenDiv0 <= '1';elsif (Cnt3_q = "001") thenDiv0 <= '0';elseDiv0 <= Div0;end if;end if;end process ;Div1_P : process(Rst,Mclk)beginif (Rst = '1') thenDiv1 <= '0';elsif (Mclk = '0' and Mclk'event) thenDiv1 <= Div0;end if;end process ;Div_clk <= Div0 or Div1;end BEHAVIOR;建议用双进程来实现带有复杂的同步复位置位的寄存器信号设计如上计数器的写法对Div0也可类似地书写6.3 函数书写实例以下是一个使用多表决函数的全加器-- Filename ﹕FullAdd.vhd-- Author ﹕suwenbiao-- Description ﹕A example of function-- Called by ﹕Top module-- Revision History ﹕99-08-01library IEEE;use IEEE.std_logic_1164.all;use IEEE.std_logic_unsigned.all;entity FULLADD isport(A: in STD_LOGIC;B: in STD_LOGIC;Carry_in: in STD_LOGIC;Sum: out STD_LOGIC;Carry_out: out STD_LOGIC);end FULLADD;architecture BEHAVIOR of FULLADD isfunction Majority (A,B,C : STD_LOGIC)return STD_LOGIC isbeginreturn (( A and b) or (A and C) or ( B and C ));end Majority;beginSum <= A xor B xor Carry_in;Carry_out <= Majority(A,B,Carry_in);end BEHAVIOR;6.4 程序包书写实例-- Filename ﹕My_pkg.vhd-- Author ﹕suwenbiao-- Description ﹕A example of Package-- Called by ﹕Top module-- Revision History ﹕00-03-18library IEEE;use IEEE.std_logic_1164.all;package MY_PKG is-- Defined constantconstant NUM64K : integer := 65636;constant EXT_RAM_ADD_WIDTH : integer := 16;constant HW_NUM : integer := 4;constant CELL_OUTPUT_CHANNEL_WIDTH : integer := 5;constant INPUT_CHANNEL_WIDTH : integer := ADDRESS_BUS_WIDTH;constant QUEUE_WIDTH : integer := 5;constant WORD_LENGTH_WIDTH : integer := 6;--Define subtypeconstant QUEUE_OVERFLOAT_WIDTH : integer := 16;subtype QUEUE_OVERFLOAT_VECTOR isSTD_LOGIC_VECTOR(QUEUE_OVERFLOAT_WIDTH-1 downto 0);--Defined Reg groupcomponent Rddf1port(Clk: in STD_LOGIC;Rst: in STD_LOGIC;D: in STD_LOGIC;Q:out STD_LOGIC);end component;component Rreg1port(Clk: in STD_LOGIC;Rst: in STD_LOGIC;Load: in STD_LOGIC;D: in STD_LOGIC;Q:out STD_LOGIC);end component;component Rreggeneric(Size: integer := 2);port(Clk: in STD_LOGIC;Rst: in STD_LOGIC;Load: in STD_LOGIC;D: in STD_LOGIC_VECTOR( Size - 1 downto 0);Q:out STD_LOGIC _VECTOR( Size - 1 downto 0));end component;end Reg_pkg;6.5 参数化元件实例-- Filename ﹕Reg_group.vhd-- Author ﹕suwenbiao-- Description ﹕A example of Reg Group with generic size-- Called by ﹕Top module-- Revision History ﹕00-03-18library IEEE;use IEEE.std_logic_1164.allentity REG_GROUP isgeneric (Size : integer : = 2);port(Clk: in STD_LOGIC;Rst: in STD_LOGIC;Load: in STD_LOGIC;D:in STD_LOGIC_VECTOR(Size - 1 downto 0);Q: out STD_LOGIC_VECTOR(Size - 1 downto 0) );end REG_GROUP;architecture BEHAVIOR of REG_GROUP isbeginR_p: process(Clk,Rst)beginif (Rst = ‘1’) thenQ <= (others => ‘0’) ;elsif(Clk ‘event and Clk = ‘1’) thenQ <= D;end if;end process;end BEHAVIOR;调用语句U1 REG_GROUP map(4) port map (Clk=> Clk,Rst=>Rst,Load=>Load,D=>D,Q=>Q );则该寄存器数据宽度为4。
verilog语法基本知识Verilog语法基本知识Verilog是一种硬件描述语言,用于设计数字电路和系统。
它是一种结构化的编程语言,具有高度的抽象性和可重用性。
本文将介绍Verilog 的基本语法知识。
1.模块定义在Verilog中,一个模块是一个独立的实体,可以包含多个输入和输出端口以及内部逻辑。
模块定义的基本形式如下:module module_name(input port_list, output port_list);//内部逻辑endmodule其中,module_name为模块名称,input port_list为输入端口列表,output port_list为输出端口列表。
2.端口定义在模块定义中,可以定义多个输入和输出端口。
每个端口都有一个名称和数据类型。
例如:input clk; //定义一个时钟输入端口output reg [7:0] data_out; //定义一个8位输出端口3.数据类型Verilog支持多种数据类型,包括整数、浮点数、布尔值、向量等。
整数类型可以是有符号或无符号的,并且可以指定位宽。
例如:reg signed [7:0] num1; //有符号8位整数类型reg unsigned [15:0] num2; //无符号16位整数类型浮点数类型包括实数和双精度实数。
例如:real num3; //实数类型realtime num4; //双精度实数类型布尔值类型包括true和false。
例如:wire flag; //布尔值类型向量类型可以表示多位数据,例如:reg [7:0] data_in; //8位向量类型4.运算符Verilog支持多种运算符,包括算术运算符、比较运算符、逻辑运算符等。
算术运算符包括加、减、乘、除等。
例如:a =b + c; //加法运算b = d * e; //乘法运算比较运算符包括等于、不等于、大于、小于等。
例如:if(a == b) begin //判断a是否等于b//执行代码end逻辑运算符包括与、或、非等。
Verilog HDL(硬件描述语言)是一种用于描述数字电路和硬件设计的语言。
它被广泛用于数字电路设计、FPGA 编程和ASIC 设计等领域。
以下是Verilog HDL的一些基本语法要点:模块声明:Verilog程序通常由一个或多个模块组成。
每个模块的声明以关键字module 开始,后面跟着模块的名称和输入/输出端口的声明。
例如:module MyModule (input wire A,input wire B,output wire Y);// 模块的行为描述endmodule端口声明:端口声明包括输入(input)、输出(output)、双向(inout)端口,以及线(wire)或寄存器(reg)类型的端口。
端口声明通常在模块的参数列表中列出。
线声明:线(wire)用于表示组合逻辑电路中的连接,它们不存储任何状态。
寄存器(reg)用于表示时序逻辑电路中的状态元素,可以存储数据。
例如:wire A, B;reg [7:0] data;组合逻辑:组合逻辑使用assign 语句来描述,它定义了如何从输入信号计算输出信号。
例如:assign Y = A & B; // Y是A和B的逻辑与结果时序逻辑:时序逻辑通常使用always 块来描述。
它表示在时钟信号的边沿或电平触发时执行的操作。
例如:always @(posedge clk) beginif (reset) begindata <= 8'h00;end else begindata <= data + 1;endend条件语句:Verilog使用if、else if 和else 来描述条件分支。
例如:if (condition1) begin// 条件1成立时的操作end else if (condition2) begin// 条件2成立时的操作end else begin// 以上条件都不成立时的操作end模块实例化:你可以在其他模块内部实例化已定义的模块,并连接其输入和输出。
(verilog和vhdl)Testbench编程指南TestBench编程指南如今数字设计的规模变得越来越庞大,设计的复杂程度也越来越高,这就使得设计的验证变得越来越困难,而且费时费力。
为了应对这种挑战,验证工程师依靠各种验证工具和方法。
对于大型设计,如几百万门的设计,通常采用一整套正式的验证工具。
然而,对于小一些的设计,设计工程师发现往往采用带TestBench的HDL仿真工具是最好的途径。
TestBench已经变成验证高级语言设计的一种标准的方法。
通常,TestBench执行以下任务:z例化设计,使其可测试(DUT-design under test);z通过将测试向量应用到模型来仿真例化后的可测试的设计;z将结果输出到终端,或者输出波形窗口;z将真实的结果和期望的结果进行比较;一般,TestBench采用工业标准的VHDL或者Verilog硬件描述语言来编写。
TestBench调用功能设计,然后仿真。
复杂的测试文件执行附加功能――例如,他们包含逻辑以决定合适的设计激励或者比较真实的结果和期望的结果。
以下章节将讨论一个组织良好的测试文件的组成,以及例举了一个带有自检的测试文件(自动将真实的结果和预期的结果进行比较)。
下图是一个标准的HDL验证的流程。
自从测试文件可以用VHDL或者Verilog编写以来,测试验证流程就可以在平台和供应商的工具交叉进行。
同时,由于VHDL和Verilog都是标准的公用的语言,所以用VHDL或者是Verilog描述的验证可以很简单的被再使用。
图1. HDL验证流程测试文件构成:测试文件可以采用VHDL或者Verilog语言编写。
由于测试文件只是用来仿真的,他们就不被用于综合的RTL语言子集的语法所约束。
相反,所有行为结构都可以被使用。
这样,测试文件可以被写的更通用,更易于维护。
所有的测试文件都包含以下基本内容,如表1。
如上所属,测试文件经常同时包含附加功能,如结果的可视化显示和内建错误检测。
verilog语言代码设计规范2011年12月目录一、规范适用范围 ------------------------------------------------------------------------ 41.1项目适用范围------------------------------------------------------------------------------------- 41.2人员适用范围------------------------------------------------------------------------------------- 41.3编码设计的成果形式 --------------------------------------------------------------------------- 4二、代码书写规范 ------------------------------------------------------------------------ 52.1模块说明书写规范------------------------------------------------------------------------------- 52.1模块注释书写规范------------------------------------------------------------------------------- 52.3变量名称书写规范------------------------------------------------------------------------------- 62.4代码结构书写规范------------------------------------------------------------------------------- 7三、使用verilog语言的语法范围----------------------------------------------------- 83.1设计RTL代码的语法范围 -------------------------------------------------------------------- 83.2设计仿真代码的语法范围 -------------------------------------------------------------------- 10四、使用verilog语言的结构范围---------------------------------------------------- 114.1系统设计文件的形式与使用方法----------------------------------------------------------- 114.2模块结构划分的标准 -------------------------------------------------------------------------- 124.3组合逻辑的代码风格 ------------------------------------------------------------------------ 134.4时序逻辑的代码风格 -------------------------------------------------------------------------- 214.5仿真代码的代码风格 -------------------------------------------------------------------------- 27五、使用受限范围内的语法或结构要进行的申请过程-------------------------- 325.1受限的语法与结构------------------------------------------------------------------------------ 325.2批准使用的程序--------------------------------------------------------------------------------- 32二、代码书写规范2.1模块说明书写规范在开始子模块设计时,必须对子模块的基本信息给予说明。
VHDL语言编写规范VHDL语言编写规范目录目录 (1)1 目的 (2)2 范围 (2)3 定义 (2)4 规范内容:VHDL编码风格 (2)4.1 标识符(Identifiers)命名习惯 (2) 4.2 数据对象和类型 (4)4.3 信号和变量 (5)4.4 实体 (5)4.5 语句 (7)4.6 运算符(Operator) (10)4.7 function (10)4.8 procedure (11)4.9 类属( generics) (11)4.10 package (12)4.11 FSM(有限状态机) (12)4.12 Comments (12)4.13 TAB键间隔 (12)4.14 语句书写规范规定 (13)5 程序中的注释 (13)6 代码模块划分 (14)7 代码编写中容易出现的问题 (15)7.1 资源共享问题 (15)7.2 组合逻辑描述的多种方式 (15)7.3 考虑综合的执行时间 (16)7.4 避免使用Latch (16)7.5 多赋值语句案例:三态总线 (16)附录一VHDL保留字 (18)附录二函数书写实例 (19)附录三参数化元件实例 (20)附录四程序包书写实例 (21)1 目的编写该规范的目的是提高书写VHDL代码的可读性、可修改性、可重用性;优化代码综合和仿真结果,指导设计工程师使用VHDL 规范代码和优化电路,规范化公司的ASIC/FPGA 设计输入,从而做到:a、逻辑功能正确;b、可快速仿真;c、综合结果最优;d、可读性最好。
2 范围该规范设计VHDL编码风格、规定,编码中应注意的问题,VHDL 代码书写范例等,适用于所有的采用VHDL代码进行设计的项目。
3 定义VHDL:Very high speed IC Hardware Description Language,甚高速集成电路的硬件描述语言。
FSM:Finite Status Machine,有限状态机Simulate:仿真,通过输入激励在计算机上验证设计是否正确。
数字设计中的Verilog编程技巧在数字设计中,Verilog是一种常用的硬件描述语言,广泛应用于数字集成电路设计和仿真中。
Verilog编程技巧对于提高设计效率、优化性能和减少错误至关重要。
下面我将介绍几种Verilog编程技巧,帮助您更好地应用Verilog进行数字设计。
首先,合理使用模块化设计。
在Verilog中,模块是设计的基本单元,将复杂系统划分为多个模块可以提高可维护性和复用性。
因此,在设计过程中应该遵循模块化设计原则,将功能模块化、分层和相互独立。
其次,正确使用参数化。
在Verilog中,参数化是指通过参数来描述模块或信号的行为。
合理使用参数可以提高代码的灵活性和可复用性。
通过定义参数,可以轻松地调整模块的行为,使得代码更加通用和易扩展。
此外,熟练掌握Verilog中的时序控制。
时序控制是Verilog设计中的关键部分,用于描述时序逻辑和时序行为。
在设计过程中,需要注意时钟的约束和时序分析,确保设计的正确性和稳定性。
可以使用时钟域划分、时钟同步等技术来解决时序问题。
另外,注意Verilog中的模拟和仿真。
在数字设计中,模拟和仿真是验证设计正确性的重要步骤。
Verilog提供了Simulator工具,可以进行行为级仿真和波形仿真。
通过模拟和仿真可以验证设计是否符合预期,发现和修复设计中的问题。
最后,关注Verilog中的调试和优化。
在设计过程中,经常需要进行调试和优化,以确保设计满足性能和功耗要求。
Verilog提供了一些调试和优化技术,如添加断点、查看波形、进行逻辑分析等。
通过调试和优化可以找到设计中的问题,并对设计进行改进。
总的来说,Verilog编程技巧对于数字设计至关重要。
通过合理的模块化设计、参数化、时序控制、模拟和仿真、调试和优化,可以提高设计效率、优化性能和减少错误。
希望以上介绍的Verilog编程技巧能够帮助您在数字设计中取得更好的结果。
祝您在Verilog编程中取得成功!。
[VHDL+Verilog]良好的代码编写风格(二十五条)
良好代码编写风格可以满足信、达、雅的要求。
在满足功能和性能目标的前提下,增强代码的可读性、可移植性,首要的工作是在项目开发之前为整个设计团队建立一个命名约定和缩略语清单,以文档的形式记录下来,并要求每位设计人员在代码编写过程中都要严格遵守。
良好代码编写风格的通则概括如下:
(1)对所有的信号名、变量名和端口名都用小写,这样做是为了和业界的习惯保持一致;对常量名和用户定义的类型用大写;
(2)使用有意义的信号名、端口名、函数名和参数名;
(3)信号名长度不要太长;
(4)对于时钟信号使用clk 作为信号名,如果设计中存在多个时钟,使用clk 作为时钟信号的前缀;
(5)对来自同一驱动源的信号在不同的子模块中采用相同的名字,这要求在芯片总体设计时就定义好顶层子模块间连线的名字,端口和连接端口的信号尽可能采用相同的名字;
(6)对于低电平有效的信号,应该以一个下划线跟一个小写字母b 或n 表示。
注意在同一个设计中要使用同一个小写字母表示低电平有效;
(7)对于复位信号使用rst 作为信号名,如果复位信号是低电平有效,建议使用rst_n;
(8)当描述多比特总线时,使用一致的定义顺序,对于verilog 建议采用bus_signal[x:0]的表示;
(9)尽量遵循业界已经习惯的一些约定。
如*_r 表示寄存器输出,*_a 表示异步信号,*_pn 表示多周期路径第n 个周期使用的信号,*_nxt 表示锁存前的信号,*_z 表示三态信号等;
(10)在源文件、批处理文件的开始应该包含一个文件头、文件头一般包含的内容如下例所示:文件名,作者,模块的实现功能概述和关键特性描述,文件创建和修改的记录,包括修改时间,修改的内容等;
(11)使用适当的注释来解释所有的always 进程、函数、端口定义、信号含义、变量含义或信号组、变量组的意义等。
注释应该放在它所注释的代码附近,要求简明扼要,只要足够说明设计意图即可,避免过于复杂;
(12)每一行语句独立成行。
尽管VHDL 和V erilog 都允许一行可以写多个语句,当时每个语句独立成行可以增加可读性和可维护性。
同时保持每行小于或等于72 个字符,这样做都是为了提高代码得可读性;
(13)建议采用缩进提高续行和嵌套语句得可读性。
缩进一般采用两个空格,如西安交通大学SOC 设计中心2 如果空格太多则在深层嵌套时限制行长。
同时缩进避免使用TAB 键,这样可以避免不同机器TAB 键得设置不同限制代码得可移植能力;
(14)在RTL 源码的设计中任何元素包括端口、信号、变量、函数、任务、模块等的命名都不能取Verilog 和VHDL 语言的关键字;
(15)在进行模块的端口申明时,每行只申明一个端口,并建议采用以下顺序:
输入信号的clk、rst、enables other control signals、data and address signals。
然后再申明输出信号的clk、rst、enalbes other control signals、data signals;
(16)在例化模块时,使用名字相关的显式映射而不要采用位置相关的映射,这样可以提高代码的可读性和方便debug 连线错误;
(17)如果同一段代码需要重复多次,尽可能使用函数,如果有可能,可以将函数通用化,以使得它可以复用。
注意,内部函数的定义一般要添加注释,这样可以提高代码的可读性;
(18)尽可能使用循环语句和寄存器组来提高源代码的可读性,这样可以有效地减少代码行数;
(19)对一些重要的always 语句块定义一个有意义的标号,这样有助于调试。
注意标号名不要与信号名、变量名重复;
(20)代码编写时的数据类型只使用IEEE 定义的标准类型,在VHDL 语言中,设计者可以定义新的类型和子类型,但是所有这些都必须基于IEEE 的标准;
(21)在设计中不要直接使用数字,作为例外,可以使用0 和1。
建议采用参数定义代替直接的数字。
同时,在定义常量时,如果一个常量依赖于另一个常量,建议在定义该常量时用表达式表示出这种关系;
(22)不要在源代码中使用嵌入式的dc_shell 综合命令。
这是因为其他的综合工具并不认得这些隐含命令,从而导致错误的或较差的综合结果。
即使使用Design Compiler,当综合策略改变时,嵌入式的综合命令也不如放到批处理综合文件中易于维护。
这个规则有一个例外的综合命令,即编译开关的打开和关闭可以嵌入到代码中;
(23)在设计中避免实例化具体的门级电路。
门级电路可读性差,且难于理解和维护,如果使用特定工艺的门电路,设计将变得不可移植。
如果必须实例化门电路,我们建议采用独立于工艺库的门电路,如SYNOPSYS 公司提供的GTECH 库包含了高质量的常用的门级电路;
(24)避免冗长的逻辑和子表达式;
(25)避免采用内部三态电路,建议用多路选择电路代替内部三态电路。