VHDL语言实用教程_第1页
VHDL语言实用教程_第2页
VHDL语言实用教程_第3页
VHDL语言实用教程_第4页
VHDL语言实用教程_第5页
已阅读5页,还剩112页未读 继续免费阅读

下载本文档

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

文档简介

VHDL实用教程雷永辉VHDL硬件描述语言及应用

-----------一种很好的数字系统硬件电路的形式化描述实现绪论EDA与FPGASSI(通用数字芯片)到MCU(单片机)FPGA/CPLD(现场可编程门阵列和复杂可编程逻辑器件)是一种发展趋势EDA(electronicdesignautomation,电子设计自动化)是一个软件平台,指利用计算机,通过软件方式的设计和测试,达到对既定功能的硬件系统的设计和实现。如quartusII7.2,完成HDL文件的逻辑编译,逻辑简化,逻辑综合及优化,布局布线,仿真并产生具体芯片的目标文件并下载等FPGA/CPLD与EDA技术的发展,使用文本描述电路(HDL)的设计方式流行起来VHDL语言概述HDL:HardwareDescriptionLanguageVHDL:由美国国防部开发,1987年由IEEE标准化,1993年进一步修订Verilog:1983年由GatewayDesignAutomation公司开发,1990年被推向公众领域,1995年成为IEEE标准TOPTODOWN设计方法DowntoTop:元件选型到逻辑设计到系统设计调试Toptodown:对系统功能进行行为描述、定义和仿真(与具体的物理芯片无关),确定设计的可行性和正确性,然后利用EDA工具把把功能描述转换成具体目标芯片网表进行布局布线及后仿真,确保实际系统性能。在这种设计思想下的设计师应具有以下设计思想:

1、设计工程师首先要考虑规划出能完成某一具体功能、满足自己产品系统设计要求的某一功能模块

2、利用某种方式(如HDL硬件描述语言)把功能描述出来,通过功能仿真(HDL仿真器)以验证设计思路的正确性

3、当所设计功能满足需要时,再考虑以何种方式(即逻辑综合过程)完成所需要的设计,并能直接使用功能定义的描述VHDL的EDA过程对初学者的几点建议重要性:FPGA是电子设计领域中最具活力和发展前途的一项技术,它的影响丝毫不亚于单片机的发明和应用应用领域:PLD能完成任何数字器件功能,上至高性能CPU,下至基本的逻辑电路要求基础:数字电路特别精通,特别是时序和逻辑的思维习惯,这也是数字电路设计的高级境界学习方法:FPGA开发平台和开发流程,对PLD结构的了解可以提高设计的效率和可靠性,如原来做过单片机要变串行思维为并行思维,语言和平台是工具,设计的核心是时序和逻辑的物理实现PLD开发系统PLD开发系统包括硬件和软件两部分。硬件部分:计算机、下载电缆或编程器;软件部分:集成开发系统。

Altera公司:MaxplusⅡ、QuartusⅡXilinx公司:Foundation、ISELattice公司:SynarioSystem、ispEXPERTSystem四、PLD设计流程设计准备设计输入设计处理器件编程功能仿真时序仿真器件测试PLD设计准备在设计之前,首先要进行方案论证和器件选择等设计准备工作。设计者首先要根据任务要求,判断系统的可行性。系统的可行性要受到逻辑要求合理性、成本、开发条件、器件供应等方面的约束。若系统可行,则根据系统所完成的功能及复杂程度,对器件本身的资源和成本、工作速度及连线的可布性等方面进行权衡,选择合适的设计方案和合适的器件类型。设计输入将所设计的电路的逻辑功能按照开发系统要求的形式表达出来的过程称为设计输入。通常,设计输入有如下三种方式:(1)原理图输入方式适用于对系统及各部分电路很熟悉的场合。(2)硬件描述语言输入方式硬件描述语言是用文本方式描述设计,硬件描述语言有ABEL、AHDL、VHDL、Verilog等,其中VHDL和Verilog已成为IEEE标准。(3)波形输入方式设计处理逻辑优化把逻辑描述转变为最适合在器件中实现的形式,优化使设计所占用的资源最少。逻辑综合根据设计描述,对给定的硬件结构组件,最终获得门级电路甚至更底层的电路描述文件,即将多个模块化设计文件合并为一个网表文件。适配确定优化后的逻辑能否与器件中的宏单元和I/O单元适配。分割将大的设计分割为多个便于器件内部资源实现的逻辑小块的形式。设计校验设计校验过程包括功能仿真和时序仿真。

功能仿真时序仿真器件编程器件编程就是将开发系统生成的目标文件下载到可编程逻辑器件中,来定义内部模块的逻辑功能以及它们的相互连接关系。

两种编程方式:编程器下载电缆PLD开发系统PLD开发系统包括硬件和软件两部分。硬件部分:计算机、下载电缆或编程器;软件部分:集成开发系统。

