
1.1 库和包集
库(LIBRARY)是一些常用代码的合集。将电路设计中经常使用的一些代码段存放到库中,有利于设计的重用和代码的共享。图1.1是库的典型结构。库中的代码通常是以函数(FUNCTION)、过程(PROCEDURE)或者元件(COMPONENT)等标准形式存放在包集(PACKAGE)中的,用户根据需要对其进行编译使用。

图1.1 库的典型结构
1.1.1 库
在使用VHDL进行电路设计时,常用的库可以分为3种:ieee库、std库和work库。除了以上3种库,EDA领域的许多大公司,如Synopsys,也会提供第三方的VHDL库。
ieee库
ieee库是IEEE根据其所发布的1076号和其他扩展标准编写的VHDL库,被IEEE正式认可。ieee库是VHDL设计中常用的库,其包含的包集非常丰富,表1.1是截至本书撰写完成时ieee库所包含的包集。
表1.1 ieee库包含的包集

std库
std库是VHDL设计的标准资源库,包括数据类型和输入输出文本等内容。表1.2是std库所包含的内容。
表1.2 std库包含的包集

第三方库
第三方库是IEEE外的公司、团体或者个人发布的VHDL库,为用户进行VHDL设计提供便利。表1.3是Synopsys库包含的包集。
表1.3 Synopsys库包含的包集

work库
work库是当前工作库,当前设计的所有代码都存放在work库中。调用work库中的函数、过程等内容不需要预先声明。
1.1.2 包集
经常使用的VHDL代码段通常会以函数(FUNCTION)、过程(PROCEDURE)或者元件(COMPONENT)的形式编写。将这些代码段整合为包集,并将其添加到目标库中,可以实现常用代码段的代码分割、代码共享和代码重用。这在编写、调试、维护VHDL代码的过程中是非常实用且重要的。
除了函数、过程和元件之外,包集中也会包含类型(TYPE)和常量(CONSTANT)的定义。
包集的语法结构如下。


包集通常有包集声明和包集主体两个部分,与C语言中函数的声明和定义类似。包集声明一般包含类型、常量、函数等的声明,是必须的。包集主体则包含对应声明中类型、常量、函数等部分的具体实现。包集声明和包集主体可以存在于同一个文件内,但一般情况下,包集声明和包集主体分别保存为“package_name.vhdl”和“package_name-body.vhdl”两个文件。VHDL程序在综合时通过声明的包集名称定位到包集声明和主体两个文件上,并在包集文件中定位到调用的类型、常量、函数等代码段。
除了包集声明和包集主体外,包集还可以将已有包集进行实例化,与JAVA中类的继承类似。实例化包集相当于一个类属映射重定义的包集声明,包含了包集声明和包集主体。其语法结构如下。

ieee.std_logic_1164包集部分内容示例
类型定义
STD_ULOGIC是ieee.std_logic_1164包集(以下简称1164包集)定义的枚举类型,可取范围是9值逻辑系统。9值逻辑系统包含了未定义、强不确定值、强0、强1、高阻态、若不确定值、弱0、弱1、随意值。
STD_ULOGIC_VECTOR是由一个或者多个STD_ULOGIC组成的数组类型。


子类型定义
STD_LOGIC是VHDL中常用的数据类型之一,是1164包集中STD_ULOGIC的决断子类型。STD_LOGIC是为了解决VHDL多驱动问题而被定义的,其取值范围是8值逻辑系统,即强不确定值、强0、强1、高阻态、弱不确定值、弱0、弱1、随意值。
相应地,1164包集还定义了STD_ULOGIC_VECTOR的决断子类型STD_LOGIC_VECTOR。

函数定义
决断函数是进行STD_ULOGIC等数据类型的决断子类型定义的关键。1164包集在包集声明中声明了如下决断函数。

1164包集的包集主体内决断函数的具体实现如下所示。

过程定义
1164包集定义了一系列读取STD_ULOGIC的过程,通过重载的形式存放在包集中。如下是其中一个读取过程的声明,输出过程运行状态和读取结果。

1164包集的包集主体相应地对以上的读取过程声明进行了实现。

重载函数和重载过程
VHDL的包集中,同一个函数或过程标识符会有不同的参数列表,进而实现不同的功能。这种不同参数的函数或过程称为重载。重载的函数或过程具有相同的标识符,如“+”“abs”等,但每一个重载函数或过程的参数列表是不同的。VHDL程序在综合时会根据所调用函数或过程的参数列表定位到对应的包集中对应的重载函数或过程。
重载不仅出现在同一个包集中,还会出现在不同的包集,甚至不同的库中。
以数值运算操作符“+”为例,IEEE官方维护的ieee.numeric_std包集、Synopsys发布的ieee.std_logic_signed包集及其他许多包集都有“+”的重载函数。
ieee.numeric_std包集中对两个UNRESOLVED_SIGNED类型的加法运算有如下定义。


ieee.std_logic_signed包集中对两个STD_LOGIC_VECTOR类型的加法运算有如下定义。

UNRESOLVED_SIGNED的决断子类型SIGNED也可以进行上述有符号数加法运算。SIGNED和STD_LOGIC_VECTOR的定义是相似的,但是两者的有符号数加法运算却是完全不同的。SIGNED和STD_LOGIC_VECTOR的定义如下所示。


1.1.3 库和包集的声明
在调用包集中的内容之前,需要实现对所调用的库和包集进行声明。进行声明之后,在所声明的文件内就可以调用数据类型、函数、过程等内容了。库和包集的声明如下。

std库和work库是默认可以调用的,调用之前不需要事先声明。但在结构设计中进行元件的宏调用,是需要对work库进行声明的。
在VHDL程序中,经常使用的库和包集声明如下。
