FPGA设计基础及VerilogHDL语言介绍_第1页
FPGA设计基础及VerilogHDL语言介绍_第2页
FPGA设计基础及VerilogHDL语言介绍_第3页
FPGA设计基础及VerilogHDL语言介绍_第4页
FPGA设计基础及VerilogHDL语言介绍_第5页
已阅读5页,还剩182页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

FPGA实验板课程安排第1章:A/D与D/A第2章:FPGA设计基础(QuartusII软件介绍)第3章:VerilogHDL语言介绍第4章:基于FPGA的数码管显示第5章:基于FPGA的液晶显示第6章:基于FPGA的大LED点阵第7章:基于FPGA的VGA显示本次实验内容1.分频器的代码实现和仿真;加分题:十分之一分频器代码实现和仿真;2.与,或,非逻辑的代码实现和仿真;加分题:数字逻辑器件的代码实现和仿真,例如三八译码器;下次实验内容1.任意偶次分频器的实现和仿真;加分题:递增,递减计数器的实现和仿真;2.学会LED源代码程序编译,下载,管脚分配;加分题:实现各种不同效果的流水灯;FPGA设计基础提要1.可编程逻辑器件概述2.可编程逻辑器件的结构及原理3.FPGA特点4.FPGA设计语言5.FPGA设计流程6.FPGA厂商及开发环境7.QuartusII开发软件使用1可编程逻辑器件概述

可编程逻辑器件(ProgrammableLogicDevice简称PLD)是20世纪70年代发展起来的一种新型逻辑器件,是目前数字系统设计的主要硬件基础。现场可编程逻辑阵列FPLA(FieldProgrammableLogicArray)可编程阵列逻辑PAL(ProgrammableArrayLogic)通用阵列逻辑GAL(GenericArrayLogic)可擦除的可编程逻辑器件EPLD(ErasableProgrammableLogicDevice)复杂可编程逻辑器件CPLD(ComplexProgrammableLogicDevice)现场可编程门阵列FPGA(FieldProgrammableGateArray)1可编程逻辑器件概述

–分类(1)

熔丝或反熔丝编程器件--Actel的FPGA器件体积小,集成度高,速度高,易加密,抗干扰,耐高温只能一次编程,在设计初期阶段不灵活SRAM--大多数公司的FPGA器件可反复编程,实现系统功能的动态重构每次上电需重新下载,实际应用时需外挂EEPROM用于保存程序EEPROM--大多数CPLD器件可反复编程不用每次上电重新下载,但相对速度慢,功耗较大1可编程逻辑器件概述

–分类(2)

低密度PROM,EPROM,EEPROM,PAL,PLA,GAL只能完成较小规模的逻辑电路高密度,已经有超过400万门的器件EPLD,CPLD,FPGA可用于设计大规模的数字系统集成度高,甚至可以做到SOC(SystemOnaChip)CPLD与FPGA的区别CPLDFPGA内部结构Product-termLook-upTable程序存储内部EEPROMSRAM,外挂EEPROM资源类型组合电路资源丰富触发器资源丰富集成度低高使用场合完成控制逻辑能完成比较复杂的算法速度慢快其他资源-EAB,锁相环保密性可加密一般不能保密2可编程逻辑器件结构原理2可编程逻辑器件结构原理2可编程逻辑器件结构原理乘积项与门2

可编程逻辑器件结构原理2

可编程逻辑器件结构原理-PROM结构与阵列固定,或阵列可编程;实现以“积之和”形式表示的各种组合逻辑编程连接点固定连接点2

可编程逻辑器件结构原理-PLA结构与阵列或阵列均可编程;PLA的内部结构在简单PLD中有最高的灵活性2

可编程逻辑器件结构原理-PAL结构与阵列可编程,或阵列固定;与阵列可编程使输入项增多,或阵列固定使器件简化。或阵列固定明显影响了器件编程的灵活性2

可编程逻辑器件结构原理-GAL结构用可编程的输出逻辑宏单元(OLMC)代替固定的或阵列,可以实现时序电路;OLMC2

可编程逻辑器件结构原理-GAL结构(OLMC)输出使能选择输出选择或门控制选择组成:-异或门:控制输出信号的极性-D触发器:适合设计时序电路-4个多路选择器2

可编程逻辑器件结构原理-CPLD\FPGA的结构基于乘积项:

Altera的MAX7000,MAX3000系列,Xilinx的XC9500系列Lattice,Cypress的大部分产品基于查找表:

Altera的FLEX,ACEX,APEX系列, Xilinx的Spartan,Virtex系列。

可编程逻辑阵列模块LAB,包含多个宏单元可编程I/O单元可编程连线PIA基于乘积项的CPLD内部结构LAB中的宏单元结构乘积项逻辑阵列乘积项选择矩阵可编程触发器基于查找表的FPGA内部结构C可编程逻辑模块(CLB),含多个逻辑单元可编程输入输出模块(IOB)可编程内部连线(PIC)基于查找表(LUT)的FPGA的结构

xilinxSpartan-II的内部结构CLB中逻辑单元内部结构查找表LUT原理3FPGA特点逻辑器件:用来实现某种特定逻辑功能的电子器件,最简单的逻辑器件是与、或、非门(74LS00,74LS04等),在此基础上可实现复杂的时序和组合逻辑功能。可编程逻辑器件:器件的功能不是固定不变的,而是可根据用户的需要而进行改变,即由编程的方法来确定器件的逻辑功能。配置数据可以存放在片外的EPROM或其它存储体上,可现场修改器件的逻辑功能。电路集成度高用硬件描述语言(HardwareDescriptionLanguage)代替传统的数字电路设计方法来设计数字系统。3FPGA特点 EP1C12Q2404FPGA设计语言

HDL语言是一种硬件描述语言,最终目的是生成实际数字逻辑电路,完成一个从抽象化的代码到形象化的电路的转变。

电路设计大规模和高复杂度发展的趋势,传统的用原理图设计电路的方法无法胜任,如何使如此复杂的芯片变得易于人脑的理解呢?用一种高级语言来表达其功能性而隐藏具体实现的细节是很必要的,工程人员将不得不使用HDL语言进行设计,而把具体实现留给逻辑综合工具去完成。

