《FPGA设计流程与规范.doc》由会员分享,可在线阅读,更多相关《FPGA设计流程与规范.doc(67页珍藏版)》请在三一办公上搜索。
1、FPGA设计流程与规范前言在大规模的逻辑设计过程中,按照标准的设计流程和代码规范来进行FPGA、CPLD的开发是很重要的,它能够使整个开发过程实现合理性、一致性、高效性。对于一个不规范的设计程序,若隔了比较长的时间来进行调试或修改的话,估计很多信号和模块的功能都忘了,若做了一半时需要由别的工程师来接着做的话,估计也得重头开始整个设计了。而且,一个不规范的设计也无法实现代码的可重用性。因此,FPGA设计流程和代码的规范化是很重要的,鉴于此原因笔者编写了本文档,以供FPGA设计参考用。同时,本文档还对FPGA开发过程中的一些常用技巧和需要注意的问题进行了阐述。目 录前言11. 基于HDL的FPGA
2、设计流程概述11.1 设计流程图11.2 关键步骤的实现21.2.1 功能仿真21.2.2 逻辑综合21.2.3 前仿真31.2.4 布局布线31.2.5 后仿真(时序仿真)43. 逻辑仿真43.1 测试程序(test bench)43.2 使用预编译库54. 逻辑综合54.1 逻辑综合的一些原则64.1.1 关于逻辑综合64.1.2 大规模设计的综合64.1.3 必须重视工具产生的警告信息64.2 调用模块的黑盒子方法65. VHDL语言编写规范75.1 VHDL编码风格75.1.1 标识符命名习惯75.1.2 数据对象和类型85.1.3 信号和变量95.1.4 实体和结构体105.1.5
3、语句115.1.6 运算符145.1.7 函数(Function)145.1.8 过程(Procedure)145.1.9 类属(generics)155.1.10 程序包(Package)155.1.11 有限状态机(FSM)155.1.12 注释(comments)165.2 代码的模块划分165.3 代码编写中容易出现的问题165.3.1 资源共享问题165.3.2 组合逻辑描述的多种方式175.3.3 考虑综合的执行时间175.3.4 避免使用Latch175.3.5 内部三态总线结构186. VERILOG语言编写规范196.1 Verilog编码风格196.1.1 命名规则196.
4、1.2 Modules206.1.3 Net and Register216.1.4 Expressions216.1.5 IF语句216.1.6 CASE语句226.1.7 Writing Functions226.1.8 Assignment236.1.9 Combinatorial VS Sequential Logic236.1.10 Macros246.1.11 Comments246.2 代码编写中容易出现的问题247. 同步数字电路设计技术277.1 设计的可靠性277.2 时序分析基础277.3 同步电路设计287.3.1 同步电路的优越性287.3.2 同步电路设计规则297
5、.3.3 异步设计中常见问题及解决办法297.3.4 不建议使用的电路377.4 置位和复位信号处理387.5 时延电路处理387.6 全局信号处理387.7 时序设计的可靠性保障措施408. 基于VHDL的FPGA设计指导418.1 VHDL代码风格418.2 常见问题418.2.1 不可综合的代码418.2.2 采用std_logic以外的数据类型418.2.3 错误使用inout428.2.4 产生不必要的Latch428.2.5 同一个信号在两个或两个以上的process中赋值438.2.6 错误的使用变量或信号438.2.7 合理使用内部RAM458.2.8 三态电路设计458.2.
6、9 异步复位电路设计468.2.10 时钟电路设计478.3 设计技巧488.3.1 合理设计加法电路488.3.2 巧妙处理比较器508.3.3 选择IF语句和CASE语句508.3.4 减少关键路径的逻辑级数508.3.5 考虑资源共享508.3.6 流水结构(Pipelining)538.3.7 组合逻辑和时序逻辑分离548.3.8 利用电路等价性“分配”延时548.3.9 复制电路,减少扇出,提高速度548.3.10 状态机编码及设计技巧548.4 与工艺相关的设计技巧(以Xilinx为例)568.4.1 高效利用IOB568.4.2 存储器的使用578.4.3579. 可重用性设计5
7、89.1 基本原则589.2 原则描述589.2.1 命名定义589.2.2 VHDL中Architecture的命名约定589.2.3 源文件中要有文件头599.2.4 使用注释599.2.5 独立成行599.2.6 行长度599.2.7 缩进599.2.8 不要使用HDL的保留字599.2.9 端口顺序599.2.10 端口映射和generic映射609.2.11 使用函数609.2.12 使用循环、Loop和数组609.2.13 使用有意思的标号609.3 可移植性编码准则609.3.1 只使用IEEE的标准类609.3.2 不要直接使用数字619.3.3 使用package619.3.
8、4 VHDL到Verilog的变换619.4 时钟和复位信号的编码准则619.4.1 避免使用混合时钟沿619.4.2 避免手工例化时钟Buffer619.4.3 避免门控时钟629.4.4 避免内部产生复位信号629.4.5 触发器的时钟使能和低功耗设计629.5 面向综合的编码准则629.5.1 寄存器推断629.5.2 定义完整的敏感表631. 基于HDL的FPGA设计流程概述1.1 设计流程图(1)设计定义(2)HDL实现逻辑仿真器(3)功能仿真逻辑综合器(4)逻辑综合逻辑仿真器(5)前仿真FPGA厂家工具(6)布局布线(8)静态时序分析逻辑仿真器(7)后仿真(9)在系统测试说明:l
9、逻辑仿真器主要指modelsim,Verilog-XL等。l 逻辑综合器主要指LeonardoSpectrum、Precision、Synplify、FPGA Compiler等。l FPGA厂家工具指的是Max+PlusII、QuartusII、ISE等。1.2 关键步骤的实现1.2.1 功能仿真RTL代码调用模块的行为仿真模型测试程序(test bench)测试数据逻辑仿真器说明:“调用模块的行为仿真模型”指的是RTL代码中引用的由厂家提供的宏模块/IP,如Altera 提供的LPM库中的乘法器、存储器等部件的行为模型,Xilinx提供的各种基本部件的仿真模型、或者是由Synopsys公司
10、提供的SmartModel模型等,当然也可以是设计者自己编写的仿真模型。1.2.2 逻辑综合设置综合目标和约束条件调用模块的黑盒子接口RTL代码逻辑综合器HDL网表(netlist)EDIF网表(netlist)说明:“调用模块的黑盒子接口”的导入,是由于RTL代码调用了一些外部模块,而这些外部模块不能被综合或无需综合,但逻辑综合器需要其接口的定义来检查逻辑并保留这些模块的接口。1.2.3 前仿真逻辑综合器调用模块的行为仿真模型测试数据测试程序(test bench)HDL网表(netlist)逻辑仿真器说明:一般来说,只要针对所用的逻辑综合器和所选的FPGA器件来说,RTL设计是完全可综合的
11、,那么前仿真这一步可以跳过不做,这一步主要用于发现综合后有无逻辑功能上的问题,有的话就需要修改源代码或者综合约束。1.2.4 布局布线逻辑综合器设置布局布线约束条件FPGA厂家工具EDIF网表(netlist)调用模块的综合模型SDF文件(标准延时格式)HDL网表(netlist)下载/编程文件1.2.5 后仿真(时序仿真)测试数据SDF文件(标准延时格式)FPGA基本单元仿真模型测试程序(test bench)FPGA厂家工具HDL网表(netlist)逻辑仿真器3. 逻辑仿真考虑到性能和易用性,首选的逻辑仿真器是Mentor Graphics的modelsim。3.1 测试程序(test
12、bench)测试程序对于设计功能和时序的验证有着举足轻重的影响,测试激励的完备性和真实性是关键所在,有以下原则须遵循:(1) 测试激励输入和响应输出采集的时序应当兼顾功能仿真(无延时)和时序仿真(有延时)的情况。(2) 对于周期较多的测试,为提高效率,尽可能采用程序语句来判断响应与标准结果是否一致,给出成功或出错标志,而不是通过观察波形来判断。(3) 采用基于文件的测试是很好的办法,即由matlab或spw等系统工具产生测试数据,测试程序将其读入产生激励,再把响应结果写入到文件,再交给上述工具进行处理或分析。(4) 仿真器支持几乎所有的VHDL、Verilog HDL语法,而不仅仅是常用的RT
13、L的描述,设计者在编写测试平台时应当要充分利用这一点,使测试程序尽可能简洁、清楚,篇幅长的要尽量采用procedure 、task来描述。3.2 使用预编译库在进行功能仿真和后仿真时都需要某些模块的行为仿真模型和门级仿真模型,如Altera Quartus里的220model.v(LPM模块行为仿真模型)和apex20ke_atoms.v(20KE系列门级仿真模型),为避免在不同的设计目录中多次编译这些模型,应当采用一次编译,多次使用的方法。具体做法如下(以20KE门级库为例):1:在某个工作目录下新建一库名 apex20ke,将apex20ke_atoms.v编译到其中。2:在图形界面中的L
14、oad Design对话框中装入仿真设计时,在Verilog 标签下指定预编译库的完整路径。(见下图)4. 逻辑综合目前可用的FPGA综合工具有Mentor Graphics 的 LeonardoSpectrum、Precision,Synplicity的Synplify,Synopsys 的FPGA CompilerII/FPGA Express。Precision和Synplify由于性能和速度最好,成为我们首选的综合器,目前在FPGA逻辑综合市场也是各占半壁天下。另外设计者也可以使用QuartusII和ISE自带的综合器。4.1 逻辑综合的一些原则4.1.1 关于逻辑综合HDL代码综合后
15、电路质量的好坏主要取决于三个方面:RTL实现是否合理、对厂家器件特点的理解、和对综合器掌握的程度,这一点FPGA工程师应该高度重视并熟练运用。 RTL级实现的合理性对综合后电路的影响至关重要。划分合理的功能模块、安排正确的process或task、设计高效的状态机等,这些都决定着最终电路的质量。LeonardoSpectrum、Precision、Synplify这些工具对综合的控制能力比较强,但使用也略为复杂,故需要在使用前尽量熟悉其功能,才能取得较好的综合结果。当出现综合结果不能满足约束条件时,不要急于修改设计源文件,应当通过综合器提供的时序和面积分析命令找出关键所在,然后更改综合控制或修
16、改代码。4.1.2 大规模设计的综合l 分块综合当设计规模很大时,综合也会耗费很多时间。如果设计只更改某个模块时,或者需要对某个模块单独进行综合从而达到比较好的效果时,可以分块综合。如有设计 top.v 包含 a.v和b.v两个模块,当只修改a.v或者为了使b.v能够综合出比较好的结果,可以先单独综合b.v,输出其网表b.edf,编写一个b模块的黑盒子接口b_syn.v,每次修改a.v后只综合top.v、a.v、b_syn.v,将综合后的网表和b.edf送去布线,可以节约综合b模块的时间。l 采用脚本命令当设计规模比较大时,逻辑综合的控制也许会比较复杂,可以考虑采用脚本控制文件的方式进行综合控
17、制,基本上所有的仿真、综合、布线工具都支持TCL(Tool Command Language)语言,采用脚本控制可以提供比图形界面更灵活和更方便的控制手段。4.1.3 必须重视工具产生的警告信息综合工具对设计进行处理可能会产生各种警告信息,有些是可以忽略的,但设计者应该尽量去除,不去除也必须要确认每条警告的含义,避免因此使设计的实现产生隐患。这个原则对仿真和布局布线同样适用。4.2 调用模块的黑盒子方法使用黑盒子(Black Box)方法的原因主要有两点:一是HDL代码中调用了一些FPGA厂家提供的模块(如Altera的LPM模块)或第三方提供的IP,这些模块不需要综合,而且有些综合器也不能综
18、合。因此须提供一个黑盒子接口给综合器,所调用的模块到布局布线时才进行连接。二是方便代码的移植,由于厂家提供的模块或第三方提供的IP通常都是与工艺有关的,直接在代码中调用的话将不利于修改,影响代码移植。5. VHDL语言编写规范该规范涉及VHDL编码风格、规定,编码中应注意的问题,VHDL代码书写范例等。编写该规范的目的是提高书写VHDL代码的可读性、可修改性、可重用性,优化代码综合和仿真的结果,指导设计工程师使用VHDL规范代码和优化电路,规范化公司的CPLD/FPGA设计输入,从而做到:(1)逻辑功能正确,(2)可快速仿真,(3)综合结果最优,(4)可读性较好。本章节中提到的VHDL编码规则
19、和建议既适用于VHDL数字电路设计中的任何一级(RTL,behavioral,gate_level),也适用于出于仿真、综合或二者结合的目的而设计的模块。5.1 VHDL编码风格5.1.1 标识符命名习惯标识符用于定义实体名、结构体名、信号和变量名等,选择有意义的命名对设计是十分重要的。命名包含信号或变量诸如出处、有效状态等基本含义。下面给出一些命名的规则包括VHDL语言的保留字。1标识符定义命名规定n 标识符第一个字符必须是字母,最后一个字符不能是下划线,不许出现连续两个下划线n 基本标识符只能由字母、数字和 下划线组成n 标识符两词之间须用下划线连接:如 Packet_addr, Data
20、_in, Mem_wr, Mem_cen 标识符不得与保留字同名2标识符大小写规定n 对常量、数据类型、实体名和结构体名采用全部大写n 对变量采用小写n 对信号采用第一个词首字符大写n 保留字一律小写3信号名连贯缩写的规定长的名字对书写和记忆会带来不便,甚至带来错误。采用缩写时应注意同一信号在模块中的一致性。一致性的缩写习惯有利于文件的阅读理解和交流。部分缩写的统一规定为:Addr address; Clk clock; Clr clear; Cnt counter;En enable; Inc increase; Lch latch; Mem memory;Pntr pointer; Pst
21、 preset; Rst reset;Reg register; Rd reader; Wr write常用多个单词的缩写:ROM RAM CPU FIFO ALU CS CE自定义的缩写必须在文件头注释。4信号名缩写的大小写规定n 单词的缩写若是信号名的第一个单词则首字符大写,如Addr_in中的Addr。 若该单词缩写不是第一 个单词则小写, 如Addr_en 中的enn 多个单词的首字符缩写都大写,不管该缩写在标识符的什么位置, 如RAM_addr、Rd_CPU_en5信号名一致性规定 同一信号在不同层次应保持一致性。6信号命名有关建议n 建议用有意义而有效的名字,能简单包含该信号的全部
22、或部分信息,如输入输出信息:Data_in 总线数据输入、Din 单根数据线输入、FIFO_out FIFO、数据总线输出;如宽度信息:Cnt8_q 8位计数器输出信号的命名n 建议添加有意义的后缀,使信号名更加明确,常用的后缀如下: 说明:1. 采用D触发器对信号进行延迟,延迟信号的命名在原信号名之后加后缀_L,若是在流水线设计中有级延迟,再分别加后缀_L1, _L2 .。 L 表示lock2. 模块内的反馈信号,在原信号名之后加后缀_s。 s 表示 same5.1.2 数据对象和类型1类型使用规定n VHDL是很强的类型语言,可综合的数据类型为标量类型(包含可枚举类型、整型、浮点型、物理类
23、型)和组合类型(包含记录、数组),模拟模型的数据类型可为存取类型、文件型。可综合的VHDL代码的编写不采用模拟类型、浮点型、物理类型n 不同基本类型的数据不能由另一类型赋值,不同类型间的赋值需使用运算符的重载。如:Cnt8_q 为STD_LOGIC_VECTOR 类型,若不对 + 运算符重载,则 Cnt8_q = Cnt8_q + 1 语句在综合中将出错。可通过对 + 运算符进行重载即使用use IEEE.std_logic_arith.all 语句,则上句赋值语句是正确的n 常量名和数据类型必须用大写标识符表示2数据及数据类型使用建议n 为改善代码的可读性,建议可把常用的常量和自定义的数据类
24、型在程序包中定义n 建议使用别名来标识一组数据类型有利于代码的清晰。如:signal Addr: STD_LOGIC_VECTOR(31 downto 0);alias Top_addr: STD_LOGIC_VECTOR(3 downto 0) is Addr(31 downto 28) ;3数据使用注意内容可枚举类型的值为标识符或单个字母的字面量,是区分大小写的,如 Z 与z 将是两个不同的量。5.1.3 信号和变量1信号不许赋初值。2变量使用建议 变量主要用在高层次的模拟模型建模及用于运算的用途,但变量的综合较难定义,对于编写可综合的VHDL模块,在没有把握综合结果情况下建议不使用。3信
25、号和变量使用注意内容n 在VHDL中,信号(signal)代表硬件连线,因此可以是逻辑门的输入输出,同时,信号也可表达存贮元件的状态。端口也是信号。n 在进程(process)中,信号是在进程结束时被赋值,因此在一个进程中,当一个信号被多个信号所赋值时,只有最后一个赋值语句起作用。如下例:Sig_p: process(A, B, C)beginD = A; - ignored!X = C or D;D = B; - overrids !Y = C xor D;end process;上面实际的结果是 B赋值给D, C xor B 结果赋值给X、Y。n 变量不能表达连线或存贮元件,变量的赋值是直
26、接的、非预设的。变量将保持其值直到对它重新赋值。如下例:Ver_p: process(A B C)Variable: d STD_LOGIC;begind := A;X = C or d;d := B;Y = C xor d;end process;实际结果是 X = C or A ,Y= C xor B。5.1.4 实体和结构体1实体、结构体使用规定n library IEEE; use IEEE.std_logic_1164.all; 除IEEE大写外其余小写n 实体名和结构体名必须用大写标识,实体名必须与文件名同名。自定义的其他标识符如信号名、变量名、标号等,不得与实体名、结构体名同名n
27、 实体端口数据模式不准使用buffer 模式。缓冲模式主要用在实体内部可读的端口,如计数器的输出。 为简化大型设计各模块间接口的配合,要求不要使用。需要反馈的信号可定义内部信号来解决。n 实体端口数据类型规定实体端口的数据类型采用IEEE std_logic_1164 标准支持的和提供的最适合于综合的数据类型STD_ULOGIC STD_LOGIC和这些类型的数组。不采用IEEE 1076 /93 标准支持和提供的BIT、BIT数组、INTEGER及其派生类型,这是为保证模拟模型和综合模型的一致性及减少转换时间和错误。n 一个文件只对应一个实体实体是设计文件的基本单元其书写规范要求如下。n 一
28、条语句占用一行,每行应限制在80个字符以内n 如果较长(超出80个字符)则要换行n 代码书写要有层次即层层缩进格式、清晰、美观n 要有必要的注释(25%)n 实体开始处应注明文件名、功能描述、引用模块、设计者、设计时间、及版权信息等。2实体使用建议n 实体名的命名建议能大致反映该实体的功能,如:COUNTER8 (8位宽的计数器模块),DECODER38 (3-8线译码器模块)n 行为级的结构体名命名为 BEHAVIOR, 结构级的结构体名命名为 STRUCTURE, 若有多个结构体用后缀A B.n 一个实体可以有多个结构体,对单个结构体的实体,文件要包含结构体和实体说明便于查阅。对多个结构体
29、的实体,建议把常用的结构体放在文件中,其余结构体用单独文件表示,使用时用configuration 语句进行配置n 结构体的描述分为行为级描述、数据流描述、和结构化描述,若无特殊要求,建议采用行为级描述和数据流的描述,不采用结构化描述或BOOLEAN 数据流的描述n VHDL设计中,如果可以避免采用器件厂商的专用元件库(硬Core )则尽量不要使用,除非只有采用该库元件才能实现你设计的性能指标,这是因为要充分利用VHDL独立于工艺且易于维护的优点3实体使用注意内容n VHDL设计应是层级型的设计。VHDL设计实体由实体说明和结构体组合而成。实体是一个设计的基本单元模块,即顶层的设计模块由次一级
30、的实体构成,每个次一级实体又可由再下一层次的实体构成,最低层模块可以是表达式或最基本的实体模块构成。这种设计方法就是Top-To-down 的设计方法n 实体端口模式为 in、 out、 buffer、 inout, 模式为in 的信号不能被驱动;模式out的信号不能用于反馈,同时必须仅被一个信号所驱动;缓冲模式的端口不能被多重驱动(除非用决断函数解决外),同时仅可以连接内部信号或另一个实体的缓冲模式的某个端口n VHDL设计各模块接口定义时要考虑模块间配合的方便,如实体端口的模式,端口的数 据类型等5.1.5 语句1VHDL各语句使用规定n with-select-when 语句书写规范规定
31、with- select - when 语句提供选择信号赋值,是根据选定信号的值对信号赋值。代码的书写规范为:with selection_signal selectSelect_name = value_a when value_1_of_selection_signal,value_b when value_2_of_selection_signal,value_c when value_3_of_selection_signal,.value_x when last_value_of_selection_signal;n with- select - when 语句的selection_
32、signal的所有值必须具备完整性,若没写完整必须有一个others 语句,如下三个写法,其综合的效果是一致的,因为S的元素不是已知的逻辑值,X将不被定义,但对RTL仿真而言,其结果是不一致的,这是因为RTL仿真支持多值元素。 建议不使用第三种写法。n with- select - when 语句中对有相同的支项可合并书写, 如X = A when “00” | “10”n when_else 语句书写规范规定 when_else 语句提供为条件信号赋值,即一个信号根据条件被赋一值,代码书写规范为:Signal_name = value_a when condition1 elsevalue_
33、b when condition2 elsevalue_c when condition3 else.value_x;n 当条件是表达式时表达式须用()括起来,使代码更为清晰,如when a = b and C= 1 elsen if 必须有一个else 对应(除在如下面例子的情况下可不写else语句)。process( Clk,Rst)beginif ( Rst = 1) thenQ = 0;elsif ( Clk event and Clk = 1) thenQ Statements1;when value2_of _selection signal =Statements2;.when
34、last_value_of _selection signal =Statements x ;when others =Statements x;end case;n case_when 语句必须有 when others 支项。n 若信号在if -else 或case-when 语句作非完全赋值,必须给定一个缺省值。n process 显示敏感列表必须完整对有Clk 的 process, 不同综合工具有不同的要求,大多数只要写Clk和Rst就可建议根据具体情况简化设计书写。n 每个process 前须加个lable。n 不同逻辑功能采用不同的process 进程块,把相同功能的放在同一进程中
35、。n 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;n 生成机构必须有一个标号,如上的Gen_lab1n if -then 用在生成机构中,不能有else 或elsif 语句,如下复杂的生成机构语句:G1: for I in 0 to 3 generateG2:
36、 for j in 0 to 7 generateG3: if (I port 1,port2 = port2,.portn = port n);n 为便于阅读,port map 采用 名字对应(=)映射方法。n port map 中总线到总线映射时 (X downto Y) 要写全。n 向量采用降序方法,即 X downto Y 格式,向量有效位顺序的定义为从大数到小数。n port map 的module(设计者自编写的entity)名用Uxx标识,cell(如厂家提供的库元件、RAM、 Core等)名用Vxx 标识。2VHDL 语句使用建议n 作为可综合的代码编写,- 值建议不用。如下一
37、个代码with tmp selectX = A when “1-”,B when “-1-”,C when “-1-”,D when “-1”,0 when others;该代码在RTL级仿真中不会出错,但在综合过程中可能编译出错,视综合工具而定n 由于不同综合工具支持能力问题,建议不采用wait 语句即不使用隐式敏感表。3VHDL 语句使用注意内容n when_else 语句具有优先级,第一个when 条件级别最高,最后一个最低可用顺序语句的if-else 替代,书写时必须考虑敏感路径n 当信号的值为不相关的值时,最好用选择信号赋值语句,如多路选择器;当信号的值为相关时,选用when-els
38、e 语句,如编写优先编码器n 注意If -elsif -elsif -else的优先级。最后一个else 优先级最低,必须把关键路径放在优先级高的语句中5.1.6 运算符1表达式书写规定为便于理解用()表示逻辑运算符执行的优先级,如X = ( A and B ) and ( C or (not D ) );建议运算操作符两边都加上空格.2比较运算符规定向量比较时,比较的向量的位宽要相等,否责会引起warning或error ,除非重载等值比较运算符(调用numeric_std 库)。5.1.7 函数(Function)1function 使用规定n function 代码书写规范规定:func
39、tion FUNCTION_NAME (参数1: 参数类型, 参数2: 参数类型 .)return 返回类型 isbegin顺序语句;end;2function 使用建议n 函数主要用于类型的转换或重载运算符的定义,对于使用IEEE1164标准的面向综合的VHDL设计,采用std_logic 类型,不必考虑与bit类型的转换,可调用 numeric_std 标准程序包实现类型转换和 + 运算符的重载, 建议少用厂家提供的函数或自定义的类型转换函数.n 对多次重复的表达式可用一个函数来定义3function 使用注意内容n 函数参数只能是输入类型,不能被赋值修改n 只能有一个返回值n 定义函数必
40、须为顺序语句, 且其中不能定义新的信号, 但可在函数说明域中说明新的变量, 并在定义域中对其赋值n 函数在结构体说明域中或程序包中定义.5.1.8 过程(Procedure)1procedure 使用规定n procedure 书写规范规定procedure PROCEDURE_NAME (signal 参数名: 模式 类型;signal 参数名: 模式 类型;.) isbegin过程体;end procedure;2procedure 使用注意内容n 过程用于数值运算、类型转换、运算符重载或设计元件的最高层设计结构。n 过程参数缺省模式为 in。5.1.9 类属(generics)1gene
41、ric 使用注意内容n 类属为传递给实体的具体元件的一些信息,如器件的上升下降沿的延时信息(对应类属为rise 、fall)、 用户定义的数据类型如负载信息(对应类属为load )、及数据通道宽度、信号宽度等n 对大型设计,建议使用类属来构造参数化的元件.n 若元件的类属在定义时已经指定默认值,在调用时,若不改变该参数值可不用定义实参的映射,即 generic map (实参) 可不写5.1.10 程序包(Package)1package 使用建议n 对大型设计,建议把全局的常量(如数据宽度等)、指令状态编码、元件组、函数和子程序组,分别用元素包、器件包、函数包来构造,如通过调用元件程序包,实
42、体的结构体说明区域中就不必再对调用的器件进行component 说明。n 程序包通过use 语句使之可见,可通过保留字all使包中所有单元都可见。2package 使用注意内容n 程序包包括程序包说明和可选包体,程序包说明用来声明包中的类型、元件、函数和子程序,包体则用来存放说明中的函数和子程序。n 不含有子程序和函数的程序包不需要包体。n 程序包中的类型、常量、元件、函数和其他说明对其他设计单元是可见的。5.1.11 有限状态机(FSM)1FSM 使用规定n VHDL 的FSM为双进程的有限状态机,即组合逻辑进程定义次态的取值,时序逻辑进程定义时钟上升沿来时次态成为现态。n VHDL的FSM
43、 不必为状态分配,而用行为级的枚举类型定义状态,根据需要在综合时选择状态的分配方式,如 one-hot 或二进制编码。n 状态机在上电时必须明确进入一个初始状态。n 必须包括对所有状态都处理,不能出现无法处理的状态,不能使状态机进入死循环。5.1.12 注释(comments)1Comments 使用建议n 对更新的内容尽量要做注释n 模块端口信号要做简要的功能描述n 语法块做简要介绍5.2 代码的模块划分模块设计的好坏直接影响着系统的设计好坏,模块设计的不好,会给后面的设计流程带来许多麻烦。设计模块的基本原则是:有利于模块的可重用性;模块设计得好,可节省大量的重复工作,并且为以后的设计带来方便。1. 在组合电路设计中应当没有层次可提高代码的可读性另外一方面是综合的时候方便并且时序较易满足。2. 每个模块输出尽量采