版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
2.1VHDL语言基本结构VHDL是通用的工业标准语言。描述的程序、格式是固定的,语句是规范的。也就是说,VHDL程序有一个标准模式。一个完整的VHDL语言通常包含实体(Entity)、结构体(Architecture)、配置(Configuration)、包集合(Package)和库(Library)五部分。VHDL程序设计基本结构,如图2.1所示。VHDL程序的核心结构如下:第一部分实体描述部分第二部分结构体描述部分下一页返回2.1VHDL语言基本结构
实体描述的是设计单元的外部特征,规定了设计单元有哪些输入信号端口和输出信号端口,或者说设计单元有哪些输入引脚和输出引脚。它是设计单元对外的通信接口。结构体描述的是设计单元的内部结构或逻辑功能。一个设计单元必须有实体和相应的结构体。VHDL程序是对一个设计单元的基本描述,这个设计单元可以是简单的门电路,也可以是复杂的微处理器,其基本的描述结构是一样的,都具备上述三个主干结构。在AlteraQuartusⅡ软件中,VHDL程序有一个基本的模板,在其中填入适当的内容,就能得到所需要的VHDL程序。上一页下一页返回2.1VHDL语言基本结构
2.1.1实体实体说明主要描述的是一个设计单元的外部特征,即对外的输入输出接口以及一些用于结构体的参数定义。简单地说,实体说明就是用来描述所设计硬件系统的外部引脚。在VHDL语言中,一个实体说明的具体格式如下所示:ENTITY<实体名>IS[类属参数说明];[端口说明];[实体说明部分];END[ENTITY]<实体名>;上一页下一页返回2.1VHDL语言基本结构
实体说明必须按照这一结构来编写。实体应以语句“ENTITY<实体名>IS”开始,以语句“END[ENTITY]实体名”结束。其中,实体名可以由设计者自己添加;中间在方括号内的语句描述,在特定的情况下并非是必需的。对于VHDL的编译器和综合器来说,程序文字的大小写是不加区分的,但为了便于阅读和分辨,建议将VHDL的标识符或基本语句关键词,以大写方式表示;而由设计者添加的内容可以以小写方式来表示。如实体的结尾可写为ENDcomp,其中的comp即设计者取的实体名。上一页下一页返回2.1VHDL语言基本结构
2.1.2结构体设计单元中的结构体主要用来描述设计的内部结构或逻辑功能。在设计中,设计人员常常将一个设计实体比喻成一个盒子,实体说明可以被看作一个“黑盒子”,通过它只能了解其输入和输出,无法知道盒子的内容。而结构体描述盒子内部的详细内容。在VHDL语言中,一个结构体的具体格式如下所示ARCHITECTURE<结构体名>OF<实体名>IS[结构体说明部分];BEGIN<并行处理语句>;上一页下一页返回2.1VHDL语言基本结构
END[ARCHITECTURE<结构体名>;用户可以看出,结构体以保留字ARCHITECTURE开始,后面紧跟着的是结构体名;然后是结构体中的结构体说明部分;接下来以保留字BEGIN开始结构体的并行处理语句部分;最后以保留字END结构体名来结束结构体。结构体名由设计者自由定义,是该结构体的唯一名称。OF后面的实体名表示该结构体属于哪一个实体。当一个实体中有多个结构体时,各个结构体名不能相同。结构体名的取法要尽量反映该结构体的特色。上一页下一页返回2.1VHDL语言基本结构
一个完整的结构体由两个基本层次组成:说明语句和功能描述语句两部分。结构体说明是指对结构体需要使用的信号、常数、数据类型和函数进行定义和说明。功能描述语句位于BEGIN和END之间,这些语句具体地描述了结构体的行为。并发处理语句是功能描述的核心部分,也是变化最丰富的部分。并发处理语句可以使用赋值语句、进程语句、元件例化语句、块语句以及子程序等。需要注意的是,这些语句都是并行(同时)执行的,与排列顺序无关。上一页下一页返回2.1VHDL语言基本结构
2.1.3配置配置可以把特定的结构体关联到一个确定的实体,配置语句为较大的系统设计提供管理和工程组织服务。设计者可以利用配置语句选择不同的结构体,使其与要设计的实体相对应;在仿真某一个实体时,可以利用配置选择不同的结构体进行性能对比实验,以得到性能最佳的结构体。配置语句根据不同情况,其说明语句有简有繁。这里介绍较为简单的缺省配置,其格式如下:CONFIGURATION配置名OF实体名ISFOR选配结构体名ENDFOR;END配置名;上一页下一页返回2.1VHDL语言基本结构
用户可以看出,配置语句以关键词CONFIGURATION开始,配置名是设计者自定义的名字,后面的实体名说明该配置为哪一个实体服务。关键词FOR后的选配结构体名是为实体指定的结构体名。下面以加入了配置的4位等值比较器设计文件为例,说明配置语句的用法。2.1.4库在使用VHDL语言进行设计时,需要将别人或自己的设计成果汇集在一个或几个库中,方便调用,以便提高设计效率。VHDL库就是用于存放预定义好的数据类型、子程序等设计单元的集合体。上一页返回2.2VHDL语言要素2.2.1VHDL文字规则VHDL也有自己的文字规则,在编程中需认真遵守。除了具有类似于计算机高级语言编程的一般文字规则外,VHDL还包含特有的文字规则和表达方式。1.数字表示数字型文字的值有多种表达方式,现列举如下:(1)整数:整数文字都是十进制的数。(2)实数:实数也都是十进制的数,但必须带有小数点,如23.34,2.0,0.0,44.99E−2。下一页返回2.2VHDL语言要素
(3)以数制基数表示的数字:用这种方式表示的数由5个部分组成。第一部分,用十进制数标明数制进位的基数;第二部分,数制隔离符号(#);第三部分,表达的数字;第四部分,指数隔离符号(#);第五部分,用十进制表示的指数部分,这一部分的数如果是0可以省去不写。2.字符串型文字字符是用单引号引起来的ASCII字符,可以是数字,也可以是符号或字母,需放在单引号中,如‘R’‘A’‘*’‘Z’。字符串则是一维的字符数组,需放在双引号中。VHDL中有两种类型的字符串,分别为文字字符串和数位字符串,如“ERROR”“ZZZZZZZZ”“XXXXXXXX”。上一页下一页返回2.2VHDL语言要素
3.数位字符串数位字符串也称位矢量,是预定义的数据类型BIT的一位数组,它们所代表的是二进制、八进制或十六进制的数组,其位矢量的长度即等值的二进制数的位数。数位字符串的表示首先要有计算基数,然后将该基数表示的值放在双引号中,基数符以“B”“O”和“X”表示,并放在字符串的前面。其基本格式如下:基数符号"数值"上一页下一页返回2.2VHDL语言要素
4.标识符标识符用来定义常数、变量、信号、端口、子程序或参数的名字。VHDL的基本标识符必须要求以英文字母开头,不连续使用下划线“_”,不以下划线“_”结尾,由26个大小写英文字母、数字0~9以及下划线“_”组成。标识符中的英文字母不区分大小写,如,MY_COUNTER,DECODER_1,FFT,Sig_N,NOT_ACK,State0是合法的标识符;而_DECODER_1,2FFT,SIG_#N,NO.ACK,ALL_RST_,data__BUS,RETURN,ENTITY则是非法的标识符。VHDL的保留字不能作为标识符使用。上一页下一页返回2.2VHDL语言要素
5.下标名下标名用于指示数组型变量或信号的某一元素。语句格式如下:标识符(表达式)标识符必须是数组型的变量或信号的名字,表达式所代表的值必须是数组下标范围中的一个值,这个值将对应数组中的一个元素。SIGNALa:BIT_VECTOR(0TO3);//定义a为具有4位元素的一维数组SIGNALz:BIT;//定义z为1位信号z<=b(3);//将数组a的第3位元素值赋给z上一页下一页返回2.2VHDL语言要素
2.2.2VHDL数据对象在VHDL中,数据对象有三种,即常量(CONSTANT)、变量(VARIABLE)和信号(SIGNAL)。前两种可以从传统的计算机高级语言中找到对应的数据类型,其语言行为与高级语言中的变量和常量十分相似。但信号是具有更多的硬件特征的特殊数据对象,是VHDL中最有特色的语言要素之一。上一页下一页返回2.2VHDL语言要素
1.常量(CONSTANT)常量是指在设计描述中不会变化的值。在VHDL描述中,一般用常量代表数字电路中的电源、地、恒定逻辑值等常数;常量的定义和设置主要是为了使设计实体中的常数更容易阅读和修改。例如,将位矢量的宽度定义为一个常量,只要修改这个常量就能很容易地改变宽度,从而改变硬件结构。在程序中,常量是一个恒定不变的值,一旦做了数据类型的赋值定义,在程序中就不能再改变,因而具有全局意义。常量的定义格式如下:CONSTANT常量名:数据类型:=表达式;上一页下一页返回2.2VHDL语言要素
VHDL要求所定义的常量数据类型必须与表达式的数据类型一致。常量的数据类型可以是标量类型或复合类型,不能是文件类型(File)或存取类型(Access)。常量定义语句所允许的设计单元有实体、结构体、程序包、块、进程和子程序。在程序包中定义的常量可以暂不设具体数值,它可以在程序包体中设定。常量的使用范围取决于它被定义的位置。在程序包中定义的常量具有最大全局化特征,可以用在调用此程序包的所有设计实体中;定义在设计实体中的常量,其有效范围为这个实体定义的所有的结构体;定义在设计实体的某一结构体中的常量,则只能用于此结构体;定义在结构体的某一单元的常量,如一个进程中,则这个常量只能用在这一进程中。上一页下一页返回2.2VHDL语言要素
2.变量(VARIABLE)变量代表暂存某些值的存储单元,变量常用在实现某种算法的赋值语句中;在VHDL语法规则中,变量是一个局部量,只能在进程和子程序中使用。变量不能将信息带出对它做出定义的当前设计单元。变量的赋值是一种理想化的数据传输,是立即发生,不存在任何延时的行为。定义变量的语法格式如下:VARIABLE变量名:数据类型约束条件:=表达式;变量作为局部量,其适用范围仅限于定义了变量的进程或子程序中。变量的值将随变量赋值语句的运算而改变。变量定义语句中的初始值可以是一个与变量具有相同数据类型的常数值,也可以是一个全局静态表达式,这个表达式的数据类型必须与所赋值变量一致。上一页下一页返回2.2VHDL语言要素
3.信号(SIGNAL)信号代表物理设计中的某一条硬件连接线,包括输入、输出端口,是描述硬件系统的基本数据对象。在VHDL中,信号及其相关的信号赋值语句、决断函数、延时语句等很好地描述了硬件系统的许多基本特征,如硬件系统运行的并行性、信号传输过程中的惯性延时特性、多驱动源的总线行为、时序电路中触发器的记忆特性等。信号作为一种数值容器,不但可以容纳当前值,也可以保持历史值。这一属性与触发器的记忆功能有很好的对应关系。信号的定义格式如下:SIGNAL信号名:数据类型约束条件﹕=表达式(初始值);上一页下一页返回2.2VHDL语言要素
信号无须设置初始值,信号的硬件特征明显,它具有全局性特性。例如,在程序包中定义的信号,对于所有调用此程序包的设计实体都是可见的;在实体中定义的信号,在其对应的结构体中都是可见的。信号的使用和定义范围是实体、结构体和程序包。在进程和子程序中不允许定义信号。信号可以有多个驱动源或者说赋值信号源,但必须将此信号的数据类型定义为决断性数据类型。在进程中,只能将信号列入敏感表,而不能将变量列入敏感表。进程只对信号敏感,而对变量不敏感。在进程和子程序中只能使用信号而不能说明信号。上一页下一页返回2.2VHDL语言要素
2.2.3数据类型VHDL是一种强类型语言,提供了多种标准的数据类型。对象的数据类型定义了该对象可以具有的值和对该对象可以进行的运算的限制,这种限制是被强制执行的。在VHDL描述中,每个信号、常量、变量都要指定它的数据类型,以确定它能保持哪一类数据。VHDL对数据类型的定义相当严格,在进行赋值或变换过程中都要进行类型检查。不允许不同类型的数值相互赋值,不能使用类型不允许的运算符进行运算。上一页下一页返回2.2VHDL语言要素
1.标准数据类型VHDL提供的10种标准数据类型。(1)Integer(整数类型),取值范围为−(231−1)~+(231−1)。一个整数类型和要被综合进逻辑的信号或变量在其范围上应有约束。(2)Real(实数),取值范围为−1.0×1038~+1.0×1038。和整数一样,实数被约束。由于实数运算需要大量的资源,因此综合工具常常并不支持实数类型。(3)Bit(位),只有两种取值,即0和1,可用于描述信号的取值。上一页下一页返回2.2VHDL语言要素
(4)Bit_Vector(位矢量),是用双引号括起来的一组数据,每位只有两种取值:0和1。在其前面可加以数制标记。例如,X(十六进制)、B(二进制、默认)、O(八进制)等。位矢量常用于表示总线的状态。(5)Boolean(布尔量),又称逻辑量,有“真”“假”两种状态,分别用TRUE和FALSE标记,用于表示关系运算和逻辑运算的结果。(6)Character(字符),是用单引号括起来的一个字母、数字、空格或一些特殊字符(如$、@、%等)。字符区分大小写字母。(7)String(字符串),是用双引号括起来的一个字符序列。字符串区分大小写字母,常用于程序的提示和结果说明等。上一页下一页返回2.2VHDL语言要素
(8)Time(时间),时间的取值范围为−(231−1)~+(231−1)。时间由整数值、一个以上空格以及时间单位组成。常用的时间单位有fs、ns、μs、ms、s、min、hr等。时间常用于指定时间延时和标记仿真时刻。(9)Natural(自然数)和Positive(正整数)是整数类型的子类型。自然数取值范围为0~(231−1);正整数是大于0的整数。(10)SeverityLevel(错误等级),错误等级分为:NOTE(注意)、WARNING(警告)、ERROR(出错)、FAILURE(失败)四级,用于提示系统的错误等级。上述10种数据类型是VHDL标准的数据类型,在编程时可以直接引用。如果用户需使用其他数据类型,则必须进行自定义。上一页下一页返回2.2VHDL语言要素
2.IEEE库STD_LOGIC_1164程序包中定义的标准逻辑类型1)STD_LOGIC类型STD_LOGIC类型的数据可以具有9种取值,其含义如下:上一页下一页返回2.2VHDL语言要素
其中,“X”服务于系统仿真,“Z”服务于双向总线的描述。2)STD_LOGIC_VECTOR类型STD_LOGIC_VECTOR是一维数组,其中每个元素的数据类型都是STD_LOGIC类型。对STD_LOGIC_VECTOR类型的元素赋值,必须严格考虑宽度和数据类型。3.用户自定义数据类型VHDL允许用户自己定义数据类型。自定义数据类型说明语句的一般格式是:上一页下一页返回2.2VHDL语言要素
4.数据类型的转换在VHDL程序中,不同类型的对象不能代入,因此要进行类型转换。类型转换的方法分别有类型标记法和类型函数法两种。例如,用户使用类型名称来实现关系密切的标量类型之间的转换,代码如下:如果使用类型标记(即类型名)实现类型转换,可采用赋值语句,代码如下:上一页返回2.2VHDL语言要素
2.2.4操作符与传统的程序设计语言一样,VHDL的各种表达式由操作数和操作符组成。其中,操作数是各种运算的对象,而操作符则规定运算的方式。VHDL中共有四类操作符:算术运算符、关系运算符、逻辑运算符和符号运算符。2.各种操作符的使用说明(1)严格遵循在基本操作符间操作数是同数据类型的规则;严格遵循操作数的数据类型必须与操作符所要求的数据类型完全一致的规则。(2)注意操作符之间的优先级别。当一个表达式中有两个以上的运算符时,可使用括号将这些运算分组。上一页下一页返回2.2VHDL语言要素
(3)VHDL共有7种基本逻辑操作符,对于数组型(如STD_LOGIC_VECTOR)数据对象的相互作用是按位进行的。一般情况下,经综合器综合后,逻辑操作符将直接生成门电路。信号或变量在这些操作符的直接作用下,可构成组合电路。(4)关系操作符的作用是,将相同数据类型的数据对象进行数值比较或关系排序判断,并将结果以布尔类型(BOOTLEAN)的数据表示出来,即TRUE和FALSE两种。对于数组或记录类型的操作数,VHDL编译器将逐位比较对应位置各位数值的大小而进行比较或关系排序。就综合而言,简单的比较运算操作在实现硬件结构时,比排序操作符构成的电路芯片资源利用率要高。上一页下一页返回2.2VHDL语言要素
(5)并置运算符(&)的操作数的数据类型是一维数组,可以利用并置运算符将普通操作数或数组组合起来形成各种新的数组。例如,“0”&“1”的结果为“01”,连接操作常用于字符串。但在实际运算过程中,要注意并置操作前后的数组长度应一致。(6)求积操作符包括*(乘)、/(除)、MOD(取模)和REM(取余)四种操作符。VHDL规定,乘与除的数据类型是整数和实数(包括浮点数)。在一定条件下,还可对物理类型的数据对象进行运算操作。但需注意的是,虽然在一定条件下,乘法和除法运算是可综合的,但从优化综合、节省芯片资源的角度出发,最好不要轻易使用乘除操作符。对于乘除运算可以用其他变通的方法来实现。上一页下一页返回2.2VHDL语言要素
(7)乘方(**)运算的左边可以是整数或浮点数,但右边必须为整数,而且只有在左边为浮点数时,其右边才可以为负数。一般地,VHDL综合器要求乘方操作符作用的操作数的底数必须是2。(8)六种移位操作符号SLL、SRL、SLA、SRA、ROL和ROR都是VHDL'93标准新增的运算符,在1987标准中没有。VHDL'93标准规定移位操作符作用的操作数的数据类型应是一维数组,并要求数组中的元素必须是BIT或BOOLEAN的数据类型,移位的位数则是整数。上一页下一页返回2.2VHDL语言要素
在EDA工具所附的程序包中重载了移位操作符以支持STD_LOGIC_VECTOR及INTEGER等类型。移位操作符左边可以是支持的类型,右边则必须是INTEGER型。如果操作符右边是INTEGER型常数,移位操作符实现起来比较节省硬件资源。其中SLL是将位矢向左移,右边跟进的位补零;SRL的功能恰好与SLL相反;ROL和ROR的移位方式稍有不同,它们移出的位将用于依次填补移空的位,执行的是自循环式移位方式;SLA和SRA是算术移位操作符,其移空位用最初的首位来填补。移位操作符的语句格式是:标识符号移位操作符号移位位数;上一页下一页返回2.2VHDL语言要素
(9)操作符可以用以产生电路。就提高综合效率而言,使用常量值或简单的一位数据类型能够生成较紧凑的电路,而表达式复杂的数据类型(如数组)将相应地生成更多的电路。如果组合表达式的一个操作数为常数,就能减少生成的电路;如果两个操作数都是常数,在编译期间,相应的逻辑被压缩掉,或者被忽略掉,而生成了零个门。在任何可能的情况下,使用常数意味着设计描述将不会包含不必要的函数,并将被快速地综合,产生一个更有效的电路实现方案。上一页下一页返回2.3顺序语句2.3.1赋值语句这种赋值语句分为变量赋值语句和信号赋值语句。它们在进程和子程序中是都可做顺序语句。变量值只在进程或子程序中使用,无法传递到进程之外。因此,它类似于一般高级语言的局部变量,只在局部范围内有效。变量赋值语句的格式为:2.3.2IF语句IF语句是一种条件语句,它根据语句中所设置的一种或多种条件,有选择地执行指定的顺序语句,其语句的格式有三种,分别为:下一页返回2.3顺序语句第一种条件语句的执行情况是:当执行到此句时,首先检测关键词IF后的条件表达式的布尔值是否为真(TRUE),如果条件为真,于是(THEN)将顺序执行条件句中列出的各条语句,直到ENDIF即完成全部IF语句的执行,如果条件检测为伪(FALSE),则跳过以下的顺序语句,直接结束IF语句的执行。第二种IF语句是双向选择。当所测条件为FALSE时,程序转向ELSE以下的另一段顺序语句进行执行。所以第二种IF语句具有条件分支的功能,就是通过测定所设条件的真伪以决定执行哪一组顺序语句。第三种IF语句通过关键词ELSIF设定多个判定条件,以使顺序语句的执行分支可以超过两个。上一页下一页返回2.3顺序语句上述程序实际上是由两个2选1多路选择器构成的。其中sel是两路控制信号,分别是两个多路选择器的通道选择开关。sel有四种取值:00、01、10、11,分别对应一路输入。2.3.3CASE语句在硬件描述中也有多项选择的情况,某个表达式有多个取值,针对不同的取值,程序就会执行相应的操作。VHDL语言用CASE语句来描述这种多项选择的情况。虽然用IF语句也能完成类似的功能,但是CASE语句的可读性要比IF语句强得多。CASE语句的格式如下:上一页下一页返回2.3顺序语句当执行到CASE语句时,首先计算表达式的值,然后根据条件句中与之相同的选择值,执行对应的顺序语句,最后结束CASE语句。2.3.4LOOP语句在采用VHDL语言描述硬件电路的过程中,设计人员经常会遇到某些操作需要多次重复的情况。在这种情况下,设计人员就可以采用LOOP语句来进行描述。LOOP语句的功能就是使VHDL语言程序进行有规则的循环操作,具体循环的次数受到迭代算法的限制。LOOP语句与其他高级编程语言中的循环语句十分类似,读者可以借鉴高级编程语言中的循环语句来理解VHDL语言中的LOOP语句。VHDL语言提供的LOOP语句有两种类型,分别为FORLOOP语句和WHILELOOP语句。上一页下一页返回2.3顺序语句1.FORLOOP循环FORLOOP循环主要用于规定重复次数的情况,其格式如下:循环标号用来作为该FORLOOP语句的标识符。循环变量的值在每次循环中都将发生变化。离散范围用来指定循环变量的取值范围,循环变量的取值将从取值范围最左边的值开始并且递增到取值范围最右边的值,取值范围确定了循环的次数。循环变量每取一个值,就要执行一次循环体中的顺序处理语句。最后当循环变量的值超出离散范围时,就结束循环。上一页下一页返回2.3顺序语句下面给出一个含有FORLOOP语句的奇偶校验电路程序,代码如下:上一页下一页返回2.3顺序语句在上述程序中,A是8位数字信号,对A进行奇偶校验的处理需要8次,每次处理的性质是一样的,因此使用FORLOOP语句的固定次数循环功能,很好地实现了设计要求。上一页下一页返回2.3顺序语句2.WHILELOOP循环WHILELOOP循环用于重复执行操作,直到控制条件满足为止的情况。其格式如下:循环标号用来作为该WHILELOOP语句的标识符,WHILE语句中的循环条件是布尔类型,如果检测到条件为真时,那么将会去执行循环体中的顺序处理语句,为假时结束循环,而去执行WHILELOOP语句后面的其他语句。上一页下一页返回2.3顺序语句循环条件中的控制变量必须进行显示说明,并初始化,这一点和FORLOOP循环语句不同。在进程语句的说明区,在上述程序中,首先显示说明了控制变量i,然后在进程语句中对其进行了初始化,循环变量i的递增是在WHILELOOP循环语句的顺序处理语句中进行的。当i=8时,则跳出循环。2.3.5跳出循环的语句在VHDL语言中,跳出循环是指完成了循环的次数或者不满足条件表达式而跳出循环体。但是在某种特殊情况下,设计人员往往需要人为地跳出本次或整个循环语句,转而去执行循环语句之外的其他操作语句。因此,VHDL语言提供了两种跳出循环的语句:一种是跳出本次循环的NEXT语句,另一种是跳出整个循环的EXIT语句。上一页下一页返回2.3顺序语句NEXT语句的格式如下:NEXT[循环标号][WHEN条件];跳出本次循环的NEXT语句经常用在LOOP语句的内部,它可以有条件或者无条件地结束当前循环并开始下一次的循环。其中,循环标号用来标明结束本次循环后,下一次循环的起始位置。保留字“WHEN”后面的条件用来标明跳出本次循环的条件。在LOOP语句中,用EXIT语句跳出并结束整个循环状态(而不是仅跳出本次循环),继续执行LOOP语句后续的语句。EXIT语句是一条很有用的控制语句,它提供了一个处理保护、出错和警告等状态的简便方法。上一页下一页返回2.3顺序语句EXIT语句的书写格式如下:EXIT[标号][WHEN条件];当“WHEN条件”为真时,跳出LOOP至程序标号处。如果EXIT后面无“标号”和“WHEN条件”,则程序执行到该语句时,即无条件从LOOP语句跳出,结束循环状态,继续执行后续语句。2.3.6RETURN语句在VHDL语言中,RETURN语句只能用在函数和过程体中,它用来结束当前的最内层的函数或者过程体的执行。RETURN语句的格式如下:上一页下一页返回2.3顺序语句RETURN语句在函数和过程体中的用法是不同的:过程体中的RETURN语句不能含有返回表达式,而函数体中的RETURN语句必须含有一个表达式,同时它也是结束函数体执行的唯一条件程序描述的是对两个输入整数求最大值的函数。在函数体中,程序比较得到的最大值,通过RETURN语句返回该最大值,并且通过该语句来结束函数体的执行。2.3.7NULL语句在VHDL语言中,NULL语句用来表示一种只占位置的空操作,它不执行任何操作。执行该语句只是使VHDL语言程序去执行下一个语句。上一页下一页返回2.3顺序语句NULL语句的书写格式比较简单,如下所示:NULL;NULL语句经常用在CASE语句中,它用来表示CASE语句中除了列出的条件选择值下的操作行为外,其他未列出的条件选择值下的操作行为,从而能够满足CASE语句对条件选择值全部列举的要求。上一页返回2.4并行语句2.4.1并行信号赋值语句所谓并行信号赋值语句,是指在结构体的进程语句之外使用的信号赋值语句,作为一种并行描述语在VHDL语言中,并行信号赋值语句有3种形式,它们分别是:并行信号赋值语句、条件信号赋值语句和选择信号赋值语句。这3种语句在编写VHDL语言程序的过程中应用十分广泛。1.并行信号赋值语句一个并行信号赋值语句实际上是一个进程的缩写。当信号赋值符号“<=”右边的信号值发生任何变化时,该信号赋值语句就执行一次。下一页返回2.4并行语句代码如下:q<=tmp3;信号tmp3类似于进程语句括号中的敏感信号。当tmp3发生变化时,就开始执行该语句。2.条件信号赋值(ConditionalSignalAssignment)语句条件信号赋值语句也是并行描述语句,可以根据不同的条件将不同的值赋给信号。其格式为:上一页下一页返回2.4并行语句条件信号代入语句与进程中的IF语句相同,具有顺序性,但ELSE不能省略。执行该语句时,每一赋值条件是按书写的先后关系逐项测定的,一旦发现条件为“TRUE”,立即将表达式的值赋予目标信号。赋值条件的数据类型是布尔量。由于条件测试的顺序性,条件信号代入语句的赋值具有优先级别,其中第1子句优先级别最高,以此类推。3.选择信号赋值语句选择信号赋值语句是一种根据选择条件的不同而将不同的表达式赋给目标信号的语句。在VHDL语言中,选择信号赋值语句的格式如下:上一页下一页返回2.4并行语句选择信号赋值语句与进程中的CASE语句相似,但不能在进程中应用。其敏感量就是WITH后面的选择条件表达式。每当选择表达式的值发生变化,便启动该语句对各子句的选择条件进行测试对比,当发现有满足条件的子句时,就将此子句表达式的值赋予目标信号。该语句对子句条件选择值具有同期非顺序性。在这种语句时,不允许有条件重叠现象,也不允许存在条件涵盖不全的情况。上一页返回2.4并行语句2.4.2进程(PROCESS)语句PROCESS语句是一种并行处理语句,在一个结构体中,多个PROCESS语句可以同时并行运行。因此,PROCESS语句是VHDL中描述硬件系统并发行为的最常用、最基本的语句。PROCESS语句的特点:(1)可以与其他进程并发执行,并可存取结构体或实体所定义的信号。(2)进程中的所有语句都是顺序执行的。(3)进程中必须包含一个显式的敏感信号表或者包含一个WAIT语句。上一页下一页返回2.4并行语句(4)进程之间的通信是通过信号量传递来实现的。PROCESS语句的表达格式如下:上一页下一页返回2.4并行语句PROCESS语句有三个重要部分组成,即进程说明部分、顺序描述语句和敏感信号参数表。进程标号不是必需的。进程说明部分用于定义该进程所需的局部量,可以定义变量、数据类型、属性、子程序等,但不能定义信号和共享变量。顺序描述语句是一段顺序执行的语句,描述该进程的行为,可使用赋值语句、进程启动语句、子程序调用语句、顺序描述语句和进程跳出语句等。敏感信号参数表列出了用于启动本进程的信号名(当有WAIT语句时例外)。当敏感信号参数表中定义的任一敏感信号发生变化,进程就立即启动,执行一次进程中的语句。当进程中最后一个语句执行完成后,执行过程将返回到第一个语句,等待下一次敏感信号变化,如此循环往复以至无限。上一页下一页返回2.4并行语句进程的激活必须由敏感信号表中定义的任一敏感信号的变化来启动,否则必须有一个显式的WAIT语句来激活。这就是说,进程既可以由敏感信号的变化来启动,也可以由满足条件的WAIT语句来激活;反之,在遇到不满足条件的WAIT语句后,进程将被挂起。因此,进程中必须定义显式或隐式的敏感信号。如果一个进程对一个信号集合总是敏感的,那么,用户可以使用敏感信号表来指定进程的敏感信号。但是,在一个使用了敏感信号表的进程(或者由该进程所调用的子程序)中不能含有任何等待语句。上一页返回2.5子程序子程序是一个VHDL程序模块,这个模块是利用顺序语句来定义和完成算法的。因此只能使用顺序语句,这一点与进程十分相似。但是,进程可以从本结构体的其他模块或进程结构中直接读取信号值或者向信号赋值,而子程序不能。此外,VHDL子程序与其他软件语言程序中的子程序的应用目的是相似的,即能避免重复性的计算工作,提高效率。子程序的使用方式只能通过子程序调用,与子程序的界面端口进行通信。子程序可以在VHDL程序的3个不同位置进行定义,即在程序包、结构体和进程中定义。由于只有在程序包中定义的子程序可被几个不同的设计所调用,所以一般应该将子程序放在程序包中。下一页返回2.5子程序
VHDL子程序具有可重载性的特点,即允许有许多重名的子程序,但这些子程序的参数类型及返回值数据类型是不同的。子程序的可重载性是一个非常有用的特性。子程序有两种类型,即过程PROCEDURE和函数FUNCTION。过程的调用可通过其界面提供多个返回值或不提供任何值,而函数只能返回一个值;在函数入口中,所有参数都是输入参数,过程有输入参数、输出参数和双向参数;过程一般被看作一种语句结构,常在结构体或进程中以分散的形式存在。而函数通常是表达式的一部分,常在赋值语句或表达式中使用;过程可以单独存在,其行为类似于进程,而函数通常作为语句的一部分被调用。上一页下一页返回2.5子程序
在实用中必须注意,综合后的子程序将映射于目标芯片中的一个相应的电路模块,且每一次调用都将在硬件结构中产生对应于具有相同结构的不同的模块。在面向VHDL的综合中,每调用一次子程序都意味着增加了一个硬件电路模块。因此,在实用中要密切关注和严格控制子程序的调用次数。上一页返回下一页2.5子程序
2.5.1过程VHDL的过程包括过程首和过程体两部分。其中,过程首定义过程的接口,过程体则是描述过程实现的逻辑功能和具体算法。其书写格式如下:PROCEDURE<过程名>(参数名[,参数名…]:[端口模式]数据类型;参数名[,参数名…]:[端口模式]数据类型;……);//以上定义过程首PROCEDURE<过程名>上一页下一页返回下一页2.5子程序
(参数名[,参数名…]:[端口模式]数据类型;参数名[,参数名…]:[端口模式]数据类型;……)IS[过程说明部分;]BEGIN<过程语句部分>;END[PROCEDURE]<过程名>;//以上定义过程体上一页下一页返回下一页2.5子程序
过程首说明,以保留字“PROCEDURE”开始,紧跟着的是过程名;然后是过程的参数列表。参数列表中的每个参数包括它的参数名、端口模式和数据类型。过程体定义部分仍以保留字“PROCEDURE”开始,紧跟着的是过程名,接下来是过程的参数列表,然后从保留字“IS”开始过程的说明部分。过程的说明部分主要说明过程中要用到的变量、常量和数据类型,这些说明只有在该过程中是可见的。以保留字“BEGIN”开始的过程语句部分,用来描述该过程的具体功能,最后将以保留字“END[PROCEDURE]”结束过程定义部分。上一页下一页返回2.5子程序
下面将给出一个具体的过程定义的程序,其功能是从两个整数中求最大值。代码如下:PROCEDUREmax(a,b:ININTEGER;c:OUTINTEGER)ISBEGINIF(a>b)THENc<=a;ELSE上一页下一页返回2.5子程序
c<=b;ENDIF;ENDmax;过程可以在VHDL语言程序中的3个位置进行定义,它们分别是程序包、结构体和进程语句。在实际的设计过程中,设计人员常常将过程定义在程序包中,这样可以在其他的设计中方便地调用这些过程。通常,过程在程序包中的定义规则为:过程首书写在程序包的包说明部分,过程体书写在程序包的包体部分。上一页下一页返回2.5子程序
下面给出一段程序,将上述过程定义在一个程序包中,说明过程在程序包中的定义规则,代码如下:LIBRARYIEEE;//使用标准库USEIEEE.STD_LOGIC_1164.ALL;PACKAGEexampleISPROCEDUREmax上一页下一页返回2.5子程序
(a,b:ININTEGER;c:OUTINTEGER);//过程首书写在程序包的包说明部分ENDPACKAGEexample;PACKAGEBODYexampleISPROCEDUREmax(a,b:ININTEGER;c:OUTINTEGER)ISBEGINIF(a>b)THEN上一页下一页返回2.5子程序
c<=a;ELSEc<=b;ENDIF;ENDmax;//过程体书写在程序包的包体部分ENDPACKAGEBODYexample;关于过程在结构体和进程语句中的定义方法,与在程序包中的定义方法十分类似。接下来,将向用户讨论过程调用。上一页下一页返回2.5子程序
在VHDL语言中,就是指过程作为子程序被主程序调用。过程被调用时,主程序先要对过程进行初始化,即将初始值传递给过程的输入参数,从而启动过程语句;过程启动后,将会按照语句的顺序,自上而下执行过程中的各条语句。过程执行完毕后,输出值将会传递给调用主程序所定义的变量或者信号中。过程调用格式如下:<过程名>(实际参数名[,参数名…]);上一页下一页返回2.5子程序
过程调用语句有两种方式:并行过程调用语句和顺序过程调用语句。其中,并行过程调用语句主要用于结构体的并行处理语句部分,它位于其他子程序和进程语句的外部;而顺序过程调用语句,则位于进程语句或者另一个子程序的内部。下面以上例所定义的过程Max为例,来讨论一下并行过程调用语句和顺序过程调用语句的具体调用方法。示例代码如下:LIBRARYIEEE;//使用标准库USEIEEE.STD_LOGIC_1164.ALL;ENTITYexampleIS//实体定义PORT(i1:ININTEGER;//端口定义上一页下一页返回2.5子程序
i2:ININTEGER;i3:OUTINTEGER;i4:OUTINTEGER;q1:OUTINTEGER;q2:OUTINTEGER);ENDexample;ARCHITECTUREbehaveOFexampleISPROCEDUREmax上一页下一页返回2.5子程序
(a,b:ININTEGER;c:OUTINTEGER)ISBEGINIF(a>b)THENc<=a;ELSEc<=b;ENDIF;ENDmax;上一页下一页返回2.5子程序
BEGINMax(i1,i2,q1);//求最大值PROCESS(i2)BEGINMax(i3,i4,q2);ENDPROCESS;ENDbehave;不难看出,上述所示的VHDL语言程序是一个完整的程序。它在结构体的说明部分,首先定义了过程Max,功能是从两个整数中求最大值。上一页下一页返回2.5子程序
在结构体的并行语句部分调用了这个过程,同时在进程语句中也调用了这个过程。其中,第一个过程调用语句是并行过程调用语句,第二个过程调用语句是顺序过程调用语句。从上面可以知道,使用过程调用语句是很简单的,只需要在调用过程前将实参正确地传递给形参,然后执行过程中的顺序语句,最后将输出值送到定义的变量或信号中去,从而完成整个过程的调用。上一页下一页返回2.5子程序
2.5.2函数在VHDL中有多种函数形式,如用于不同目的的用户自定义函数,以及在库中现成的具有专用功能的预定义函数。函数定义应由两部分组成,即函数首和函数体。在进程或结构体中不必定义函数首,而在程序包中必须定义函数首。函数的VHDL语言表达格式如下:FUNCTION函数名输入参数表RETURN数据类型;//函数首FUNCTION函数名输入参数表RETURN数据类型IS//函数体[说明语句];BEGIN顺序语句;上一页下一页返回2.5子程序
RETURN[返回变量名];//函数返回值ENDFUNCTION函数名;与过程中的参数稍有不同,函数参数的数据类型只能包括常量和信号,参数的端口模式只能是IN,因此参数的端口模式可以省略。如果函数中的参数没有指明对象类型和端口模式,那么参数将被默认为端口模式为IN的常量。函数首的作用只是作为程序包的有关此函数的一个接口,放在包首说明部分。函数体则是描述过程实现的逻辑功能和具体算法,放在包体中。上一页下一页返回2.5子程序
在程序包中定义函数的示例如下:LIBRARYIEEE;USEIEEE.STD_LOGIC_1164.ALL;PACKAGEexampleISFUNCTIONmax(a,b:INSTD_LOGIC_VECTOR(7downto0))//定义函数首RETURNSTD_LOGIC_VECTOR(7downto0));ENDmax;ENDPACKAGEexample;上一页下一页返回2.5子程序
PACKAGEBODYexampleISFUNCTIONmax(a,bINSTD_LOGIC_VECTOR(7downto0))//定义函数体RETURNSTD_LOGIC_VECTOR(7downto0)ISBEGINIFa>bTHENRETURNa;ELSERETURNb;上一页下一页返回2.5子程序
ENDIF;ENDFUNCTIONmax;//结束FUNCTION语句ENDexample;//结束PACKAGEBODY语句上述程序在程序包中,定义了比较两个8位逻辑向量大小的函数,其功能是返回a、b中的最大值。下面举例说明如何调用该函数。其代码如下:LIBRARYIEEE;//使用标准库USEIEEE.STD_LOGIC_1164.ALL;USEWORKexample.ALL;上一页下一页返回2.5子程序
ENTITYDDIS//实体定义PORT(dat1,dat2,dat3,dat4:STD_LOGIC_VECTOR(7downto0));//端口定义out1,out2:STD_LOGIC_VECTOR(7downto0));ENDDD;ARCHITECTUREbhvOFDDISBEGINout1<=max(dat1,dat2);//用在赋值语句中的并行函数语句PROCESS(dat3,dat4)BEGIN上一页下一页返回2.5子程序
out2<=max(dat3,dat4);//顺序函数调用语句ENDPROCESS;ENDbhv;函数语句的调用格式如下:函数名(实际参数表);在上例中的调用语句就是max(dat1,dat2)和max(dat3,dat4)。每一次调用,程序都将实参赋给函数的形参,经过运行后,由RETURN语句返回指定值。:上一页下一页返回2.5子程序
VHDL允许以相同的函数名定义函数,但要求函数中定义的操作数具有不同的数据类型,以便调用时分辨不同功能的同名函数,即同样名称的函数可以用不同的数据类型作为此函数的参数定义多次。这样定义的函数称为重载函数。下面是一个完整的重载函数max的定义和调用的实例,代码如下LIBRARYIEEE;USEIEEE.STD_LOGIC_1164.ALL;PACKAGEpackexpIS//定义程序包FUNCTIONmax(a,bINSTD_LOGIC_VECTOR(7downto0))//定义函数首上一页下一页返回2.5子程序
RETURNSTD_LOGIC_VECTOR(7downto0);FUNCTIONmax(a,bINBIT_VECTOR(7downto0))//定义函数首RETURNBIT_VECTOR(7downto0);FUNCTIONmax(a,bININTEGER0TO15)//定义函数首RETURNINTEGER0TO15;ENDpackexp;PACKAGEBODYpackexpISFUNCTIONmax(a,bINSTD_LOGIC_VECTOR(7downto0))//定义函数体上一页下一页返回2.5子程序
RETURNSTD_LOGIC_VECTOR(7downto0)ISBEGINIFa>bTHENRETURNa;ELSERETURNb;ENDIF;ENDFUNCTIONmax上一页下一页返回2.5子程序
FUNCTIONmax(a,bININTEGER)//定义函数体RETURNINTEGER0TO15ISBEGINIFa>bTHENRETURNa;ELSERETURNb;ENDIF;上一页下一页返回2.5子程序
ENDFUNCTIONmax;//结束FUNCTION语句FUNCTIONmax(a,bINBIT_VECTOR(7downto0))//定义函数体RETURNBIT_VECTOR(7downto0)ISBEGINIFa>bTHENRETURNa;ELSERETURNb;ENDIF;上一页下一页返回2.5子程序
ENDFUNCTIONmax;//结束FUNCTION语句ENDpackexp;//结束PACKAGEBODY上述的包中定义了三个名字都为max的函数,它们的功能是取两个输入信号的最大值。虽然3个函数名字相同,但是它们针对的数据类型是不同的。第一个max函数的参数的数据类型为STD_LOGIC_VECTOR(7downto0)类型,第二个max函数的参数的数据类型为BIT_VECTOR(7downto0)类型,第三个max函数的参数的数据类型为INTEGER类型。这样做的好处是可以使max函数作用于不同的数据类型。如果调用上面定义的max函数,具体调用哪一个函数是由调用过程中参数的数据类型决定的。上一页返回2.6
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 关于宾馆管理制度的规定(3篇)
- 安全改造项目管理制度范本(3篇)
- 2026广东广州生物医药与健康研究院数字生物医学研究中心招聘科研助理1人笔试参考题库及答案解析
- 2026重庆市铜梁区巴川街道福利院工作人员招聘2人(第二次)考试参考题库及答案解析
- 2026年吉安市青原区两山人力资源服务有限公司面向社会公开招聘2名超市店员参考考试题库及答案解析
- 2026年上半年云南省科学技术厅直属事业单位公开招聘人员(8人)参考考试题库及答案解析
- 2026春季江西赣州石城县西外公立幼儿园教职工招聘备考考试题库及答案解析
- 2026年临沂市市直部分事业单位公开招聘综合类岗位工作人员(21名)参考考试题库及答案解析
- 2026年度济南市章丘区所属事业单位公开招聘初级综合类岗位人员备考考试题库及答案解析
- 2026山东事业单位统考滨州市阳信县招聘30人备考考试题库及答案解析
- GB/T 17587.2-2025滚珠丝杠副第2部分:公称直径、公称导程、螺母尺寸和安装螺栓公制系列
- 锅炉应急预案演练(3篇)
- 2026中国数字化口腔医疗设备市场渗透率与增长动力研究报告
- 2025中证信息技术服务有限责任公司招聘16人笔试参考题库附答案
- 建筑工程决算编制标准及实例
- 安徽省江淮十校2025年高二数学第一学期期末质量检测试题含解析
- 电力工程项目预算审核流程
- GB/T 14748-2025儿童呵护用品安全儿童推车
- 蒸汽管道-应急预案
- 叠合板专项施工方案(完整版)
- 造价咨询沟通和协调方案(3篇)
评论
0/150
提交评论