VerilogHDLVHDL-硬件描述语言HDL(HardwareDescriptionLanguage)4FPGA设计语言-HDL语言特点

HDL语言既包含一些高层程序设计语言的结构形式同时也兼顾描述硬件线路连接的具体结构;

通过使用结构级或行为级描述可以在不同的抽象层次描述设计。

语言采用自顶向下的数字电路设计方法,主要包括三个领域五个抽象层次如表所示4FPGA设计语言-HDL语言特点

HDL语言是并发的,即具有在同一时刻执行多任务的能力。一般编程语言是非并行的但在实际硬件中许多操作都是在同一时刻发生的,所以HDL语言具有并发的特征;

HDL语言有时序的概念,一般编程语言是没有时序概念的,但在硬件电路中从输入到输出总是有延迟存在的,为描述这些特征,HDL语言需要建立时序的概念。因此,使用HDL除了可以描述硬件电路的功能外还可以描述其时序要求;4FPGA设计语言由于VerilogHDL早在1983年就已推出至今已有十三年的历史,因而拥有广泛的设计群体,成熟的资源比VHDL丰富。

目前版本的VerilogHDL和VHDL在行为级抽象建模的覆盖范围方面也有所不同,一般认为VHDL在系统抽象方面比VerilogHDL强一些,VerilogHDL较为适合算法级、寄存器传输级、逻辑级、门级等的设计,而VHDL更为适合大型的系统级设计。-VerilogHDL与VHDL比较用两种语言设计同一个计数器4FPGA设计语言-VHDLlibraryieee;useieee.std_logic_1164.alluseieee.std_logic_unsigned.allentitycounterisport(clk,clr:instd_logic;qout:instd_logic_vector(3downto0);architectureaofcounterissignalqout_temp:std_logic_vector(3downto0);beginqout<=qout_temp;process(clk)beginifclr=‘1’thenqout_temp<=“0000”;elseqout_temp<=qout_temp+“0001”;endifendprocess;enda;4FPGA设计语言-VerilogHDLmodulecounter(clk,clr,qout);inputclk,clr;output[3:0]qout;reg[3:0]qout;always@(posedgeclk)if(clr)qout=0;elseqout=qout+1;endmodule4FPGA设计语言顶层模块子模块A子模块B子模块C模块化的逻辑电路I/O/状态图5FPGA设计的一般流程实现5.1设计准备方案论证,器件选择

根据系统的功能和复杂度,对工作速度和器件本身的资源、成本及连线的可布性等方面进行权衡,选择合适的设计方案和合适的器件类型。5.2设计输入原理图输入HDL(硬件描述语言)输入状态图输入波形输入5.2.1原理图输入方式原理图输入方式是一种最直接的设计描述方式,要设计什么,就从软件系统提供的元件库中调出来,画出原理图。优点是容易实现仿真,便于信号的观察和电路的调整;缺点是效率低,特别是产品有所改动,需要选用另外一个公司的PLD器件时,就需要重新输入原理图5.2.2HDL输入方式硬件描述语言是用文本方式描述设计(普通硬件描述语言和行为描述语言)。普通硬件描述语言有ABEL、CUR和LFM等,它们支持逻辑方程、真值表、状态机等逻辑表达方式,主要用于简单PLD的设计输入。行为描述语言是目前常用的高层硬件描述语言,主要有VHDL和VerilogHDL两个IEEE标准。语言与工艺的无关性,可以使设计人员在系统设计、逻辑验证阶段便确立方案的可行性;语言的公开可利用性,便于实现大规模系统的设计;具有很强的逻辑描述和仿真功能,而且输入效率高,在不同的设计输入库之间的转换非常方便,用不着对底层的电路和PLD结构的熟悉。5.2.3波形输入方式波形输入方式主要是用来建立和编辑波形设计文件,用于输入仿真向量和功能测试向量。波形设计输入适用于时序逻辑和有重复性的逻辑函数。5.3功能仿真验证逻辑功能的正确性,不加入任何硬延时信息。仿真前,要先利用波形编辑器和硬件描述语言等建立波形文件和测试向量仿真结果将会生成报告文件和输出信号波形,从中便可以观察到各个节点的信号变化。如果发现错误,则返回设计输入中修改逻辑设计。功能仿真:验证逻辑功能的正确性,不加入任何硬件延时等信息。测试波形被测电路检查输出输入信号输出波形5.4设计实现设计处理是器件设计中的核心环节。在设计处理过程中,编译软件将对设计输入文件进行规则检查、逻辑优化综合、适配和分割(映射)、布局布线等,最后产生编程用的编程文件。5.4.1逻辑优化和综合化简所有的逻辑方程或用户自建的宏,使设计所占用的资源最少。综合的目的是将多个模块化设计文件合并为一个网表文件,并使层次设计平面化。综合:将抽象的HDL代码转换成具体的逻辑电路原理图。WithselselectDin<=Awhen‘1’,Bwhenothers;process(clk,rst)beginifrst=‘0’thenD_out<=0;elseD_out<=D_in;endif;endprocess;5.4.2适配和分割(映射)确立优化以后的逻辑能否与器件中的宏单元和I/O用单元适配,然后将设计分割为多个便于识别的逻辑小块形式映射到器件相应的宏单元中。映射:将电路逻辑图转换成用切片表示的FPGA内部的实际电路图。布局布线:以最优的方式对逻辑元件布局,并准确地实现元件间的互连。布线以后软件自动生成报告,提供有关设计中各部分资源的使用情况等信息。5.4.3布局布线

布局布线后仿真(时序):所验证的是在原来逻辑电路基础上加入硬件实际信息后,电路功能上的正确性。这是最符合实际情况的仿真。

如仿真无误,则可下载设计结果到实际的FPGA芯片中。功能仿真布局布线后仿真5.5时序仿真5.6器件编程时序仿真完成后,产生位流数据文件(BitstreamGeneration),然后将该文件通过下载器下载配置到可编程器件中去。5.6器件编程

XilinxFPGA的配置方式最大的PLD供应商之一FPGA的发明者,最大的PLD供应商之一ISP技术的发明者提供军品及宇航级产品6FPGA厂商及开发环境MAX+PLUSIIISEFoundationQUARTUSII6FPGA厂商及开发环境7QuartusII开发软件使用QuartusII是Altera的综合开发工具,它集成了Altera的FPGA/CPLD开发流程中所涉及的所有工具和第三方软件接口;创建一个新的工程输入工程路径输入工程名和实体名,必须一样点击NEXT点击NEXT点击NEXT点击NEXT点击结束点击创建新文件图标选择新文件类型为VHDL,然后点击OK在编辑窗口录入源文件顶层文件的实体名必须和工程名一致保存源文件点击编译图标,开始编译在编译过程中如果有错会给出错误提示,否则显示编译成功创建波形文件(还是创建一个新文件,

并选择类型)选中波形文件,点击OK一个空的波形文件被建立波形文件窗口按快捷键Alt+1,弹出如下窗口,按图中所示设置好后,点击List.所有端口信号会被列出来.如图,将输入输出信号拖动到波形文件窗口给输入信号添加激励。如图按住鼠标左键不放,拖动一定距离,再将鼠标放在图中的浅兰色区域双击左键,这时会弹出一个窗口,在该窗口中输入波形值(位数据输入0或1,位矢量输二进制序列)并点击ok。这时就给A端口加上了一段高电平,依此方法给所有的输入都加上指定激励。将输入的激励都加上以后,保存该波形文件在菜单中选择Tools->SimulatorTool选择仿真类型(Functional),并创建功能仿真网表(点击绿色荐头所指按钮)此处应为刚才保存的波形文件功能仿真网表创建完后点击Start运行,运行完成后关闭此窗口.功能仿真点击此处,开始仿真功能仿真运行结束后会弹出功能仿真的波形报告,观察仿真波形并验证在菜单中选择Tools->SimulatorTool弹出下面的窗口,改变仿真类型(选Timing),点击Start运行.运行结束后,关闭该窗口.时序仿真时序仿真点击此处,开始时序仿真得到时序仿真波形.比较时序仿真的波形和功能仿真波形有什么不同应用举例:流水灯及下载开发板使用共阴极接法:程序简介:端口定义moduleled_run(mclk,led);inputmclk;output[7:0]led;reg[7:0]led;reg[22:0]count;reg[2:0]state;wireclk;分频器always@(posedgemclk)count=count+1;assignclk=count[22];//取计数器最高位做低频时钟说明:mclk是FPGA的输入时钟,采用50M有源晶振。请问:这是多少分频?程序主体:花色流水灯always@(posedgeclk)begincase(state)3'b000: beginled=8'b10000001;state=state+1;end3'b001: beginled=8'b01000010;state=state+1;end3'b010: beginled=8'b00100100;state=state+1;end3'b011: beginled=8'b00011000;state=state+1;end3'b100: beginled=8'b00011000;state=state+1;end3'b101: beginled=8'b00100100;state=state+1;end3'b110: beginled=8'b01000010;state=state+1;end3'b111: beginled=8'b10000001;state=state+1;endendcaseendendmodule然后管脚分配,编译,仿真,下载仿真不是必须的。下载程序可看到物理效果。下载分两种:仿真器的接口不同!JTAG下载:程序放在ram中运行AS下载:程序烧写到flash里面运行管脚分配根据原理图管脚分配主时钟:50M晶振提供复位及8个灯的电路应用举例:流水灯及下载开发板使用共阴极接法:VerilogHDL语言介绍

VerilogHDL是使用广泛的硬件描述语言,该语言的特点是语言能力强,代码简单。有大量支持仿真的语句与可综合语句,对于初学者设计简单的数字系统,重点是利用该语言中的可综合语句正确设计数字系统。该语言很多规定与C语言相似。VerilogHDL语言的基本结构VerilogHDL语言基础VerilogHDL中的结构描述VerilogHDL数据流描述VerilogHDL行为描述VerilogHDL语言中的分支语句基于VerilogHDL语言的组合逻辑电路设计基于VerilogHDL语言的时序电路设计1.1VerilogHDL语言的模块结构

VerilogHDL语言以模块(module)的形式来描述数字电路,其中每一个模块都有接口部分用来描述与其它模块之间的连接,一个文件就是一个模块。模块的定义从关键词module开始,到关键字endmodule结束,每条VerilogHDL语句以分号‘;’作为结束(块语句、编译向导语句,endmodule等少数语句除外)。1VerilogHDL语言的基本结构[例1]与非门的Verilog描述moduleNAND(in1,in2,out)inputin1,in2;//端口类型定义outputout;//端口类型定义//wirein1,in2,out;//由于是1位连线类型,所以可以采用缺省定义,此语句可省略assignout=~(in1&in2);endmodule[例2]具有数据输入端d的D触发器。moduledff(q,d,clk);/*模块开始,q是寄存器输出,d是寄存器的数据端输入,clk是寄存器时钟*/outputq;//定义输出量qinputd,clk;//定义输入量d,clkregq;//对q进行进一步数据类型说明,表明q是寄存器型always@(posedgeclk)//当上升沿到来的时候执行如下语句beginq=d;//q等于d,这是D触发器的特性方程endendmodule//模块结束1.2VerilogHDL语言中的描述方法

VerilogHDL语言具有三种描述方法:1.结构型描述该描述是用VerilogHDL中预定义的基本逻辑单元(逻辑门)描述数字电路。[例3]2选1选择器结构图如上图所示,其VerilogHDL的描述如下:modulemux(out,a,b,sel);outputout;inputa,b,sel;not(net1,sel);//非门and(net2,a,net1);//与门and(net3,b,sel);//与门or(out,net2,net3);//或门endmodule2.数据流型描述

数据流型描述是一种描述组合功能的方法,用VerilogHDL中的连续赋值语句assign来实现,连续赋值语句持续监视等式右边的所有变量,每当这些变量中有任何一个发生变化时,整个表达式被重新赋值,并赋予等式左边,这种描述方法只能用来描述组合电路功能。[例4]二选一多路选择电路的数据流型描述。modulemux1(out,a,b,sel);//模块开始outputout;inputa,b,sel;assignout=(sel==0)?a:b;//类似于C语言中的问号语句endmodule3.行为型描述

行为型描述是一种使用高级语言的方法描述数字电路,关键词是(always)。

[例5]二选一多路选择电路的行为型描述程序。modulemux2(out,sel,b,c);outputout;inputsel,b,c;regout;always@(selorborc)//always语句,括号中的是敏感信号if(sel==1)//类似于C语言中的if语句out=b;elseout=c;endmodule

2.1VerilogHDL中的基本约定

1.注释行

VerilogHDL中注释行的定义与C语言一样。2.逻辑状态

0表示逻辑0、逻辑非、低电平、假。1表示逻辑1、逻辑真、高电平、真。x或X表示不确定的逻辑状态。z或Z表示高阻态。这些逻辑状态都可以用在描述语句中。2VerilogHDL语言基础3.整数及其表示整数可以按照简单十进制数格式或基数格式书写。(1)简单十进制数简单十进制数的整数表示与普通十进制数表示相同,例如,35、-46。(2)基数表示法表示格式:+/-<位宽>‘<基数符号><按基数表示的数值>其中:+/-是符号位位宽就是数的等效二进制数的位数(bit),位宽用十进制数表示。二进制的基数符号位b或B。八进制的基数符号是o或O。十进制的基数符号是d或D,可缺省不写基数符号。十六进制的基数符号是h或H。(1)数值中,左边是数值最高位(MSBMostSignificantBit),右边是最低有效位(LSBLeastSignificantBit)。(2)在二进制中,x、z只代表相应位的逻辑状态。x表示不定,z表示高阻(3)当位宽缺省时,位宽为32位。例如:3'b000位宽为3的二进制数res=8'b11111110res是8位二进制数1'b1位宽为1的二进制数9’o671位宽为9的八进制数8’h3f位宽8的十六进制数4.标识符取名

(1)必须是字母或下划线开头,长度小于1024。(2)后续部分可以是字母、数字或下划线。(3)VerilogHDL中的标识符区分大小写。例如,_bus,topp,BUS。5.系统命令

以$开头的标识符代表VerilogHDL中的命令(系统任务与系统函数),普通的标识符不能以$开头。6.保留字VerilogHDL语言内部已经使用的保留字

2.2数据类型

VerilogHDL中总共有19种数据类型,其中4种最基本的数据类型是:整形(integer)、参数(parameter)型、寄存器(reg)型和连线(wire)型。连线类型(又称为线网类型)与寄存器类型是Verilog中的主要数据类型,这两种类型在驱动方式(赋值)、保持方式和相应的硬件实现方式三方面不同。连线类型连线类型说明可综合的连线类型不能综合的连线类型连线功能wire,tri

标准连线(缺省)wor,trior多重驱动时,具有线或功能wand,triand多重驱动时,具有线与功能

trireg具有电荷保持功能的连线

tri1上拉电阻,无驱动时为‘1‘

tri0下拉电阻,无驱动时为‘0‘supply1

电源线,逻辑1supply0

地线,逻辑0(1)不能综合的意思就是不能用来设计数字电路,只能用于软件仿真或是编写激励信号。(2)连线类型的逻辑状态为0、1、x(任意)、z(高阻)(3)在VerilogHDL中,连线类型主要用在模块的结构描述中,对应硬件的物理信号连接,当用数字表示其逻辑值时,不存在符号位。(4)在对连线类型进行描述时,必须用连线类型定义语句进行类型说明,当说明被省略时,表示位宽为1bit的wire型连线。wire是基本的、不附带其它功能的连线,也是最常用的连线类型。(5)tri与wire在VerilogHDL中功能完全一样,差别是名称写法不一样。

连线类型定义格式:

<连线类型>[范围][时间延迟]<连线名>[,连线名];

其中范围为矢量范围,以[MSB:LSB]格式描述,时间延迟只用于仿真中定义连线类型时用。例如:wire[0:31]w1,w2;//w1和w2是32位连线类型,高位MSB为bit0wire[7:0]tmp;//tmp为8位连线,高位MSB为bit7,低位LSB是位02.寄存器类型寄存器类型说明reg用于行为模型中对寄存器类型的说明,由过程赋值语句赋值,是最常用的寄存器类型integer32位带符号整数,通常用作不会由硬件实现的数据处理。real64位浮点、双精度、带符号实型变量,通常用作不会由硬件实现的数据处理。time64位无符号时间变量,用于仿真时间的保存与处理一些说明:(1)所有寄存器类的信号,都可以保存数据,在接受下一次赋值前,数据保持不变。(2)寄存器类型必须给出类型说明(无缺省状态)。(3)寄存器类型的信号,必须通过过程赋值语句进行赋值,只能出现在initial或always后面的过程语句中。(4)除了reg类型以外,其它三种integer、real、time只有抽象意义,不能综合。在对模块的行为描述中,reg的引入,通常说明模块中有触发器或锁存器。

寄存器变量的定义格式:

<寄存器类型>[范围]<寄存器名>[,寄存器名];其中范围为矢量范围,以[MSB:LSB]格式描述。例如:rega;//a为寄存器类型reg[3:0]v;//v为4位寄存器向量类型reg[7:0]m,n;//m和n为8位寄存器类型3.标量与矢量

在VerilogHDL中,线宽为一位的连线和只有一位的寄存器变量称为标量;线宽大于一位的连线和位宽大于一位的寄存器变量为矢量,对矢量进行说明时,矢量的范围由括在中括号中的一对数字表示,中间用冒号相隔:[MSB:LSB]用于矢量范围说明的数字可以是任意整数,但是左边为最高有效位(MSB),右边为最低位(LSB)。例如,reg[7:0]reg_a;//8位寄存器变量reg_awire[7:0]bus_a,bus_b;//线宽为8位的一组线wirea,b;//线宽为1位的连线,该说明可以缺省rega,b,c;//位宽为1位的寄存器4.标量类矢量与矢量类标量

按位或部分位赋值的矢量称为标量类矢量,这相当于多个一位标量的集合,标量类矢量进行类型说明时,需要关键字scalared。不能按位或部分位赋值的矢量称为矢量类矢量,在进行类型说明时,需要关键字vectored。例如,regscalared[7:0]reg_a;//reg_a被定义成标量类矢量,该说明可以缺省关键字scalaredwirevectored[15:0]bus16;//bus16被定义成矢量类矢量标量类矢量的说明可以缺省,就是说没有关键字scalared或vectored的矢量均将被解释成标量类矢量,这是使用最多的一类矢量。5.端口与内部信号

(1)信号可以分为端口信号和内部信号。出现在端口列表中的信号是端口信号,其它的信号为内部信号。

(2)对于端口信号,输入端口只能是连线类型。输出端口可以是连线(wire)类型,也可以是寄存器(register)类型。若输出端口在过程块中赋值则为register类型;若在过程块外赋值,则为wire类型。

(3)内部信号类型与输出端口相同,可以是连线(wire)或寄存器(register)类型。若在过程块(always叙述)中赋值,则为register类型;若在过程块外赋值,则为wire类型。6.其他定义语句(1)参数定义语句参数定义语句经常用于对时延、线宽、寄存器位数等物理量的定义,其方法是用一个文字参数来代替一个数字量,从而增加描述的可读性和可修改性。参数定义的格式:parameter<参数定义>其中参数定义部分给出具体的各个参数与数字之间的关系,各个关系之间用逗号隔开。

例如:modulemodule_name();parametermsb=7,lsb=0,delay=1;//定义参数reg[msb:lsb]reg_a;//使用参数and#delay(x,y,z);……..endmodule2.3运算符

VerilogHDL的运算符除没有加1和减1运算符外,其他运算符与C语言很相似。1.算术运算符(1)加法,实现加法运算,例如a+b。(2)减法,实现减法运算,例如a-b。当写成-b时,它是单目运算符,表示b的补码。(3)乘法,实行乘法运算,例如,a*b。(4)除法,实现除法运算,例如,a/b,通常综合工具不支持。(5)取模,实现取模运算,例如,a%b。通常综合工具不支持。2.位运算符

按位运算的运算符是位运算符,原来的操作数有几位,结果就有几位,若两个操作数位数不同,则短的操作数左端会自动补0处理。(1)按位取反运算符:~(2)按位与运算符:&(3)按位或运算符:|(4)按位异或运算符:^(5)按位同或运算符:^~或~^例如,a=’b0110,b=’b0100则a|b=0110,a&b=0100。3.缩位(归约)运算符

缩位运算符是单目运算符,也是按位进行逻辑运算,但是结果是一位逻辑值。例如,对a[3],a[2],a[1],a0]进行缩位运算时,先对a[3]和a[2]进行缩位运算符指定的运算,产生一位结果,再将这个结果与a[1]进行缩位运算,然后在将产生的结果与a[0]缩位运算,产生最后的结果。(1)与缩位运算符:&(2)或缩位运算符:|(3)异或缩位运算符:^(4)与、或、异或缩位运算符和非操作运算符组成的复合运算符:~&,~|,~^例如,a=’b0110,b=’b0100则|b=1,&b=0,~|a=0。4.逻辑运算符(1)逻辑与运算符:&&(2)逻辑或运算符:||(3)逻辑非运算符:!其中逻辑与和逻辑或为双目运算符,逻辑非为单目运算符。如果操作数是一位的,则1代表真值,0代表逻辑假。如果操作数是多位的,则将操作数看做整体,如果操作数中每一位都是0,则具有逻辑0值,若其中有一位为1,就把这个操作数看作逻辑1值。5.关系运算符关系运算符包含:(1)小于:<(2)大于:>(3)小于等于:<=(4)大于等于:>=关系运算符都是双目运算符,用于比较两个操作数的大小,比较结果是1位逻辑值,值1代表关系成立,值0代表比较关系不成立。6.相等与全等运算符(1)相等运算符:==(2)不等运算符:!=(3)全等运算符:===(4)不全等运算符:!==这四个运算符都是双目运算符,结果是一位的逻辑值。7.逻辑移位运算符(1)逻辑左移:<<(2)逻辑右移:>>设a是操作对象,n是移位位数,则a<<n表示将a左移n位。进行移位操作时,用0填补移出的空位。8.连接运算符