Altera公司:MaxplusⅡ、QuartusⅡXilinx公司:Foundation、ISELattice公司:SynarioSystem、ispEXPERTSystem三、PLD电路设计的特点1、设计简单,方便;2、电路系统可以集成在一片芯片上;3、电路设计不依赖于器件进行设计;4、电路系统很容易完善和升级。器件选择:(1)电路系统所完成的功能及复杂程度;(2)器件本身的资源和成本、性能参数、器件编程工艺等方面进行权衡。外部示意图内部示意图LIBRARYieee;USEieee.std_logic_1164.all;ENTITYmcu_collectISPORT ( iclk:INSTD_LOGIC; in1:INSTD_LOGIC; in2:INSTD_LOGIC; in3:INSTD_LOGIC; in4:INSTD_LOGIC; in5:INSTD_LOGIC; o1:OUTSTD_LOGIC; o2:OUTSTD_LOGIC; o3:OUTSTD_LOGIC; o4:OUTSTD_LOGIC; o5:OUTSTD_LOGIC); ENDmcu_collect;ARCHITECTUREmcu_collect_architectureOFmcu_collectIS BEGINk1:process(iclk)beginif(rising_edge(iclk))then o1<=in1; o2<=in2; o3<=in3; o4<=in4; o5<=in5;endif;endprocessk1;ENDmcu_collect_architecture;VHDL入门与程序结构第二章结构概述完整的设计实体的最低要求是能被综合器接受并能作为一个独立设计单元(元件)存在的vhdl程序一个实用的vhdl程序一般由库(library)、实体(entity)和结构体(archtecture)组成完整的设计实体由内部和外部组成,内组由实际功能的描述组成,为不可视部分,外部由实体名和端口组成,为可视部分。(看实例)实例LIBRARYieee;USEieee.std_logic_1164.all;USEieee.std_logic_arith.all;USEieee.std_logic_unsigned.all;ENTITYtest1IS PORT (

iclk:INSTD_LOGIC;

oclk:OUTSTD_LOGIC );

ENDtest1;ARCHITECTUREtest1_architectureOFtest1ISsignalcount:std_logic_vector(30downto0);

BEGINoclk<=count(22);k1:process(iclk)beginifrising_edge(iclk)then count<=count+1;endif;endprocessk1;ENDtest1_architecture;VHDL语言程序的基本构成示例库、包集合说明实体说明构造体库与包集合用于存放预先编译好的程序包(PACKAGE)和数据集合体,以便不同的VHDL设计使用(注:包集合存在于库中)库的说明总是放在设计单元的最前面,如:

LIBRARYieee;前面LIBRARY为关键字,后面ieee为库名称库的种类及使用VHDL语言中的库分为5类:IEEE库、STD库、ASIC矢量库、WORK库和用户自定义的库系统默认的库存放路径为:c:\altera\72\quartus\libraris\vhdl除STD库和WORK库外,其它库在使用前必须加以说明,同时还应说明使用库中的具体包集合,如:

LIBRARYieee; USEieee.std_logic_1164.all; USEieee.std_logic_arith.all; USEieee.std_logic_unsigned.all;std_logic_arith与std_logic_unsigned存放在c:\altera\72\quartus\libraris\vhdl\synopsys下的syn_srit.vhd和ayn_unsi.vhd两文件中库的作用范围库的说明语名作用范围是从一个实体说明开始到它所需结构和配置结束为止当一个源程序中具有多个实体时,每个实体前都应加库说明语句,即使完全一样也要重复书写如下:库说明在多实体程序中使用库分类介绍IEEE库STD库ASIC矢量库WORK库用户自定库

作用:

ENTITY(实体)用于定义电路的外观,即I/O端口的类型和数量。定义格式:Entity

实体名

is

Port(a:

inbit;

b:inbit;

c:outbit);End

实体名;ENTITY定义区端口名数据类型端口模式端口模式(MODE)有以下几种类型:

IN;OUT;INOUT;BUFFER

端口模式可用下图说明:(黑框代表一个设计或模块)

INOUTBUFFERINOUTENTITY定义区VHDL结构要点注意简单地说

In

不可以出现在<=或:=的左边

out不可以出现在<=或:=的右边

buffer可以出现在<=或:=的两边In信号只能被引用,不能被赋值out信号只能被赋值,不能被引用buffer信号可以被引用,也可以被赋值VHDL中的注意事项在VHDL语言中,大小写不加区分,但在代码中巧妙应用大小写,可以使代码变得易于阅读和规范实体名必须与VHDL文件名相同,否则编译会出错信号与变量,过程与函数的区分类属参数说明类属参数说明必须放在端口说明之前,用于指定参数LIBRARYieee;USEieee.std_logic_1164.all;USEieee.std_logic_arith.all;USEieee.std_logic_unsigned.all;ENTITYtest_genericIS

GENERIC(m:TIME:=100ns); PORT (

idata:INSTD_LOGIC;

odata:OUTSTD_LOGIC );ENDtest_generic;ARCHITECTUREtest_generic_architectureOFtest_genericISBEGINodata<=idataAFTERm;ENDtest_generic_architecture;端口说明端口名是赋于每个外部引脚的名称,通常用一个或几个英文字母,或者用英文字母加数字命名端口方向端口方向是用来定义外部引脚的信号方向OUT与BUFFER的区别端口的数据类型端口的数据类型一般使用std_logic与std_logic_vectorStd_logic数据类型:是位逻辑数据类型,其取值只能是两个逻辑值‘0’和‘1’中之一Std_logic_vector:是逻辑总线说明数据类型,取值是一组二进制位的值ENTITYtest_genericIS

