一个完整的VHDL程序组成有5部分:实体(entity)、结构体(architecture)、库(library)、配置(configuration)和包(package)。其中实体用于描述所设计电路的外部接口信号;结构体用于描述系统内部的结构和行为,建立输入和输出之间的关系;配置语句安装具体元件到实体—结构体对,可以被看作是设计的零件清单;包集合存放各个设计模块共享的数据类型、常数和子程序等;库是专门存放预编译程序包的地方。我们以例2.1所示的2选1数据选择器为例,其中程序的头两行为包的调用,中间为实体部分,后部为结构体部分。
在一个电路的VHDL描述中,实体和结构体部分是不可或缺的,其余部分则根据需要纳入程序中。
实体用于描述电路和系统的输入、输出端口及其性质等外部信息,例如端口信号名称、端口模式、数据类型等。实体类似于一个“黑盒子”,描述了“黑盒子”的输入输出端口,实体格式如下:
例如:
我们可以把mux21a这个实体看作是一个具有三个输入端和一个输出端的逻辑电路,具体功能未知。
1)port语句
port语句为端口说明语句,类似于器件的引脚,其格式如下:
实体的端口可以有5种模式,如表2-1所示。其中LINKAGE模式通常用在一个VHDL实体连接另一个非VHDL实体时,此模式使用时有一定的限制,所以较少使用。
表2-1 实体端口模式
端口的数据类型主要有以下4种:
bit:位类型,取值只有“0”或“1”,主要用于描述单个信号引脚。
bit_vector:位矢量,由IEEE库中的程序包numeric_bit支持,程序包定义了位矢量的基本元素是bit类型,主要用于描述一组信号引脚。
std_logic:逻辑类型,IEEE_std_logic_1164程序包支持,其取值为0(信号0)、1(信号1)、H(弱信号1)、L(弱信号0)、Z(高阻)、X(不定)、W(弱信号不定)、U(初始值)和—(不可能情况)9种,是数字电路设计的工业标准逻辑类型,主要用于描述单个信号引脚。
std_logic_vector:逻辑矢量,其基本元素是std_logic类型,主要用于描述一组信号引脚。
VHDL的数据类型除此之外还有布尔类型、数组类型、枚举类型等,具体参见2.2小节。
2)generic类属说明语句
generic类属说明语句提供端口界面常数,用来规定端口的大小,如总线宽度,实体中子元件的数目,以及时间参数等静态信息。与常数不同,常数只能从内部赋值而类属参量可以由实体外部赋值。其格式如下:
generic ([常数名: 数据类型[: =设定值]]);
例如,若实体中有如下语句:
generic (w: integer: =16); port (abus: out bit_vector (w-1 downto 0));
则相当于
port (abus: out bit_vector (15 downto 0));
结构体(architecture)用于描述电路和系统的功能信息,是对系统的结构或行为(逻辑功能)的具体描述。每一个结构体必须有一个实体与它相对应,所以两者一般成对出现。其格式如下:
例如上例2选1数据选择器中的结构体部分:
结构体名是该结构体的唯一名称,of后面跟随的实体名表明该结构体对应的是哪个实体,一个实体可以有多个结构体,具体综合时,采用哪个结构体来确定设计实体的结构和功能可以由配置语句来完成,具体参见本节“配置”部分。
结构体由两部分组成,关键字begin前为结构体的说明语句部分,用于对结构体内部所用到的信号、常数和函数等的定义,其定义只对结构体内部可见,即结构体内部可以使用;begin后为结构体功能描述部分,由并行语句构成,用于描述电路的功能和逻辑行为。并行语句是硬件描述语言独有的特点,这也是由硬件电路本身的结构决定的。以图2-2所示半加器为例,其结构体的VHDL描述如下:
图2-2 半加器
虽然结构体内部的两条信号赋值语句在书写上有先后顺序,但是两条语句的执行是并行的,即若a或b上的信号有变化,则y和c上的信号变化是同时的,这一点是与电路的硬件结构相符的。
库(library)是经编译后的数据的集合,它存放包集合定义、实体定义、结构体定义和配置定义。库的功能类似于操作系统中的目录,库中存放设计的数据。在VHDL语言中,库的说明总是放在设计单元的最前面,这样在设计单元内的语句就可以使用库中的数据。由此可见,库的好处就在于使设计者可以共享已经编译过的设计结果。
在VHDL语言中可以存在多个不同的库,库和库之间是独立的,不能相互嵌套。当前在VHDL语言中存在的库大致可以分为两类,一类是用户自行生成的IP库,汇集用户设计需要所开发的共用包集合和实体等,使用时要首先说明库名。另一类是PLD、ASIC芯片制造商提供的库,例如常用的74系列芯片、RAM、ROM控制器、Counter计数器等标准模块。用户可以直接引用,而不必从头编写。这类库又可以分为4种:IEEE库、STD库、ASIC矢量(VITAL)库和WORK库。
STD库是VHDL的标准库,包含了两个标准程序包,STANDARD和TEXTIO程序包,用户在使用时可以不用进行库的说明。
IEEE库是VHDL标准库的扩展,包含有std_logic_1164、std_logic_arith和std_logic_unsigned、numeric_std、numeric_bit、math_real、math_complex等常用程序包。
ASIC矢量(VITAL)库是面向ASIC的库,存放着与逻辑门一一对应的实体,使用时要对库进行必要的说明。VITAL程序包已成为IEEE标准,并已并到IEEE库中,包含VITAL_TIMING和VITAL_PRIMITIVES两个时序程序包,对ASIC提供高精度和高效率的仿真模型库。
WORK库是用户的现行工作库,设计者所描述的VHDL语句不需要任何说明,都将存放在WORK库中,使用时无须进行任何说明。需要注意,WORK库只是一个逻辑名,不存在WORK库的实名。
除STD库和WORK库外,其他的库在使用时必须先说明库和包集合名。库及程序包的调用语句格式如下:
library 库名; use 库名.程序包.all; use 库名.程序包.项目名;
例如:
library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_1164.rising_edge;
对于常用库中的常用程序包的说明如表2-2所示。
表2-2 常用库中的常用程序包
库的作用范围从一个实体说明开始到它所属的结构体、配置为止,当有两个实体时,第二个实体前要另加库和包的说明。
配置(configuration)用于从库中选取所需单元来完成自己的设计方案,组成系统设计的不同规格的不同版本,使被设计系统的功能发生变化。配置语句描述层与层之间的连接关系以及实体与结构之间的连接关系,在仿真每一个实体时,可以利用配置来选择不同的结构体,进行性能对比试验以得到性能最佳的结构体。在VHDL语言中,经常使用的配置有以下3类:默认配置、元件配置和结构配置。
1)默认配置
默认配置是VHDL语言中最简单的一种配置结构,默认配置常常被设计者用来为一个设计实体选择不同的结构体,每一种结构体对应设计实体的一种实现方案。设计者可以通过不同结构体速度和面积等性能指标的对比从而确定一个最佳的设计方案。VHDL中默认配置的语句格式如下:
表示将<结构体名>指定的结构体作为由<实体名>指定的实体进行综合或仿真时采用的结构体。默认配置定义好之后,在其他配置中如元件配置或结构配置中,可以<配置名>的形式对其进行引用。
【例2.2】 默认配置使用的实例。
上述两个配置语句分别定义了两对实体-结构体之间配置关系。第一个配置语句的配置名为and2_conf,将结构体and2指定给实体exam,第二个配置语句的配置名为or2_conf,将结构体or2指定给实体exam。两个配置语句分别指定了实体exam的两种不同实现方案,一个为与门,一个为或门。两种实现方案在Quartus中综合得到的RTL图如图2-3所示。
图2-3 两种配置方案的RTL综合图
一个VHDL程序中允许存在多个配置语句,在Quartus软件中,综合时默认采用第一个配置语句指定的配置方案。
2)元件配置
元件配置主要用于层次化电路设计中,高层的设计往往需要调用多个其他的元件。利用元件配置语句,设计者可以为高层设计中的每一个被调用元件配置一个特定的结构体。这可以通过两种方式来实现:一种方式是直接指定,即直接为每一个被调用的元件指定一个特定的结构体;另外一种是间接指定,即为底层每一个被调用的元件指出该元件使用哪一个配置,由该配置来确定该元件在综合或仿真时所采用的结构体,使用这种方式时,底层元件的配置必须事先定义好。这两种方式在VHDL语言中可分别由对应的配置语句来实现,即实体-结构体对配置语句和底层元件配置语句。
(1)实体-结构体对配置
实体-结构体对配置是在层次化电路设计中,直接为高层设计调用的底层元件指定具体结构体的一种配置方式。其配置语句格式如下:
通过“for<元件例化标号名>:<底层元件名>use entity <库名>.<实体名>(<结构体名>)”语句为被调用元件指定结构体,其中子句中的“<库名>”一般为用户工作库,即WORK库。
例如在一个高层设计实体exam_h的结构体struct中需要调用2个不同结构的exam元件,则可以采用如下的配置语句:
(2)底层元件配置
底层元件配置是另外一种为高层设计中调用的元件指定具体结构体的方式。它通过为底层被调用的元件指定配置的方式来确定该底层元件在综合或仿真时所采用的结构体,是一种间接指定的方式。其配置语句格式如下:
例如上例中在高层设计实体exam_h的结构体struct中调用2个不同结构的exam元件,则可以采用如下的底层元件配置语句:
默认配置和元件配置都具有独立的标识,可以在其他设计中对其进行引用,习惯上将这两种配置写在VHDL语言程序的末尾。
3)结构配置
在VHDL语言中,还允许在结构体说明部分对该结构体中所引用的元件的具体装配(即综合或仿真时采用的结构体)进行详细说明,这种配置方式称为结构配置。结构配置的语句格式如下:
for 元件例化标号名: 元件名use entity库名.实体名 (结构体名);
或者
for 元件例化标号名: 元件名use库名.元件配置名;
可以看出,上面两个语句分别与前述元件配置中的实体-结构体配置和底层元件配置相对应,例如可以在上例的实体exam_h的结构体说明部分写上以下两条语句:
for u0: exam use entity work.exam (and2); for u1: exam use entity work.exam (or2);
或者
for u0: exam use configuration work.and2_conf; for u1: exam use configuration work.or2_conf;
包(package)用来存放VHDL语言中所要用到的信号定义、常数定义、数据类型、元件语句、函数定义和过程定义等。它是一个可编译的设计单元,主要任务是共享相同的数据单元,在包集合内说明的数据允许其他的实体所引用,即包中定义的内容对其他设计项目也是可见的。
包的使用在前面库的讲解中提到过,用use语句完成,例如下面的语句即表示调用ieee的std_logic_1164包:
use ieee.std_logic_1164.all
包集合由包头和包体两部分组成,包的格式如下:
在包头的说明语句部分,要在此列出包中所有项的名称;在包体的说明语句部分,要给出包头中列出的各项的具体细节。
下例是一个名字为mylogic的包,包里定义了一个有三个取值的枚举类型three_logic,一个具有三个返回值的函数invert,程序包如下:
从例子中可以看出,包头为包集合定义接口,声明包中的类型元件、函数和子程序,其方式与实体定义模块接口非常相似,区别在于entity中指定的信号在元件外部可用,而package的说明语句则指定哪些子程序、常量和数据类型在package外部可用。包体是次级设计单元,可以在其对应的主设计单元之后,独立编译并插入设计库中。包体用来存放程序包中指定的函数和过程本身的程序体,其格式与结构体相同,architecture描述元件的行为,而包体描述包中所说明的子程序的行为。
对于上例中mylogic包的使用,可以使用下面的语句:
use mylogic.three_logic, mylogic.invert
则下面的VHDL程序中就可以使用mylogic中定义的three_logic数据类型和invert函数。
VHDL语言支持三种结构体的描述方式:行为描述方式、寄存器传输级(Register-Transfer-Level,RTL)描述方式、结构描述方式,也支持这三种描述方式相互混合的描述方式。
1)行为描述方式
行为描述方式是对系统数学模型的描述,用输入/输出响应来描述器件的模型。其只描述电路的功能,而不关注电路的结构或是具体的门级实现。同时不针对专门的硬件用于综合和仿真。其抽象程度比寄存器传输方式和结构描述方式的程度更高。一般,6万门以上用行为描述可以提高效率。
例2.1所示的2选1数据选择器的VHDL描述就是一种基于行为描述的电路设计方法。
2)寄存器传输级描述方式
RTL描述也称数据流描述方式。RTL级描述是以规定设计中的各种寄存器形式为特征,然后在寄存器之间插入组合逻辑。它描述了数据流的运动路径、运动方向和运动结果。由于受逻辑综合的限制,采用RTL描述方式时,所用的VHDL语言的语句有一定的限制。RTL描述方式类似于布尔方程,可以描述时序电路,也可以描述组合电路。它既含有逻辑单元的结构信息,又隐含某种行为,是非结构化的并行描述。由于RTL描述是对从信号到信号的数据流的路径形式进行描述,因此很容易进行逻辑综合,也可认为是一种用于综合的行为描述模型。
图2-4 2选1数据选择器
以图2-4所示的2选1数据选择器为例,其布尔方程为:y=a·sel'+b·sel,则其RTL描述的VHDL结构体部分如下所示。
3)结构描述方式
对于一个复杂的电子系统,可以分解成许多子系统,子系统再分解成模块。多层次设计可以使设计多人协作,并且同时进行。多层次设计时每个层次都可以作为一个元件,再构成一个模块或构成一个系统,每个元件可以分别仿真,然后再整体调试。结构描述方式,就是在多层次的设计中,高层次的设计模块调用低层次的模块,或者直接用门电路设计单元来构成一个复杂电路的描述方法。结构化描述不仅是一个设计方法,并且是一种设计思想,对于大型电子系统的设计可以很好地提高设计效率。
图2-5 mux电路结构图
例如一个内部带有2个2选1数据选择器mux21a的电路mux如图2-5所示,其VHDL的结构描述如下所示。
在实际电路设计时,为了能兼顾整个设计的功能、资源、性能等方面的因素,通常也可以采用混合描述方式,即上述三种描述方式的组合。