该运算符可以将两组信号用大括号括起来,拼接成一个新的信号。例如,{a,b,c,3’b101},若a,b,c都是一位信号,则该连接运算的结果是6位宽信号。对于一些重复信号,连接运算符有简化表示方法{n{a}},例如:{4{w}}表示{w,w,w,w}[例6]使用连接运算符的全加器moduleaddr(sum,co,ci,ina,inb);output[3:0]sum;//4位宽的和input[3:0]ina,inb;//4位宽的加数与被加数outputco//1位宽的进位输出inputci;//1位宽的进位输入assign{co,sum}=ina+inb+ci;//连接运算endmodule/*将co和sum拼接成一个新信号为{co,sum[3],sum[2],sum[1],sum[0]}.*/9.条件运算符

条件运算符是三目运算符,它的格式是:〈条件表达式〉?〈条件为真时的表达式〉:〈条件为假时的表达式〉例如,assigntri_bus=(drv_enable)?data:16’bz;[例7]描述三态门modulelikebufif(in,en,out);inputin;inputen;outputout;assignout=(en==1)?in:'bz;//如果en=1,则输出out=in,否则输出out=z。endmodule

1.结构描述方法VerilogHDL结构描述只是将图形方式的连接关系转换成文字表达,若是已经有了模块的逻辑图,则可以按照如下步骤将图形转换成VerilogHDL模块。(1)给电路图中的每个输入输出端口命名端口名。(2)给电路图中的内部连线命名连线信号名。(3)给每个逻辑单元命名调用名。(4)命名模块名。(5)书写模块名和输入输出端口,进行端口的类型的说明。(6)依据电路图,描述信号之间的连接关系。3VerilogHDL中的结构描述2.模块调用模块调用是VerilogHDL结构描述的基本构成方式,一个模块可以调用其它模块,则被调用的模块是底层模块,而调用底层模块的模块是顶层模块。模块调用分为两类:一类是调用基本门,另一类是用户自己写的模块调用。模块调用的格式:模块名调用名(端口名列表)调用时注意端口名列表中端口名的排列顺序、输入输出类型,它们都必须与被调用的模块定义保持一致。(1)位置对应调用法将被调用模块定义时的端口名,对应地用与之相连的信号名代替。(2)端口名对应调用法调用格式:定义时的端口名(调用时与之相连的信号名)。模块调用例:模块中端口名对应方式的例子被调用的低层模块:modulecop(out1,out2,in1,in2,in3);outputout1,out2;inputin1,in2,in3;……endmodule第一种情况:在顶层模块中用位置对应方式调用:moduledemo1outputq,qb;inputr,j,k;……copgate1(q,qb,r,j,k);//位置对应调用,cop是模块名,gate1是调用名endmodule第2种情况:在顶层模块中用端口名对应方式调用:moduledemo2;outputq,qb;inputr,j,k;……copgete2(in1(r),in2(j),in3(k),out1(q),our2(qb))//端口名对应调用endmodule第3种情况:在顶层模块中存在不连接端口的调用方式:moduledemo3outputq,qb;inputr,j,k;……copgate1(q,,r,j,k);//不需要qb,但是应该保留out2端口的位置。endmodule