GENERIC(m:TIME:=100ns); PORT( idata1,idata2,idata3,idata4:INSTD_LOGIC;

odata:OUTSTD_LOGIC_VECTOR(3DOWNTO0));ENDtest_generic;Idata1,idata2,idata3,idata4只能取‘0’或‘1’;odata只能取“0000”,“0001”,“0010”,“0011”,“0100”….“1111”

ExempleofENTITYGENERIC所定义的元件叫做参数化元件,即元件的规模或特性由GENERIC的常数决定,利用GENERIC可以设计更加通用的元件,弹性地适应不同的应用

端口信号名在实体之中必须是唯一的,信号名应是合法的标识符分别有IN、OUT、INOUT、BUFFER、LINKAGE

常用的有INTEGER、STD_LOGIC、STD_LOGIC_VECTOR

ARCHITECTURE(构造体或结构体)所有能被仿真的实体都由结构体(ARCHITECTURE)描述,即结构体描述实体的结构或行为,一个实体可以有多个结构体,每个结构体分别代表该实体功能的不同实现方案结构体格式:

ARCHITECTURE

结构体名

OF

实体名

IS

[定义语句(元件例化);]

BEGIN

并行处理语句;

END

结构体名;结构体名是对本结构体的命名,它是该结构体的惟一名称,虽然可以由设计人员自由命名,但一般都将命名和对实体的描述结合起来,例如:行为描述(BEHAVE),寄存器传输级(RTL)

ExempleofARCHITECTURE定义语名:置于architecture与begin之间,用于定义结构体中的信号、常数、数据类型和函数并行处理语名:置于begin与end之间,具体描述构造体的行为与连接关系,语句的执行与书定语名的顺序无关

构造体的子结构子结构的使用使设计者可以把整个电路分成若干个相对独立的模块来进行描述子结构有:BLOCK,PROCESS,SUBPROGRAMSBLOCK与ARCHITECTURE相当于整体原理图与子原理图关系,block结构内部语句是并发的,如希望BLOCK有条件执行,可采用卫式BLOCK,如下:

ARCHITECTURE的PROCESS子结构PROCESS中的语句是顺序执行的,一个结构体中可以有多个PROCESS,它们之间可以通过信号进行通信PROCESS的启动受敏感信号控制,敏感信号的变化会直接导致PROCESS的启动进程名,可省参数说明:只在本进程中有效顺序执行语句

ARCHITECTURE的SUBPROGRAM子结构与高级语言中的子程序概念差不多,可以反复调用,但不能重入,结构内语句为顺序执行,有Procedure和Function之分多个过程和函数汇集在一起构成包集合,几个包集合汇集在一起构成库数据类型及运算操作符第三章

VHDL中的数据对象在逻辑综合中,VHDL常用的数据对象有信号、变量及常量

信号SIGNAL:为全局变量,定义格式:

SIGNAL

信号名:

数据类型[:=初始值];

赋值格式:

目标信号名<=表达式常在结构体中用赋值语句完成对信号赋初值的任务,因为综合器往往忽略信号声名时所赋的值

常量:全局变量,在设计中描述某一规定类型的特定值不变,如利用它可设计不同模值的计数器,模值存于一常量中,对不同的设计,改变模值仅需改变此常量即可,就如上一章所说的参数化元件。

定义格式:

CONSTANT

常数名:数据类型:=表达式

变量(VARIABLE):用于声明局部值或用于子程序中,变量的赋值符号为“:=”,

定义格式:

VARIABLE

变量名:

数据类型[:=初始值]

VHDL中的信号与变量信号是实际的,是内部的一个存储元件(SIGNAL)或者是外部输入(IN、OUT、INOUT、BUFFER)变量是虚的,仅是为了书写方便而引入的一个名称,常用在实现某种算法的赋值语句当中如果在一个进程中多次为一个信号赋值,只有最后一个值会起作用,这与SIGNAL的硬件特性有关变量赋值时,变量的值改变是立即发生的信号赋值用“<=”,变量赋值用“:=”数据对象综合实例ARCHITECTUREtest_object_architectureOFtest_objectISconstantn:std_logic:='1';signala:std_logic;BEGINk1:process(idata1)variablecount:integerrange0to10:=0;beginifrising_edge(idata1)then count:=count+1; ifcount=1then

odata<=n;

elsifcount=8then count:=0; else

odata<=idata2; endif;endif;endprocessk1;ENDtest_object_architecture;

VHDL的数据类型VHDL是一种强类型语言,对于每一个常数、变量、信号、函数及设定的各种参量的数据类型(DATA

TYPES)都有严格要求,相同数据类型的变量才能互相传递和作用,标准定义的数据类型都在VHDL标准程序表STD中定义,实际使用中,不需要用USE语句以显式调用

VHDL常用的数据类型有三种:标准定义的数据类型、IEEE预定义标准逻辑位与矢量及用户自定义的数据类型标准定义的数据类型

Boolean布尔量:取值为FALSE和TRUE

CHARACTER字符:ASCII字符,编程时用单引号括起来,如‘A’

STRING字符串:字符失量,双引号括起来,如“ADFBD”

INTEGER整数:32位,范围从-(231-1)到(231-1);

