首页 百科知识 子程序调用语句

子程序调用语句

时间:2022-10-10 百科知识 版权反馈
【摘要】:子程序是一个VHDL程序模块,它是利用顺序语句来定义和完成算法的,应用它能更有效地完成重复性的设计工作。函数体包括对数据类型、常数、变量等的局部说明,以及用以完成规定算法或转换的顺序语句,并以关键词END FUNCTION以及函数名结尾。VHDL允许以相同的函数名定义函数,即重载函数。VHDL不允许不同数据类型的操作数间进行直接操作或运算。例4.18给出了程序包STD_LOGIC_UNSIGNED中的部分函数结构,其说明部分只列出了四个函数的函数首。

4.1.4 子程序调用语句

子程序是一个VHDL程序模块,它是利用顺序语句来定义和完成算法的,应用它能更有效地完成重复性的设计工作。子程序不能从所在的结构体的其他块或进程结构中直接读取信号值或者向信号赋值,而只能通过子程序调用及与子程序的界面端口进行通信。

子程序有两种类型,即过程(PROCEDURE)和函数(FUNCTION)。

1)过程

过程的语句格式是:

img128

过程由过程首和过程体两部分组成,过程首不是必须的,过程体可以独立存在和使用。即在进程或结构体中不必定义过程首,而在程序包中必须定义过程首。

(1)过程首

过程首由过程名和参数表组成。参数表用于对常数、变量和信号三类数据对象目标作出说明,并用关键词IN、OUT和INOUT定义这些参数的工作模式,即信息的流向。以下是三个过程首的定义示例:

img129

一般的,可在参量表中定义三种流向模式,即IN、OUT和INOUT。如果只定义了IN模式而未定义目标参量类型,则默认为常量;若只定义了INOUT或OUT,则默认目标参量类型是变量。

(2)过程体

过程体是由顺序语句组成的,过程的调用即启动了对过程体的顺序语句的执行。过程体中的说明部分只是局部的,其中的各种定义只能适用于过程体内部。

(3)过程调用

根据调用环境的不同,过程调用有两种方式,即顺序语句方式和并行语句方式。在一般的顺序语句自然执行过程中,一个过程被执行,则属于顺序语句方式;当某个过程处于并行语句环境中时,其过程体中定义的任一IN或INOUT的目标参量发生改变时,将启动过程的调用,这时的调用是属于并行语句方式的。这里介绍顺序语句调用方式。

过程调用就是执行一个给定名字和参数的过程。调用过程的语句格式如下:

img130

其中,括号中的实参表达式称为实参,它可以是一个具体的数值,也可以是一个标识符,是当前调用程序中过程形参的接受体。在此调用格式中,形参名即为当前欲调用的过程中已说明的参数名,即与实参表达式相联系的形参名。被调用中的形参名与调用语句中的实参表达式的对应关系有位置关联法和名字关联法两种,位置关联可以省去形参名。

一个过程的调用有三个步骤:

①将IN和INOUT模式的实参值赋给欲调用的过程中与它们对应的形参;

②执行这个过程;

③将过程中IN和INOUT模式的形参值赋还给对应的实参。

【例4.15】

img131

img132

本例是一个取三个输入位矢量最大值的功能描述,它在结构体中的进程语句中使用了两个过程调用语句。

(4)重载过程

两个或两个以上有相同的过程名和互不相同的参数数量及数据类型的过程称为重载过程。对于重载过程,靠参量类型来辨别究竟调用哪一个过程。

【例4.16】

img133

2)函数

在VHDL中有多种函数形式,如在库中现成的具有专用功能的预定义函数和用于不同目的的用户自定义函数。函数的语言表达格式如下:

img134

img135

一般的,函数定义由两部分组成,即函数首和函数体。

(1)函数首

函数首是由函数名、参数表和返回值的数据类型三部分组成的。函数首的名称即为函数的名称,需放在关键词FUNCTION之后,它可以是普通的标识符,也可以是运算符(这时必须加上双引号)。函数的参数表是用来定义输入值的,它可以是信号或常数,参数名需放在关键词CONSTANT或SIGNAL之后,若没有特别说明,则参数被默认为常数。如果要将一个已编制好的函数并入程序包,函数首必须放在程序包的说明部分,而函数体需放在程序包的包体内。如果只是在一个结构体中定义并调用函数,则仅需函数体即可。由此可见,函数首的作用只是作为程序包的有关此函数的一个接口界面。

(2)函数体

函数体包括对数据类型、常数、变量等的局部说明,以及用以完成规定算法或转换的顺序语句,并以关键词END FUNCTION以及函数名结尾。一旦函数被调用,就将执行这部分语句。

(3)函数调用

函数调用与过程调用是十分相似的,不同之处是,调用函数将返还一个指定数据类型的值,函数的参量只能是输入值。

【例4.17】

img136

本例在结构体内定义了一个完成某种算法的函数,并在进程PROCESS中调用了此函数,整个函数没有函数首。在进程中,输入端口矢量a被列为敏感信号,当a的3个位输入元素a(0)、a(1)和a(2)中任何一位发生变化时,将启动对函数sam的调用,并将函数的返回值赋给m输出。

(4)函数重载

VHDL允许以相同的函数名定义函数,即重载函数。但这时要求函数中定义的操作数具有不同的数据类型,以便调用时用以分辨不同功能的同名函数。

VHDL不允许不同数据类型的操作数间进行直接操作或运算。为此,在具有不同数据类型操作数构成的同名函数中,可定义运算符重载函数,这种函数为不同数据类型间的运算带来极大的方便。

例4.18中以加号“+”为函数名的函数即为运算符重载函数。VHDL的IEEE库中的STD_LOGIC_UNSIGNED程序包中预定义的操作符如“+”、“-”、“*”、“=”、“>”、“>=”、“<”、“<=”、“/=”、“AND”和“MOD”等,对相应的数据类型INTEGER、STD_LOGIC 和STD_LOGIC_VECTOR的操作作了重载,赋予新的数据类型操作功能,也就是说,通过重新定义运算符的方式,允许被重载的运算符能够对新的数据类型进行操作,或者允许不同的数据类型之间用此运算符进行运算。

【例4.18】

img137

img138

例4.18给出了程序包STD_LOGIC_UNSIGNED中的部分函数结构,其说明部分只列出了四个函数的函数首。在程序包体部分只列出了对应的部分内容,程序包体部分的UNSIGNED()函数是从IEEE.STD_LOGIC_ARITH库中调用的,在程序包体中的最大整型数检出函数MAXIMUM只有函数体,没有函数首,这是因为它只在程序包体内调用。

实用中,如果已用“USE”语句打开了程序包STD_LOGIC_UNSIGNED,这时,如果设计实体中有一个STD_LOGIC_VECTOR类型和一个整数相加,程序就会自动调用第一个函数,并返回STD_LOGIC_VECTOR类型的值。若是一个STD_LOGIC_VECTOR与STD_LOGIC数据类型的数相加,则调用第三个函数,并以STD_LOGIC_VECTOR类型的值返回。例4.19为重载函数使用实例,其功能时实现4位二进制加法计数器。

【例4.19】

img139

img140

免责声明:以上内容源自网络,版权归原作者所有,如有侵犯您的原创版权请告知,我们将尽快删除相关内容。

我要反馈