VerilogHDL语言的数据流描述可以很好的描述组合电路。1.连续赋值语句连续赋值语句将值赋给连线信号,格式如下:assign<连线变量>=<表达式>例:assignmux=(s==0)?a:’bz;2.在定义连线类型时赋值连续赋值可作为连线说明的一部分,成为连线说明赋值。wire[3:0]sum=4’b0;//将4’b0赋给sumwireclear=’b1;//将’b1赋给clear4VerilogHDL数据流描述

[例8]描述一个数值比较器。在VerilogHDL中,描述组合逻辑时常使用assign结构。源代码如下:modulecompare(equal,a,b);inputa,b;outputequal;assignequal=(a==b)?1:0;

//a等于b时,equal输出为1;a不等于b时,equal输出为0。endmodule例中equal=(a==b)?1:0是一种在组合逻辑实现分支判断时常使用的格式。

5.1过程块

VerilogHDL对模块的行为描述以过程块为基本单位,一个模块的行为描述由一个或多个并行运行的过程块组成。过程块格式如下:过程语句@(事件控制敏感表)块语句开始标识符:

块名块内局部变量说明一条或多条过程赋值或其他程序语句块语句结束标识符

5VerilogHDL行为描述其中,过程语句就是指关键字initial或always开始的语句,事件控制敏感表只在always语句中出现,用于激活过程语句的执行;块语句标识符分为串行块(begin-end)与并行块(fork-join)两类;块名和块内局部变量说明均为可选项。

