第4章VHDL程序设计基础4.1库4.2程序包4.3元件库4.4配置概述4.5子程序和重载4.6关于变量用法的进一步讨论4.1库(LIBRARY)一、库的一般结构库程序包程序包元件定义常数说明数据类型说明子程序说明(函数、过程等)┊┊不同库中的包有多有少,每个包中的内容也没有定数。包中存放的通常是一些基础设计内容,可供不同的设计实体访问和调用。库的种类设计库资源库STD库WORK库IEEE库EDA厂商库二、库的种类STD库:收录了VHDL语言标准定义的两个标准程序包,即STANDARD和TEXTIO程序包。WORK库:是VHDL语言的工作库,用于保存当前正在进行的设计。用户的成品、半成品模块、元件等会自动进入此库存放。IEEE库:是VHDL设计中最为常见的库,它包含有IEEE标准的程序包和其他一些支持工业标准的程序包。EDA厂商库:如:ALTERA公司的资源库、SYNOPSYS公司的资源库(有些包已并入了IEEE库)等等。三、库的用法库的使用说明总是放在实体单元最前面,库语句LIBRARY一般必须与USE语句同用。设计库(STD库、WORK库)对当前项目是可见的、默认的。无需用Library子句、USE子句声明。资源库(IEEE库、EDA厂商库)必须用Library子句、USE子句声明方可使用,声明语句格式:LIBRARY库名;USE库名.程序包名.ALL(或项目名);--LIBRARY语句为其后的设计实体打开了以此库名命名的库,以便设计实体可以利用其中的程序包。--USE语句用来开放指定库中指定程序包内所有内容(或指定项目)。VHDL要求一项含有多个设计实体的更大的系统,每一个设计实体都必须有自己完整的库说明语句和USE语句。如:LIBRARYIEEE;USEIEEE.STD_LOGIC_1164.ALL;USEIEEE.STD_LOGIC_UNSIGNED.ALL;如:LIBRARYIEEE;USEIEEE.STD_LOGIC_1164.STD_ULOGIC;USEIEEE.STD_LOGIC_1164.RISING_EDGE;--以上的三条语句表示打开IEEE库,再打开此库中的STD_LOGIC_1164程序包和STD_LOGIC_UNSIGNED程序包的所有内容。为了使已定义的常数、数据类型、元件调用说明以及子程序能被更多的设计实体方便地访问和共享,可以将它们收集在一个程序包中。多个程序包可以并入一个库中,使之适用于更一般的访问和调用范围。这一点对于大系统开发,多个或多组开发人员并行工作显得尤为重要。程序包的内容主要由如下四种基本结构组成,因此一个程序包中至少应包含以下结构中的一种。①常数说明:主要用于预定义系统的宽度,如数据总线通道的宽度。②数据类型说明:主要用于说明在整个设计中通用的数据类型,例如通用的地址总线数据类型定义等。③元件定义:主要规定在VHDL设计中参与元件例化的文件(已完成的设计实体)对外的接口界面。④子程序说明:用于说明在设计中任一处可调用的子程序。4.2程序包(PACKAGE)PACKAGE程序包名IS--程序包首开始程序包首说明部分;END[PACKAGE][程序包名];--程序包首结束PACKAGEBODY程序包名IS--程序包体开始程序包体说明部分以及包体内容;END[PACKAGEBODY][程序包名];--程序包体结束一、程序包结构和定义程序包由两部分组成;程序包首和程序包体。名字要相同,在语句的表现上,包体比包首多了BODY一词。包首是主设计单元,为程序包定义接口,声明包中的类型、元件、函数和子程序,其方式与实体定义模块接口非常相似。包首可独立地编译并插入设计库中。包体是次设计单元,规定程序的实际功能,存放包首中说明的函数和子程序,其方式与结构体语句方法相同。包体可以在其对应的主设计单元后,独立地编译并插入设计库中。例:一个完整的程序包的范例。PACKAGEPkg_exampleISCONSTANTpi:real:=3.1415926535897936;CONSTANTdeferred_constant:integer;FUNCTIONmean(a,b,c:real)RETURNreal;COMPONENTand_gateISPORT(in1,in2:INbit);ENDand_gate;ENDPkg_example;PACKAGEBODYPkg_exampleISFUNCTIONmean(a,b,c:real)RETURNrealIS;BEGINRETURN(a+b+c)/3.0;ENDmean;┅ENDPkg_example;包首的说明部分可收集多个不同的VHDL设计所需的公共信息,其中包括数据类型说明、信号说明、子程序说明及元件说明等。程序包结构中,包体并非是必须的,包首可以独立定义和使用。1.程序包首例1:PACKAGEPAC1IS--程序包首开始TYPEBYTEISRANGE0TO255;--定义数据类型BYTESUBTYPEBYTE1ISBYTERANGE0TO15;--定义子类型BYTE1CONSTANTC1:BYTE:=255;--定义常数C1SIGNAS1:BYTE1;--定义信号S1COMPONENTBYTE_ADDERIS--定义元件PORT(A,B:INBYTE;C:OUTBYTE;OVERFLOW:OUTBOOLEAN);ENDCOMPONENTBYTE_ADDER;FUNCTIONMY_FUNCTION(A:INBYTE)RETURNBYTE;--定义函数ENDPACKAGEPAC1;--程序包首结束若要使用该程序包中的所有定义,可用USE语句访问此程序包:LIBRARYWORK;--此两句可省去USEWORK.PAC1.ALL;ENTITY…ARCHITECTURE…例2:在现行WORK库中定义程序包并立即使用的示例。PACKAGESEVENIS--定义程序包SUBTYPESEGMENTSISBIT_VECTOR(0TO6);TYPEBCDISRANGE0TO9;ENDPACKAGESEVEN;USEWORK.SEVEN.ALL;--打开程序包,以便后面使用ENTITYDECODERISPORT(SR:INBCD;SC:OUTSEGMENTS);ENDENTITYDECODER;ARCHITECTUREARTOFDECODERISBEGINWITHSRSELECTSC=B“1111110”WHEN0,B“0110000”WHEN1,B“1101101”WHEN2,B“1111001”WHEN3,B“0110011”WHEN4,B“1011011”WHEN5,B“1011111”WHEN6,B“1110000”WHEN7,B“1111111”WHEN8,B“1111011”WHEN9,B“0000000”WHENOTHERS;ENDARCHITECTUREART;包体用于定义在包首中已定义的子程序的子程序体。包体说明部分的组成可以是USE语句(允许对其他程序包的调用)、子程序定义、子程序体、数据类型说明、子类型说明和常数说明等。对于没有子程序说明的包首,包体可以省去。程序包常用来封装属于多个设计单元分享的信息,程序包定义的信号、变量不能在设计实体之间共享。2.程序包体3.常用的预定义的程序包①STD库中的STANDARD包定义了若干类型、子类型和函数。布尔类型位Bit类型字符类型出错级别实数范围整数范围时间单位等子类型有:延迟长度自然数范围整数范围等提示:包结构中的具体内容参看P79。②STD库中的TEXTIO包该包中定义了支持ASCI/O操作的若干类型和子程序。TEXTIO包不能自动与任意模型连接,需要在使用它的任一设计单元之前加一个USE子句:USESTD.TEXTIO.ALL;③IEEE库中的Std_Logic_1164包访问std_Logic_1164程序包,需声明:LIBRARYIEEE;USEIEEE.std_Logic_1164.AlL;Std_Logic_1164程序包中含有:Std_Logic;Std_Logic_Vector;其他常用类型函数。提示:包结构中的具体内容参看P81。④IEEE库中的Numeric_Std包该包中定义了用于综合的数值类型和算术函数。其中数值类型为:Unsigned--表示向量形式的无符号数Signed--表示向量形式的带符号数,采用补码形式。该包中还含有类型转换函数、时钟检测函数和其他的实用函数等。⑤IEEE库中的Numeric_Bit包VHDL综合程序包Numeric_Bit的基本元素类型为Bit类型,而不是Std_Logic类型。在一些VHDL仿真中,把这个包预先编译在Ieee库中,使用这些功能也必须预先声明,使这个程序包成为可见。4.3元件库在VHDL程序设计中,始终贯穿着库的使用,在一些标准库中除了有许多有用的预定义的数据类型、函数、过程可调用外,并存放了各种已设计好的通用元件可供设计者调用。另外,有些EDA开发商在其EDA工具中,也为用户提供了各种元件库。而且用户也可建立自己的元件库。对元件库运用来讲,需要掌握的内容是:①元件构造;②元件打包;③构建元件库;④元件的调用;一、元件构造要点是:元件设计要参数化,要带有参数入口,使得元件的调用灵活、方便。据此应尽量做到通过参数传递(Generics)来指定元件的规模和参数的有关特性。例:设计一个带有异步复位端的D触发器,为方便、灵活起见,创建的触发器宽度任意,在将来的设计中用参数指定它的宽度。为此,有必要设计一个规模大小、电路性能都可以通过参数引用(Generics)进行指定的参数化元件。要求如下:--设计一个通用的n位D触发器--宽度(1,n)--CLK输入时钟--reset异步复位--d寄存器输入--q寄存器输出输出信号端口都使用buffer类型,作为n位元件内部互连的端口。而in,out作为n位D触发器组的外部端口与信号相连。参数传递size定义std_Logic_Vector型的信号d和q的宽度。libraryieee;useieee.std_logic_1164.allentityrdffisgeneric(size:integer:=2);--参数设置port(clk,reset:instd_logic;d:instd_logic_vector(size-1downto0);q:bufferstd_logic_vector(size-1downto0));endrdff;architecturearchrdffofrdffisbeginP1:process(reset,clk)beginifreset=‘1’thenq=(others=0);elsif(clk'eventandclk=‘1’)thenq=d;endif;endprocessP1;endarchrdff;Beffer,size两项是参数化元件设计的要点。二、元件打包(即在包首中对元件定义)libraryieee;useieee.std_logic_1164.all;packageregs_pkgis--包首componentrdff--元件说明(定义)generic(size:integer:=2);--参数设置port(clk,reset:instd_logic;d:instd_logic_vector(size-1downto0);q:bufferstd_logic_vector(size-1downto0));endcomponent;…endregs_pkg;--包首结束例:将前例中已设计好的一个通用的n位D触发器进行打包。说明:此处是将元件rdff(n位D触发器)打包在名为regs_pkg的包首中。方法是用元件调用语句(COMPONENT)在包首中对打包元件作说明即可。其他元件说明三、构建元件库将程序放入库中,因不同的EDA工具,操作方法也不一致。MAX+plus的设计库允