REAL实数:实数类型仅能在VHDL仿真器中使用,综合器不支持

BIT位:取值为0或1;

TIME时间:范围从-(231-1)到(231-1),表达方法包含数字、(空格)单位两部分,如(10

PS);

BIT_VECTOR位矢量:其于BIT数据的数组,使用矢量必须注明宽度,即数组中的元素个数和排列,如SIGNAL

A:

BIT_VECTOR(7

DOWNTO

0)

NATUREAL自然数:整数的一个

POSITIVE正整数:

SEVRITY

LEVEL错误等级:在VHDL仿真器中,错误等级用来设计系统的工作状态,共有四种可能的状态值:NOTE,WARNING,ERROR和FAILURE

IEEE预定义的标准逻辑位与矢量STD_LOGIC:工业标准的逻辑类型,取值为‘0’、‘1’、‘Z’、‘X’(强未知)、‘W’(弱未知)、‘L’(弱0)、‘H’(弱1)、‘—’(忽略)、‘U’(未初始化),只有前四种具有实际物理意义,其他的是为了与模拟环境相容才保留的STD_LOGIC_VECTOR:工业标准的逻辑类型集,STD_LOGIC的组合用户自定义的数据类型用户自定义的数据类型有枚举类型、整数类型和实数类型、数组类型、记录类型四种枚举类型:

TYPE

数据类型名

IS

(枚举文字,枚举文字,.

.

.

.)整数类型与实数类型是标准包中预定义的整数类型的子集,由于综合器无法综合未限定范围的整数类型的信号或变量,故一定要用RANGE子句为所定义整数范围限定范围以使综合器能决定信号或变量的二进制的位数。

格式:

TYPE

数据类型名

IS

RANGE

约束范围;数组类型:数组是同一类型数据集合,记录内元素类型可以不同

TYPE

数据类型名

IS

ARRAY(下限

TO

上限)

OF

类型名称,多维数组不能生成逻辑电路,只能用于仿真图形记录类型:

TYPE

记录类型名

IS

RECODE

元素名:

数据类型名;

元素名:

数据类型名;

。。。。。。。。。。。。。

END

RECODE

用户自定义的数据类型举例RANGE<>其范围一般由调用者传递的参数决定用户自定义的子类型对已定义类型作一些范围限制(也可以与原数据类型完全一致),定义格式为:

SUBTYPE子类型名IS数据类型名(范围)数据类型转换VHDL中,不同数据类型不能直接进行运算和代入,要进行运算或代入必需对类型进行转换,使之一致

BIT_VECTOR与STD_LOGIC_VECTOR代入STD_LOGIC_VECTOR的值只能是二进制,代入BIT_VECTOR的值除二进制外还可以是八进制和十六进制数据类型的限定VHDL中有时可以用上下文关系来判断某一数据的数据类型,如果不能判断出来,就必需对数据进行类型限定,类似C中的强制类型转换运算符运算符的使用逻辑运算、算术运算、关系运算的左右以及代入的数据类型一定要相同VHDL中左右没有优先级的差异,如

x<=(aANDb)OR(NOTcANDd)能真正综合的算术运算符只有“+”,“-”,“*”;“MOD”,“REM”,“/”分母是2乘方时可综合,由于硬件特性,后4种应慎用,最好作适当变通“《=”应通过上下文关系判定是关系运算符还是代入符位的连接也可以采用集合的方式,把并置符改成“,”即可,如:temp_4<=(‘1’,‘0’,‘1’,‘0’);其中temp_4为4位宽的位失量,但这种方式不能用于位失量连接,如:temp_4<=(temp_2,temp_2);就是错误的Vhdl顺序语句第四章描述语句分类顺序描述语句和并发描述语句是VHDL程序设计中两大基本描述语句系列顺序描述语名只出现在PROCESS和SUBPROGRAM中,语句按出现的次序加以执行对于FPGA搭建的应用系统,元件在定义的仿真时该应该是并发工作的,并发语句就用于表示这种并发行为顺序语句顺序描述语句只能出现在进程(Process)或子程序中,它定义进程或子程序所执行的算法。顺序描述语句按这些语句在进程或子程序中出现的顺序执行,这一点与高级语言类似。

VHDL中常用的顺序描述语句包括:信号和变量赋值、Wait、If、Case、Loop、Next、Exit、断言语句、过程调用语句、空语句等。进程(Process)所有的顺序描述语句都只能在进程(process)中使用,进程内是顺序执行,进程与进程之间是并发的,有点类似于计算机操作系统中“进程”的概念。Process语句的格式:

[进程名]:Process(敏感信号列表)

Begin

顺序描述语句;

EndProcess;

Process语句从Process开始,到End

Process结束,进程名可以省略。功能相对独立的模块可以用一个进程来描述。进程(Process)

Process语句的格式:例1:

Entitymux2Is

Port

(a,b:Instd_logic;

s:In

std_logic;

f:Out

std_logic);

Endmux2;

ArchitecturebehaviorOfmux2Is

Begin

mux2:Process(a,b,s)

Begin

If(s=‘0’)Thenf<=a;

Elsef<=b;

EndIf;

EndProcess;

Endbehavior;进程(Process)