1.过程语句initial和always

VerilogHDL中的过程语句只有两条:initial和always。动作如下图所示。(1)两者都是从仿真的0时刻开始执行,但是initial过程语句后面的块语句沿时间轴只执行一次,而always循环重复执行后面的块语句。

(2)initial语句不带触发条件,而always语句常带有触发(激活或敏感)条件,只有当触发条件被满足时,块中的语句才真正开始执行,若触发条件缺省,则触发条件始终成立。(3)一个模块的行为描述可以有多个initial与always语句,这些语句之间相互独立,并行运行。2.块语句(1)串行块

串行块的标识符是begin-end,位于串行块中的语句按串行方式顺序执行。串行块支持综合。(a)串行块中的每条语句,依据块中的排列次序先后逐条执行。块中的每条语句给出的时延都是相对于前一条语句执行结束时的相对时间。(b)串行块的起始执行时间就是串行块中第一条语句开始执行的时间,而结束时间就是串行块最后一条语句执行的结束时间。(c)串行块的行为描述可以形象的理解为硬件电路中,数据在时钟与控制信号的作用下,沿数据通道的各级寄存器之间的传送过程。

例如:beginreg_a=reg_b;reg_c=reg_a;end(2)并行块

并行块的标识符是fork-join,位于并行块中的语句按并行方式同时被执行。并行块是不可综合的,在测试文件中很常用。(a)并行块中的每条语句都是同时开始并行执行的,各条语句执行的过程与语句在块中的先后次序无关,每条语句的延时都是相对于并行块开始执行的绝对时间。(b)并行块的行为描述可以形象的理解为硬件电路上电后,各个电路模块同时开始执行的过程。例:forkreg_a=reg_b;reg_c=reg_a;join5.2过程赋值语句

