收藏 分销(赏)

EDA技术与VHDL设计(西电版)第7章-程序包和子程序.ppt

上传人:快乐****生活 文档编号:14660941 上传时间:2026-10-26 格式:PPT 页数:75 大小:2.14MB 下载积分:10 金币
下载 相关
EDA技术与VHDL设计(西电版)第7章-程序包和子程序.ppt_第1页
第1页 / 共75页
EDA技术与VHDL设计(西电版)第7章-程序包和子程序.ppt_第2页
第2页 / 共75页


点击查看更多>>
资源描述
单击此处编辑母版标题样式,*,第7章 程序包和子程序,第7章 程序包和子程序,7.1 程序包,7.2 子程序,7.1 程 序 包,经常需要使用的一些设计代码可以以元件、函数或过程的形式出现,然后再放置于程序包中,编译到库中,这是代码重用的重要手段。程序包中可以包含数据类型、常量、元件、函数和过程等。程序包的语句结构如下:PACKAGE 程序包名 IS -程序包首 声明部分;END PACKAGE 程序包名;PACKAGE BODY 程序包名 IS-程序包体函数和过程的描述;END PACKAGE BODY 程序包名;,程序包一般由程序包首和程序包体构成,二者的程序包名必须一致。在程序包首部分进行常量、数据类型、函数、过程以及元件的声明。程序包体并不是必须的,只有当子程序在程序包首中被声明了,才需要在程序包体中进行描述。包含了程序包的常用VHDL代码结构可扩展为图7-1所示结构。例7-1例举了一个简单的程序包,仅包含数据类型和常量的声明,因此并不需要程序包体。,图7-1 VHDL代码结构示意图,例7-2例举了一个包含函数声明的程序包,所以需要程序包体。【例7-2】,例7-3例举了一个利用VHDL语言描述的2输入与门,例7-4是将与门作为元件在程序包中声明的示例,例7-5则使用该程序包中的与门元件实现一个三输入逻辑与的电路。如果将程序包保存于当前工程同一文件夹内编译,相当于放入工作库WORK中,则通过使用语句“USE work.my_component.all;”就可打开该程序包中的所有内容(由于WORK库是默认打开的,所以不需要“LIBRARY work;”语句)。图7-2是综合后的RTL电路结构,图7-3是仿真结果。,【例7-3】,【例7-5】,图7-2 三输入与门综合后RTL电路结构,7.2 子 程 序,函数和过程统称为子程序。从结构特征上看,它们与进程十分相似,其内部都只能采用顺序描述语句,如IF语句、CASE语句、LOOP语句。但子程序内部不允许使用WAIT语句,这点与进程不同。其次,从应用的角度来看,进程只能在主代码中使用,不能被其他设计实体调用来实现代码的共享和重用;而子程序既可在主代码中使用,也可通过程序包放入库中使用。相比于前者,放入库中是使得子程序能够被其他设计调用以达到代码重用的目的的更为重要和常用的手段。需要指出的是,每一次调用子程序都将在综合时产生一个硬件电路,这与软件语言的子程序有很大的不同。,函数的创建中应注意以下几点:(1)参数列表专指函数的输入参数,所以不需要以显式表示参数的方向。输入参数可以是常量和信号(不能使用变量),具体描述如下:CONSTANT常量名:数据类型;-当参数是常量时,可省略关键词CONSTANTSIGNAL 信号名:数据类型;参数的个数是任意的,即可以没有、有一个或多个参数。参数的类型是可以被综合的任意一种数据类型,如布尔型、标准逻辑型、整型等,但不能指定它的取值范围(如使用整型时不能使用关键词RANGE来指定范围,使用BIT_VECTOR和STD_LOGIC_VECTOR数据类型时不能使用关键词TO和DOWNTO来指定范围)。,(2)函数只有一个返回值,该返回值的数据类型由关键词RETURN后面的数据类型决定。(3)函数名可以是普通的标识符,也可以是运算符。当函数名采用运算符时,必须加双引号,这就是前面章节中提及的运算符重载。运算符重载是对VHDL中现有运算符进行重新定义,以在原有基础上获得新的功能,具体讲解见7.2.2节。(4)在VHDL93标准中,结束语句“END FUNCTION 函数名;”中的关键词FUNCTION和函数名都是可以省略的。(5)函数内不能声明信号和元件。,【例7-6】FUNCTION max(a,b:STD_LOGIC_VECTOR)RETURN STD_LOGIC_VECTOR ISBEGIN IF a b THEN RETURE a;ELSE RETURN b;END IF;END FUNCTION max;,函数的创建可以放在程序包中,也可以直接放在主代码中(如结构体并行语句部分、进程内、实体内)。如果是在程序包中定义一个函数,则函数首是必须的,它放置于程序包首内,用于声明函数;如果函数定义在主代码内,则不需要函数首。函数首的语句格式如下:FUNCTION 函数名 参数列表 RETURN 数据类型;,例7-7在一个程序包my_pacakage中创建了一个函数max,功能是返回两个数据中的大值。例7-8是在主代码中调用该函数的示例,L15在结构体并行语句部分采用的是并行函数调用,L16L19在进程内部采用的是顺序函数调用。此外,数据d1、d2的长度是4,数据d3、d4的长度是8,即函数可以使用任意长度的矢量调用。本例还需要指出的是,由于大多数综合器都兼容VHDL87标准和VHDL93标准,所以程序包、函数、过程以及以前曾提及的实体、结构体的结束语句既可以单独使用关键词“END”表示结束,也可以使用“END 名称;”或“END PACKAGE 名称;”这样的语句格式。图7-4是例7-8主代码综合后的RTL电路结构,图7-5是例7-8的仿真结果。,【例7-7】,【例7-8】,图7-5 例7-8仿真结果,例7-9将函数的创建放于主代码结构体的并行语句部分,例7-10将函数的创建放于主代码的进程中,这两种创建函数的形式都不需要函数首,都不能够进行函数的重用。需要注意的是,如果将函数的创建放于进程内,则不能在进程外调用它,如例7-11是一个错误的示例,编译后会出现图7-6所示错误。,【例7-9】,【例7-10】,图7-6 例7-11编译后的错误报告,7.2.2 函数的重载,VHDL允许以相同的函数名定义函数,但要求函数中的参数具有不同的数据类型,这就是函数的重载。如在IEEE库的std_logic_unsigned程序包中预定义的“+”运算,能够实现数据类型STD_LOGIC_VECTOR间、数据类型STD_LOGIC_VECTOR与INTEGER间、数据类型STD_LOGIC_VECTOR与STD_LOGIC间的相加运算。例7-12是程序包std_logic_unsigned中截取的重载函数“+”的定义。可以看到,在程序包首的部分对函数进行了声明,5个函数具有相同的名字,即都是以加法运算符“+”作为函数名,但它们具有不同的参数数据类型。在实际应用中,如果使用USE语句打开程序包std_logic_unsigned,就能够根据主代码中数据类型的需要自动调用相应的函数。例如:主代码中有一个数据类型是STD_LOGIC_VECTOR的数据和一个数据类型是INTEGER的数据相加,就会调用第二个函数。,【例7-12】,例7-13通过对运算符“+”的重载,使其能够实现两个长度相同的二进制数组相加的功能。其中,在函数内声明了两个变量sum和carry(注意:函数内部不能声明信号),返回值是求和结果sum。例7-14通过对“+”的调用,实现了3个4位二进制数组的相加运算。图7-7是例7-14的仿真结果。,【例7-13】,【例7-14】,图7-7 例7-14仿真结果,如果将例7-14稍作改动,假设x、y、z是5位二进制数组,如例7-15,则仿真结果如图7-8所示。例7-14和例7-15再次显示了函数可以使用任意长度的矢量调用。,【例7-15】,图7-8 例7-15仿真结果,例7-16是一个完整的对重载函数max的定义,分别能够实现数据类型STD_LOGIC_ VECTOR、BIT_VECTOR以及INTEGER的操作;例7-17是对此函数的调用示例。【例7-16】,【例7-17】,7.2.3 决断函数,决断函数不可综合,主要在VHDL仿真中用于解决信号有多个驱动源时,驱动信号间的竞争问题。在std_logic_1164程序包中定义的数据类型STD_LOGIC和STD_LOGIC_VECTOR就是决断函数类型,其定义如例7-18所示。其中,L5L15是程序包首,L20L49是程序包体。当有几个驱动源驱动一个STD_LOGIC信号时,即调用函数resolved,返回该信号在有多个驱动源时应取的一个值。,【例7-18】,例7-19所示是一个两输入与门。例7-20是它的测试平台,用于产生测试激励信号(具体测试平台相关知识点请参考第8章),其中信号a有两个驱动源。根据决断函数resolved的定义,最终a将取值“1”,仿真结果如图7-9所示。如果将a的驱动源稍作改动,如例7-21,则a最终取值为“0”,仿真结果如图7-10所示。,【例7-19】,【例7-20】,图7-9 带有多个驱动源的两输入与门仿真结果(1),【例7-21】,图7-10 带有多个驱动源的两输入与门仿真结果(2),由此可见,数据类型STD_LOGIC是一个决断类型。当有多个驱动源时,它能够调用预定义的决断函数解决冲突并决定最终赋值。而当有多个驱动源时,数据类型STD_ULOGIC会导致错误,因为VHDL不允许一个非决断类型有两个及其以上的驱动源。所以,由于STD_ULOGIC类型的限制,设计者更多地使用STD_LOGIC数据类型。,7.2.4 过程的创建与调用,过程与函数非常相似,都有实现代码重用的功能,但过程允许返回多个值(函数只允许一个返回值)。过程的使用也需要经过两个阶段:过程的创建和过程的调用。创建过程(或称过程体)的语句格式如下:PROCEDURE 过程名 参数列表 IS 声明语句部分;BEGIN 顺序语句部分;END PROCEDURE过程名;,过程的创建中应注意以下几点:(1)参数列表给出了过程的输入、输出参数。参数可以是常量、信号和变量,具体描述如下:CONSTANT 常量名:模式类型;SIGANAL 信号名:模式类型;VARIABLE 变量名:模式类型;模式类型可以从IN(输入)、OUT(输出)、INOUT(输入/输出)三种类型中选择。如果没有指定模式类型,则默认是IN。如果模式类型是OUT或INOUT,则参数可以是变量或信号。对于输入类型的参数,其数据对象默认是常量;对于输出类型(OUT/INOUT)的参数,其数据对象默认是变量。,(2)过程内部可以声明变量和信号,但变量参数不允许出现在并行过程调用中。例7-22是一个过程的创建示例。该例有两个输入参数a和b,其中a是数据类型为BIT的常量,b是数据类型为INTEGER的信号。有两个输出参数x和y,其中x是数据类型为STD_LOGIC_VECTOR的变量,y是数据类型为STD_LOGIC的信号。,【例7-22】,PROCEDURE my_procedure(a:IN BIT;-输入参数a,没有指定数据对象则默认为常量SIGNAL b:IN INTEGER;-输入参数b,信号,数据类型为整型x:OUT STD_LOGIC_VECTOR-输出参数x,默认为变量SIGNAL y:OUT STD_LOGIC)IS 输出参数y,信号BEGINEND my_procedure;,与函数的创建相似,过程的创建也可以放在程序包内或是直接放在主代码中,如结构体并行语句部分、进程内、实体内。如果在程序包中创建一个过程,则过程首是必须有的,它放置于程序包首内,用于声明过程。如果过程定义在主代码内,则不需要过程首。过程首的语句格式如下:PROCEDURE 过程名 参数列表;,例7-23是一个在程序包中创建过程的示例。在程序包首中声明过程compare,在程序包体中创建该过程。过程compare有两个数据类型是整型的输入参数a和b,默认为常量;有两个输出参数max和min,默认为变量,数据类型也是整型。例7-24是对该过程的调用,其中声明了两个变量temp1和temp2,用于比较结果的暂存。例7-24在进程中调用过程compare,属于顺序过程调用。例7-24的仿真结果如图7-11所示。,【例7-23】,【例7-24】,图7-11 例7-24仿真结果,如果将例7-24稍加修改,如例7-25,其本意是想实现并行过程调用,但编译时却出现图7-12所示错误。究其原因是因为在过程compare中的输出参数max和min是变量。所以,当参数是变量时不能进行并行过程调用。如果要进行并行过程调用,则需要声明过程compare中的输出参数max和min为信号,见例7-26和例7-27。,【例7-25】,图7-12 例7-25并行过程调用错误信息报告,【例7-26】,【例7-27】,过程也可以直接在结构体中创建,请读者自行实现在结构体中创建过程compare,然后调用,这里不再赘述。,7.2.5 过程的重载,两个或两个以上有相同过程名和互不相同的参数数量或数据类型的过程称为重载过程。与重载函数相似,重载过程也是通过参数的不同来辨别应该调用哪一个过程的。例7-28中定义了两个重载过程,它们的过程名、参数数量及模式类型都是完全一致的。但第一个过程的参数的数据类型是INTEGER,第二个过程的参数的数据类型是STD_LOGIC_VECTOR。例7-29采用并行过程调用语句对两个重载过程进行了调用。,【例7-28】,【例7-29】,7.2.6 函数与过程的比较,函数和过程统称为子程序,它们都可以实现代码的重用。二者都可以在程序包、实体、结构体或是进程中创建,但只有在程序包中创建的函数和过程才能够被其他设计调用。当在程序包中创建时,必须要在程序包首内声明函数和过程。子程序内部的VHDL代码都是顺序的,即在子程序内部只能使用顺序语句,但WAIT语句除外。另一方面,由于子程序内部是顺序语句,这就意味子程序内部只能声明变量,不能声明信号。,函数和过程的不同如下:(1)函数可以没有、有一个或有多个输入参数,但只能有一个返回值。函数输入参数只能是信号或常量,且默认为常量,不能是变量。(2)过程可以有任意的输入、输出参数(IN、OUT、INOUT),可以是常量、变量和信号。在没有以关键词显式明确参数类型时,输入参数默认是常量,输出参数默认是变量。变量参数不允许出现在并行过程调用中。,
展开阅读全文

开通  VIP、SVIP  下载更划算
下载10份以上建议开通 VIP 会员
下载20份以上建议开通SVIP会员


开通VIP      成为共赢上传

当前位置:首页 > 包罗万象 > 大杂烩

移动网页_全站_页脚广告1

关于我们      便捷服务       自信AI       AI导航        关注我们

©2010-2026 宁波自信网络信息技术有限公司  版权所有

客服电话:0574-28810668  投诉电话:18658249818

gongan.png浙公网安备33021202000488号   

icp.png浙ICP备2021020529号-1  |  浙B2-20240490  

关注我们 :微信公众号    抖音    微博    LOFTER 

客服