Process的启动和敏感信号列表:进程在仿真运行中,总是处于两个状态之一:执行或挂起。初始启动时,进程处于执行状态,进程中的顺序语句从前向后逐句执行一遍,即从Process执行到EndProcess之前。当最后一条语句执行完后,返回到进程开始的Process语句,进程处于挂起状态。此时,只要该进程的敏感信号列表中任何一个信号发生变化(即信号的值发生变化,如从“1”变到“0”或从“0”变到“1”),进程又再次处于执行状态。然后,再挂起,再执行,一直循环下去,直到仿真结束。从硬件方面来看,一个Process相当于一个电路模块,它的敏感信号列表指明了所有能引起该电路模块状态发生改变的信号。例1中mux2进程的敏感信号列表是(a,b,s),三个信号中的任何一个发生变化,都引起进程重新执行。从硬件特性来看,二选一电路的a,b,s输入的变化都可能引起输出发生变化。进程(Process)

Process的启动和敏感信号列表:敏感信号列表对于进程至关重要,它是进程描述的一个重要组成部分。一般来说,如果描述的是组合电路模块,那么敏感信号列表必须包括所有的输入信号;否则,在综合时会出错,在仿真时将导致一个错误的结果。如果描述的是时序电路模块,那么敏感信号列表只需要包括时钟信号和异步清零/置位信号。因为,触发器的输出只在时钟上升/下降沿才会改变。在一个结构体里可以有多个Process语句,这些Process之间可以通过一些信号相互联系。在一个Process的执行中,某个信号的值发生改变,它会导致另一个(或几个)进程的重新执行,如此构成所有进程的反复执行。进程(Process)中的顺序语句

信号和变量的赋值:信号的赋值语句格式:目标信号名<=表达式;例2:

c<=‘1’;

q<=“010010”;

q(1)<=‘1’;

q(3downto1)<=“001”;

a<=b;

s<=axorb;

x<=y+z;需要特别注意的是:VHDL是强类型语言,左边的信号量和右边的表达式的类型和位长度都必须一致,否则将出错。进程(Process)中的顺序语句

信号和变量的赋值:变量的赋值语句格式:目标变量名:=表达式;例3:

v:=‘1’;

s:=“010010”;变量赋值的符号与信号赋值的符号不同,表达式与信号赋值的表达式写法是完全一样的。变量与信号有明显的区别:变量只在定义它的进程和子程序内有效,无法传递到进程之外;而信号在定义它的结构体内有效。赋给变量的值立即成为当前值;而赋给信号的值必须在进程结束后才能成为当前值。进程(Process)中的顺序语句

转向控制语句:条件控制语句——If语句:

IF语句的基本格式:

If条件Then

If条件Then顺序描述语句; 顺序描述语句;

Else

EndIf;顺序描述语句;

EndIf;

进程(Process)中的顺序语句

转向控制语句:条件控制语句——If语句:例4:EntitydffIs

Port(d:Instd_logic;clk:In

std_logic;

q:Outstd_logic);Enddff;ArchitecturebehaviorOfdffIs

Begin

Process(clk)

Begin