VerilogHDL对模块的行为描述由一个或多个并行运行的过程块构成,而位于过程块中赋值语句称为过程赋值语句。在过程赋值语句中表达式左边的信号必须是寄存器类型(如reg类型);在过程赋值语句等式右边可以是任何有效的表达式,数据类型也没有限制。如果一个信号没有声明则缺省为wire类型,使用过程赋值语句给wire赋值会产生错误。过程赋值的基本格式是:<寄存器变量>=<表达式>。例:如果sum定义为寄存器信号,而carry为连线信号,则在过程块中有:sum=a^b^cin;//正确carry=a&b|a&!b&cin|!a&b&cin;//错误1.过程赋值语句的延时模式如果考虑赋值过程的定时问题,则有如下的延时赋值格式:<定时控制><寄存器变量>=<表达式>所谓延时模式就是经过定时控制所确定的延时后,再计算右端表达式的值,并把结果赋给左端的寄存器变量。其中定时控制又可分为如下两种:

(1)延时控制

直接给出延迟的时间称为延时控制(又称为简单延时),例如,#delaya=b;表示从b到a延时delay个时间单位。延时控制语句用于描述仿真硬件电路时的激励信号,或是仿真硬件自身的时延。[例9]如下的描述就是用过程语句initial与always作成一个周期为cycle的时钟。moduleclock_gen(clk);outputclk;regclk;parametercycle=20;//定义参数initialclk=0;//只执行1次的过程块,使clk初值为0always//重复执行的过程块#(cycle/2)clk=~clk;//延时(cycle/2)后使时钟取反endmodule(2)事件控制

事件控制以”@”开头,后面紧跟的是事件敏感表,包括如下几种:a)@(信号名)其中,信号名通常是一位标量,也可以是多位矢量,数据类型没有限制,其含义是只有检测到信号名所确定的信号发生变化时,后面的赋值语句才能执行。例如,@(clock)reg_a=reg_b;//当时钟信号clock发生变化的时候,执行reg_a=reg_b。b)@(posedge信号名)

与前一情况相比,只关心信号上升沿(posedge)跳变的情况。例如,@(posedgeclock)reg_a=reg_b;//当时钟上升沿到来的时候,执行reg_a=reg_b。c)@(negedge信号名)只关心信号下降沿(negedge)跳变的情况。例如,@(negedgeclock)reg_a=reg_b;//当时钟下降沿到来的时候,执行reg_a=reg_b。d)@(敏感事件1or敏感事件2or敏感事件3……)在这个表达式中,敏感事件可以是上面(a)、(b)、(c)三类事件控制中的任一种,只要所列举的任意一种情况发生,都将激活事件控制,各个敏感事件之间是“或”的关系。例如,@(posedgeresetornegedgeclear)reg_out=0;

[例10]一个加法器的描述,该加法器在时钟下降沿时输出半加和。modulereg_adder(out,a,b,clk);inputclk;input[2:0]a,b;output[3:0]out;reg[3:0]out;reg[3:0]sum;always@(aorb)//若a或b发生任何变化,执行如下语句,实现加法运算sum=a+b;//赋值语句sum=a+balways@(negedgeclk)//在clk下降沿执行如下语句,将相加和输出out=sum;//将加法和赋予寄存器信号outendmodule2.阻塞型过程赋值与非阻塞型过程赋值

等号赋值符“=”,在VerilogHDL中称为阻塞(blocking)型过程赋值符,该赋值符的特点是它在串行块的执行过程中,前一条语句没有完成赋值过程之前,后面的语句不能执行,阻塞的意义就是前一条语句阻塞了后面语句的执行。非阻塞(non_blocking)赋值符“<=”可以改变阻塞的情况,在串行块中,非阻塞赋值符是并行执行的。

图11-3阻塞型赋值示意图例如,阻塞赋值:a=1;b=a;c=b;结果是a、b、c都等于1,相当于右图所示的逻辑电路。图11-4非阻塞型示意图非阻塞赋值:a<=1;b<=a;c<=b;则a等于1,b是a的老值,c是b的老值。相当于下图所示的逻辑电路。[例11]如果实现图11-5所示的逻辑图,必须在过程块中使用阻塞型赋值语句,程序如下:moduleblocking(a,b,c,x,y);inputa,b,c;outputx,y;regx,y;always@(aorborc)beginx=a&b;//阻塞赋值y=x|c;endendmodule[例12]串行块与阻塞型赋值语句的例子。图4-6例12描述电路的示意图moduledemo1(reg_a,reg_b,d,clock);inputd,clock;outputreg_a,reg_bregreg_a,reg_b;always@(posedgeclock)//时钟上升沿到来时beginreg_a=d;//该语句不执行,下一个赋值语句不能执行reg_b=reg_a;endendmodule图4-6例13描述电路的示意图[例13]串行块与非阻塞赋值语句的例子。moduledemo1(reg_a,reg_b,d,clock);inputd,clock;outputreg_a,reg_bregreg_a,reg_b;always@(posedgeclock)beginreg_a<=d;//reg_a的输出为dreg_b<=reg_a;//同时赋值,reg_b的输出为reg_a的老值endendmodule在实现组合逻辑的assign结构中,几乎都采用阻塞赋值语句。因为非阻塞逻辑不能描述多级组合逻辑。而在顺序always块中,应该采用非阻塞赋值。因为阻塞赋值不能描述多级时序逻辑。3.连续赋值语句

VerilogHDL语言中有两类赋值语句,一类是上面介绍的过程赋值语句,另外一类是连续赋值语句,它们之间的区别是:(1)赋值对象不同

连续赋值语句用于连线类信号,过程赋值语句用于寄存器类信号。(2)赋值语句的实现过程不同连线信号一旦被连续赋值语句赋值后,赋值语句右端表达式中的信号有任何变化,都将反映到左端的连线变量中;过程赋值语句只有在执行时才有效,且赋值过程的具体执行时刻还受定时控制和延时模式控制。(3)语句的位置不同连续赋值语句不能出现在过程块中;而过程赋值语句只能出现在过程块中。(4)语句结构不同

连续赋值语句以assign开头;而过程赋值不需要先导字。

[例14]用连续赋值符实现与门:moduledemo1(c,a,b);inputa,b;outputc;assignc=a&b;//连续赋值语句endmodule[例15]同样的与门用过程赋值符实现:moduledemo1(c,a,b);inputa,b;outputc;regc;//定义寄存器变量always@(a

orb)c=a&b;//过程赋值语句endmodule6.1if-else语句

1.if(条件表达式)块语句

当条件表达式成立时,执行后面的块语句,否则不执行。例如,always@(enableordata)if(enable)out=data;//如果enable等于1则执行语句out=data6VerilogHDL语言中的分支语句2.if(条件表达式)块语句1else块语句2当条件表达式成立时,执行块语句1,否则执行块语句2。always@(enableordata_aordata_b)if(enable)out=data_a;elseout=data_b;3.if(条件表达式)块语句1elseif(条件表达式)块语句2……elseif(条件表达式)块语句nelse(条件表达式)块语句n+1if-else语句可以嵌套使用,使用方法同C语言,注意else与最近的if搭配。[例16]同步清零的D触发器moduledff(q,d,clr,clk);outputq;inputd,clr,clk;regq;always@(posedgeclk)//时钟上升沿是敏感信号if(!clr)q=0;elseq=d;endmodule6.2case语句1.case语句语句格式:case(敏感表达式)值1:块语句1值2:块语句2……值n:块语句ndefault:块语句n+1endcase