If(clk'eventandclk=’l’)Then

q<=d;

EndIf;

EndProcess;Endbehavior;进程(Process)中的顺序语句

转向控制语句:条件控制语句——Case语句:

Case语句的基本格式:

Case表达式Is

When条件表达式1=>顺序描述语句;

When条件表达式2=>顺序描述语句;

...

When条件表达式n=>顺序描述语句;

EndCase;

Case语句的各个条件表达式之间没有优先级,所以,给定的条件表达式不能有重叠,否则将无法确定执行哪一个分支。而且,如果没有列举出Case和Is之间的表达式的全部取值,则Whenothers=>必不可少。

条件表达式可以是以下格式:When值=>When值1|值2|...|值n=>When值ito值j=>Whenothers=>它们分别表示条件表达式的值是某个确定的值、多个值中的一个、一个取值范围中的一个和其他所有的默认值。进程(Process)中的顺序语句

转向控制语句:

Case语句和If语句的区别:在大多数情况下,能用Case语句描述的逻辑电路,同样也可以用多条件If语句来描述。但有时能用If语句描述的逻辑电路,却不能用Case语句描述。通常在Case语句中,条件表达式(When语句)可以颠倒次序,不致于发生错误。但对于多条件的If语句,却不能颠倒条件的次序。因为在Case语句中,条件表达式是没有优先级的,而多条件的If语句的条件是有优先级的。在If语句中,最前面的条件其优先级最高,越往后优先级越低,也就是说,先处理最起始的条件;如果不满足,再处理下一个条件。而在Case语句中,所有值的判定是并行处理的。例如,优先级编码器可以用If语句来描述,但不可以用Case语句描述。进程(Process)中的顺序语句

转向控制语句:例5(8位优先编码器):EntitypriorityIs

port(I:inbit_vector(7downto0);A:outbit_vector(2downto0);--encodedoutputGS:outbit);--groupsignaloutputEndpriority;Architecturev1OfpriorityIsBegin

process(I)beginGS<='1';--setdefaultoutputsA<="000";

IfI(7)='1'thenA<="111";

ElsifI(6)='1'thenA<="110";

ElsifI(5)='1'thenA<="101";

ElsifI(4)='1'thenA<="100";

ElsifI(3)='1'thenA<="011";

ElsifI(2)='1'thenA<="010";

ElsifI(1)='1'thenA<="001";

ElsifI(0)='1'thenA<="000";ElseGS<='0';Endif;Endprocess;Endv1;进程(Process)中的顺序语句

转向控制语句:循环控制语句——For循环:

For循环语句的基本格式:

[标号:]For循环变量in循环次数范围Loop顺序描述语句;

End

Loop

[标号];这里,标号是可以省略的;循环变量是整数型变量,它不需要在结构体或进程中定义,在循环体(由顺序描述语句构成)中不能通过信号或变量给循环变量赋值。进程(Process)中的顺序语句

转向控制语句:例6

For循环(奇偶校验电路):Entityparity_checkerIs

Port(data:Instd_logic_vector(7downtoO);

p:Outstd_logic);Endparity_checker;ArcLitecturebehaviorOfparity_checkerIs

Begin

Process(data)

Variabletmp:std_logic;

Begin

tmp:=‘0’;

Foriin7downto

0Loop

tmp:=tmp

xor

data(i);

EndLoop;

p<=tmp;

EndProcess;Endbehavior;进程(Process)中的顺序语句转向控制语句:循环控制语句——While循环:

While循环语句的基本格式:

[标号:]While条件Loop顺序描述语句;

End

Loop

[标号];这里,当条件为“真”时,执行循环体中的语句;如果条件为“假”时,则结束循环。在循环体内,必须包含条件式中判别变量的赋值语句,否则会形成死循环。实际上,固定次数的循环一般用For循环,不定次数的循环用While循环比较方便。但在进行需要综合的电路描述时,不定次数的循环较难控制,所以,一般不用While循环。进程(Process)中的顺序语句

转向控制语句:

Next语句:

Next语句的基本格式:

Next[标号]

[When条件];

Next语句用于从循环体跳出本次循环。执行到该语句时,如果条件为“真”时,将结束本次循环,跳到“标号”规定的语句,开始下次循环。如果标号省略,则表示跳到本层循环的起始位置,开始下一次循环。如果标号不省略,则可以跳到多层嵌套循环的指定外层循环起始处。如果“When条件”省略,则执行到Next语句时无条件结束本次循环。如果“When条件”不省略,则条件为True时,结束本次循环。进程(Process)中的顺序语句

转向控制语句:

Exit语句:

Exit语句的基本格式:

Exit[标号]

[When条件];

Exit语句用于结束循环。执行到该语句时,如果条件为“真”时,将结束循环,跳到“标号”规定的语句。如果标号省略,则表示跳到EndLoop语句的后继位置,开始向后执行。如果标号不省略,则可以跳到多层嵌套循环的指定外层循环起始处。如果“When条件”省略,则执行到Next语句时无条件结束循环。如果“When条件”不省略,则条件为True时,结束循环。进程(Process)中的顺序语句

转向控制语句:

Next语句和Exit语句的区别:

Next只结束本次循环,开始下一次循环;而Exit语句结束整个循环,跳出循环体外。进程(Process)中的顺序语句

Wait等待语句(进程挂起语句):进程的状态还可以通过Wait语句来控制,当进程执行到Wait语句时,将被挂起,并设置好再次执行的条件。可以是无限等待(Wait)或有限等待。有限等待的条件可以是:等待一段时间(WaitFor)、等待某些信号发生变化(Waiton)、等待某个条件满足(WaitUntil),这几个条件还可以组合成一个复合条件。进程(Process)中的顺序语句

Wait等待语句(进程挂起语句):

Waiton语句格式:

Waiton信号列表;信号列表可以包括一个或多个信号,信号列表中的任何一个信号的值发生变化,进程将结束挂起状态,进入执行状态,执行Waiton语句后面的语句。如:

Waitona,b,s;它等待信号a、b、s中的任何一个发生变化。进程(Process)中的顺序语句

Wait等待语句(进程挂起语句):例7:Entitymux2Is

Port(a,b:Instd_logic;

s:Instd_logic;

f:Outstd_logic);Endmux2;ArchitecturebehaviorOfmux2IsBegin

mux2:Process(a,b,s)

Begin

If(s=‘0’)Thenf<=a;

Elsef<=b;

EndIf;

EndProcess;Endbehavior;mux2:Process()Begin

If(s=‘0’)Thenf<=a;

Elsef<=b;

EndIf;

Waitona,b,s;EndProcess;进程(Process)中的顺序语句

Wait等待语句(进程挂起语句):

WaitUntil语句格式:

WaitUntil布尔表达式;当布尔表达式为“真”时,进程将结束挂起状态,进入执行状态,执行WaitUntil语句的后继语句。如:

WaitUntila=’1’;此时,当信号量a的值不是’1’时,进程执行到该语句将被挂起,当a的值为’1’时进程再次被启动,继续执行Wait语句的后继语句。进程(Process)中的顺序语句Wait等待语句(进程挂起语句):

WaitFor语句格式:

WaitFor时间表达式;如:

WaitFor30ns;

WaitFor语句只能仿真时使用,不能被综合。进程(Process)中的顺序语句

Wait等待语句(进程挂起语句):复合Wait语句:例如:

Waitonclkuntilclk=‘1’;该语句等待到clk信号的值发生变化,而且clk的值为‘1’(即clk从‘0’变到‘1’时),进程将结束挂起状态,进入执行状态,执行该语句的后继语句。编程时注意等待条件的判别,不要出现“死锁”状态(即无限期等待)。进程(Process)中的顺序语句

空操作语句:格式:

Null;进程(Process)中的顺序语句

断言语句Assert:

Assert语句的格式是:

Assert条件[report输出信息]

[severity级别]断言语句主要作为仿真和调试中的人-机会话,可以给出一个文字串作为警告和错误提示信息。当执行Assert语句时,就会对条件进行判别。如果条件为“真”,则执行下一条语句;如果条件为“假”,则输出由report指定的输出信息和由severity指定的错误级别。在report后面跟的是设计者所写的文字串,通常是说明错误的原因,文字串应该用双引号“”引起来。断言语句不是一条可综合语句,仅仅是为了仿真的方便。进程(Process)中的顺序语句

断言语句Assert:例:

Assert

(B=’1’)

report”Btimedoutat

’1’”;

severityerror;

该断言语句的条件是信号量B=’1’。如果执行到该语句时,信号量B=’0’,说明条件不满足,就会输出report后跟的文字串。该文字串说明,出现了超时等待错误。severity后跟的错误级别告诉操作人员,其出错级别为error。第五章Vhdl并行语句并发信号赋值语句

注意:信号赋值语句在顺序语句里面也有,顺序语句里可以给信号赋值也可以给变量赋值,而顺序语句里只能对变量说明,不能对信号说明。并行语句刚好相反为什么变量不能在并行语句里面说明呢?为什么信号不能在顺序语句里面说明呢?并发语句信号是全局的,变量是局部的

赋值方式一:信号名<=表达式赋值方式二(条件信号赋值):目标信号<=表达式1

WHEN

条件1

ELSE

表达式2

WHEN

条件2

ELSE

表达式3

WHEN

条件3

ELSE

表达式4注意:用条件信号赋值,只有当用进程、IF和CASE难以对电路进行描述时才用;条件信号赋值语句ELSE是必须的、不能进行嵌套且必须用在结构体中的进程之外

赋值方式三(选择信号赋值):WITH

选择条件表达式

SELECT

目标信号<=信号表达式1

WITH

选择条件1

信号表达式2

WITH

选择条件2

信号表达式3

WITH

选择条件3

信号表达式4

WITH

OTHERS

注意:选择信号赋值语句必须用在结构体中的进程之外

并发信号赋值语句的三种形式并发语句

块语句在VHDL语言设计中,块语句常常用来对比较复杂的结构体作结构化描述,格式如下

[块标号:]

BLOCK

[卫式表达式]

[类属子句;]

[端口子句;]

[块说明部分;]

BEGIN

<块语句说明部分;>

END

BLOCK[块标号];

卫式表达式:是一个布尔条件表达式,只有当这个表达式为TURE时,BLOCK语句才被执行;

类属子句:块的属性说明

块说明部分:用于定义USE、子程序、数据类型、子类型、常量、信号和元件

块语句说明部分:用于描述块的具体功能,可以包含结构块中的任何并行语句结构。

注:块语句的作用就是将一个大的结构划成一块一块小的结构,现比较流行原理图和元件的方式,这样更为简洁直观并发语句进程语句进程语句是一种应用广泛的并行语句,一个结构体中可以包括一个或者多个进程语句,结构体中的进程语句是并发关系,即各个进程是同时处理的、并行执行的;但在每一个进程语句结构中,组成进程的各个语句都是顺序执行,在进程语句中是不能用并行语句的。

格式

[进程标号:]PROCESS

[敏感信号表]

[IS][进程语句说明部分;]

BEGIN

<顺序语句部分>

END

PROCESS[进程标号];

注:

1、

敏感信号表列出了进程语句敏感的所有信号,每当其中的一个信号发生变化时,就会引起其他语句的执行,如果敏感信号表不写,那么在PROCESS里面必须有WAIT语句,由WAIT语句来产生对信号的敏感;而当敏感信号表存在时,就不能在PROCESS里再有WAIT语句;

2、

IS可有可无,是由93版规定的

3、

进程语句说明部分是进程语句的一个说明区,它主要用来定义进程语句所需要的局部数据环境,包括数据类型说明、子程序说明和变量说明。

4、

进程语句有两种存在状态,一是等待,当敏感信号没有发生变化时;一是执行,当敏感信号变化时。

5、时钟信号自动进入敏感表

并发语句子程序调用语句子程序分为函数和过程,它们的定义属于说明语句,均可在顺序语句和并行语句里面使用,它们的调用方法不一样。

函数只有一个返回值,用于赋值,可以说在信号赋值的时候就是对函数的调用;

过程有很多个返回值,用于进行处理,准确的来说子程序调用语句就是过程调用语句。并发语句

参数传递语句参数传递语句即在实体中定义的GENERIC,可以描述不由材料和不同工艺构成的相同元件或模块的性能参数(如延时),在定义了GENERIC的实体叫参数化实体,由参数化实体形成的元件在例化时具有很大的适应性,在不同的环境下,只须用GENERIC

MAP来修改参数就可以了使用时,在对元件例化时加在里面就可,比如已经定义了一个AND2的实体,要在EXAMPLE里面使用AND2,要先对AND2进行元件声明,再将AND2例化,如下:

u0:

AND2

GENERIC

MAP(参数值1,参数值2)

PORT

MAP(参数表)

并发语句

元件例化语句一个实体就相当于元件,元件名就相当于实体名,元件要实现的功能在实体里面就已经描述好,比如,同一个文件夹下已经有一个名为A.VHD的文件,如果要在另一个文件B.VHD里面用到A.VHD里面定义的功能,那么可以在B.VHD文件里面通过元件声明和元件例化来调用A这个元件,总的来说调用元件过程就是“建立元件----元件声明------元件例化”,元件调用时不用USE语句。注:元件声明语句属说明语句,不是同步语句,以下对元声的说明是为了更好地了解元件的调用,元件的实例化之前必须要有元件声明

元件声明语句格式

COMPONENT

<元件名>

——元件名就是文件名,即是实体名

[GENERIC

<参数说明>;]

——这就是所产的元件参数

PORT<端口说明>;

END

COMPONENT;

元件例化格式:

元件符:元件名

GENERIC

MAP

(参数表)

PORT

MAP(端口表)

并发语句元件例化语句实例并发语句元件声明元件例化并行断言语句前面已经说过顺序断言语句,这里的断言语句是并行的,可以放在实体说明、结构体和块语句中使用,可以放在任何要观察和调试的点上,而顺序断言语句只能在进程、函数和过程中使用其实断言语句的顺序使用格式和并行使用格式是一样的,因此断言语句是可以应用在任何场所的,格式请看顺序的说明

并发语句思考:是不是所有的VHDL语句都可以归结为顺序语句和并行语句呢?

可以把VHDL语句分为三大类:顺序语句、并行语句和说明语句,其中说语句在没有调用之前是不会参与执行的,如:元件和函数说明,在元件实例化和函数调用前是不参与执行的三类语句的关系是顺语句可以用在并行语句和说明语句当中;说明语句可以用在并行语句当中;而并行语句是不能用在其他语句当中,可以说并行语句属于一种高级形态,是语句的最终形态过程和函数有什么区别?过程可以具有多个返回值(准确来说不是返回值,而是这些信号在过程之中被改变),函数只有一个返回值过程通常用来定义一个算法,而函数用来产生一个具有特定意义的值过程中的形式参数可以有三种通信模式(输入、输出、双向),而函数中的形参只能是输入通信模式(因为函数是用来产生一个值的)过程中可以使用赋值语句或WAIT语句,而函数不可(因为过程是用来处理的)第六章Vhdl的描述风格VHDL语言的构造体描述方式行为描述方式数据流描述方式(寄存器传输描述RTL)结构描述方式行为描述方式所谓行为描述,就是对设计实体的数学模型的描述,其抽象程度远远高于数据流描述方式和结构描述方式.行为描述类似于高级编程语言,当要描述一个设计实体的行为时,无须知道具体电路的结构,只需要用一组状态来描述即可.行为描述的优点在于只需要描述清楚输入与输出的行为,而不需要花费更多的精力关注设计功能的门级实现.数据流描述方式数据流描述是对从信号到信号的数据流的路径形式进行描述,因此很容易进行逻辑综合.由于要对信号的流动路径进行描述,因此要求设计人员对设计实体的功能实现要有一定的了解,有时候还需要对内部电路有清楚的认识,具有一定的难度.结构描述方式结构描述方式就是在多层次的设计中,通过调用库中的元件或是已设计好的模块来完成设计实体功能的描述.在结构体中,描述只表示元件(或模块)和元件(或模块)之间的互连,就像网表一样.当引用库中不存在的元件时,必须首先进行元件的创建,然后将其放在工作库中,通过调用工作库来引用元件.在引用元件时,要先在结构体说明部分进行元件的说明,然后在使用元件进行元件例化.基本演变成原理图+元件的设计方式全加器真值表AiBiCi-1SiCi0000000110010100110110010101011100111111一位全加器的逻辑示意图ΣabCinSCo采用行为描述方法设计一位全加器LIBRARYIEEE;USEIEEE.STD_LOGIC_1164.ALL;ENTITYfull_adderIS

PORT(a,b,Cin:INSTD_LOGIC;

Co,S:OUTSTD_LOGIC);ENDfull_adder;ARCHITECTUREbehavOFfull_adderISBEGIN

PROCESS(a,b,Cin)VARIABLEai,bi,ci,si:INTEGER;BEGINIF(a=‘0’)THEN

ai:=0;ELSE

ai:=1;ENDIF;IF(b=‘0’)THENbi:=0;ELSEbi:=1;ENDIF;

IF(Cin=‘0’)THEN

ci:=0;ELSE

ci:=1;ENDIF;

si:=ai+bi+ci;CASEsiISWHEN0=>S=>’0’;Co=>’0’;WHEN1=>S=>’1’;Co=>’0’;WHEN2=>S=>’0’;Co=>’1’;WHEN3=>S=>’1’;Co=>’1’;WHENOTHERS=>S=>’X’;Co=>’0’;

温馨提示

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

评论

0/150

提交评论