[例17]bcd码到7段共阳数码管译码器。数码管各段排列顺序为abcdefg,低电平有效。modulebcd(ag,bcd);//ag是译码器输出,bcd是译码器输出output[6:0]ag;input[3:0]bcd;//输入BCD码reg[6:0]ag;always@(bcd)begincase(bcd)4'd0:ag=7'b0000001;//显示数字0高位为a段,低位是g段4'd1:ag=7'b1001111;//显示数字14'd2:ag=7'b0010010;//显示数字24'd3:ag=7'b0000110;//显示数字34'd4:ag=7'b1001100;//显示数字4

4'd5:ag=7'b0100100;4'd6:ag=7'b0100000;4'd7:ag=7'b0001111;4'd8:ag=7'b0000000;4'd9:ag=7'b0000100;//显示数字94'd10:ag=7'b0001000;//显示数字A4'd11:ag=7'b1100000;4'd12:ag=7'b0110001;4'd13:ag=7'b1000010;4'd14:ag=7'b0110000;4'd15:ag=7'b0111000;//显示数字Fendcaseendendmodule[例18]4选1数据选择器modulemux(a,b,c,d,s,o);//a、b、c、d是数据,s是选择信号,o是输出信号

inputa,b,c,d;

input[1:0]s;

outputo;

rego;

always@(aorborcordors)

begin

case(s)

2'b00:o=a;

2'b01:o=b;

2'b10:o=c;

default:o=d;

endcase

endendmodule11.9基于VerilogHDL语言的组合逻辑电路设计

组合逻辑电路是输出仅与当前输入信号有关的的电路,描述组合电路可用always块或连续赋值assign语句。1.always块实现组合电路在使用always块实现组合电路时,需要将所有影响always块内赋值的信号都列入always的敏感信号表中,同时注意在always块内部赋值一定要使用声明过的reg型信号。在敏感信号表中不能有描述时钟边沿的posedge和negedge关键字。7基于VerilogHDL语言的组合逻辑电路设计[例19]8-3线编码器1moduleencoder1(none_on,out2,out1,out0,h,g,f,e,d,c,b,a);inputh,g,f,e,d,c,b,a;//编码器输入信号,可以是按钮信号,高电平有效outputout2,out1,out0;outputnone_on;reg[3:0]outvec;assign{none_on,out2,out1,out0}=outvec;//连接运算always@(aorborcordoreorforgorh)//always过程块,敏感信号中没有边沿描述关键字begin if(h)outvec=4'b0111;//使用如果语句,如果h为1,则输出outvcc等于4'b0111 elseif(g)outvec=4'b0110;

elseif(f)outvec=4'b0101; elseif(e)outvec=4'b0100; elseif(d)outvec=4'b0011; elseif(c)outvec=4'b0010; elseif(b)outvec=4'b0001; elseif(a)outvec=4'b0000; elseoutvec=4'b1000;endendmodule

2.连续赋值语句实现组合电路使用连续赋值语句Assign需要注意:(1)连续赋值的信号型式一定是连线wire型。(2)使用assign关键字,格式是:assign被赋值的连线变量=表达式;(3)只要等式右侧的值发生改变时,就会重新对左侧被赋值变量进行赋值。(4)所有output和inout引脚都是连线变量,不需要特别的连线变量声明。[例20]8-3线编码器2moduleencoder(none_on,out2,out1,out0,h,g,f,e,d,c,b,a);inputh,g,f,e,d,c,b,a;outputnone_on,out2,out1,out0;wire[3:0]outvec;assignoutvec=h?4'b0111:g?4'b0110:f?4'b0101:e?4'b0100:d?4'b0011:c?4'b0010:b?4'b0001:a?4'b0000:4'b1000;//条件操作符assignnone_on=outvec[3];//正在编码信号,用于编码器级连assignout2=outvec[2];assignout1=outvec[1];assignout0=outvec[0];endmodule例214选1数据选择器(采用if叙述)。modulemux(a,b,c,d,s,o);//a,b,c,d是数据输入,s是选择信号,o是输出

inputa,b,c,d;

input[1:0]s;

outputo;

rego;

always@(aorborcordors)//always块实现组合电路

begin

if(s==2'b00)o=a;

elseif(s==2'b01)o=b;

elseif(s==2'b10)o=c;

elseo=d;

endendmodule例22采用case语句描述的3-8译码器,输出高电平有效。modulemux(sel,res);//sel是译码输入,res是译码输出(高电平有效)

input[2:0]sel;

output[7:0]res;

reg[7:0]res;

always@(selorres)

begin

case(sel)

3'b000:res=8'b00000001;

3'b001:res=8'b00000010;

3'b010:res=8'b00000100;

3'b011:res=8'b00001000;

3'b100:res=8'b00010000;

3'b101:res=8'b00100000;

3'b110:res=8'b01000000;

default:res=8'b10000000;

endcase

endendmodule可以使用always块和连续赋值assign语句实现时序电路。1.使用always块实现触发器只要在always块的敏感信号表中定义有效的时钟沿,然后使用过程赋值语句对信号赋值,就可以实现触发器或寄存器了。需要注意的是在always块中的过程赋值语句只能对reg型的信号进行赋值。8基于VerilogHDL时序电路设计[例23]D触发器moduledff(q,a,b,clk);outputq;inputa,b,clk;regq;always@(posedgeclk)//时钟的上升沿beginq<=a|b;//D触发器的驱动方程是a|bendendmodule在这个例子中,D触发器的D端输入信号是a|b。2.使用连续赋值语句实现电平敏感的锁存器在VerilogHDL中实现电平敏感的触发器最好使用连续赋值语句assign。[例24]电平敏感的同步锁存器modulelatch(q,a,b,clk);outputq;inputa,b,clk;assignq=clk?(a|b):q;endmodule

该例描述的是电平控制的同步锁存器,当时钟信号为1时,q就是

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论