
2.1 常量、信号和变量
在VHDL程序中,所有的数据信息都需要存储在一个数据容器中,动态数据用信号(signal)和变量(variable)存储,静态数据用常量(constant)存储。本节将介绍常量、信号和变量,并比较信号与变量的异同。
2.1.1 常量
在VHDL语言中,使用constant标识符定义用来存储静态数据的数据容器被称为常量。
常量的值在定义后就不可改变,不可以对常量进行赋值。定义常量的语法规范如下。

其中,identifier_list为常量名,subtype_indication为常量的类型,conditional_expression为常量的初始值。
常量定义示例如下。

常量可以在包集、实体和结构体中声明。声明了包含常量声明的包集后,VHDL程序内就可以直接调用常量进行赋值、运算等操作。同样,实体的所有结构体都可以调用实体内声明的常量;结构体中声明的常量仅可在结构体内部调用。
2.1.2 信号
在VHDL语言中,信号可以看作逻辑电路中的连线。电路的输入输出端口、电路内部各个单元的连接都需要用到信号。与常量不同,信号存储的数据是可以更改的。对信号进行赋值使用符号<=。定义信号的语法规范如下。

其中,identifier_list为信号名,subtype_indication为信号的类型,signal_kind为信号种类,conditional_expression为信号的初始值。
信号定义及赋值示例如下。

信号一般在实体和结构体中声明。实体中声明的信号可以在实体的所有结构体重调用;结构体中声明的信号仅可在结构体内部调用。
在顺序语句中,如函数(function)等,更改信号的值不会立刻生效,信号只有在相应的函数、进程、过程结束时才会更新信号的值。
2.1.3 信号赋值语句
信号赋值语句是实现对信号进行赋值的语句,修改一个或多个信号驱动的输出波形。信号赋值语句可以分为3种,分别是简单信号赋值语句、条件信号赋值语句、选择信号赋值语句。
简单信号赋值语句的语法结构如下。

其中,signal_name是需要赋值的目标信号;waveform是目标信号新的输出波形。
条件信号赋值语句的语法结构如下。

其中,signal_name是需要赋值的目标信号;condition是对目标信号赋予新输出波形的条件;waveform是对应的condition为真时,目标信号新的输出波形。
选择信号赋值语句的语法结构如下。

其中,expression是进入赋值分支的判断表达式;signal_name是需要赋值的目标信号;choices是构成表达式的取值列表,并且必须涵盖表达式的所有可能取值;waveform是对应choices的目标信号的新的输出波形。
信号赋值语句可作为并行语句使用,也可作为顺序语句使用。需要注意的是,信号的赋值需要等到process结束时才会生效。
例2.1 信号赋值语句示例
示例一中,将信号a和信号b的异或操作和与操作的结果分别赋值给信号s和信号c,实现半加器的功能。

示例二中,通过条件赋值语句实现4位优先级编码器。

示例三中,将command作为判断表达式,根据command的值实现各种基础的门电路,如command为“000”时,选择赋值语句为输入与门;command为“100”时,选择赋值语句为异或门。

2.1.4 变量
变量是另外一种存储动态数据的容器。与信号不同,变量只能在函数、进程和过程的内部使用,在局部电路中使用。另外,对变量进行赋值,变量的值是立即生效的。对变量进行赋值,使用符号:=。定义变量的语法规范如下。

其中,shared可以定义共享变量,identifier_list为信号名,subtype_indication为信号的类型,signal_kind为信号种类,generic_map_aspect为类属映射表,conditional_expression为信号的初始值。
变量定义及赋值示例如下。

信号一般在函数、进程和过程中声明和调用。但是,共享变量可以在包集、实体和结构体中声明,也可以在相应的部分调用信号。
2.1.5 变量赋值语句
变量赋值语句是实现对变量进行赋值的语句,将变量的当前值修改为一个新的值。变量赋值语句可以分为两种,分别是简单变量赋值语句、选择变量赋值语句。
简单变量赋值语句的语法结构如下。

其中,variable_name是需要赋值的目标变量;expression是目标变量新值的表达式形式。
选择信号赋值语句的语法结构如下。

其中,expression_select是进入赋值分支的判断表达式;variable_name是需要赋值的目标变量;choices构成表达式的取值列表,并且必须涵盖表达式的所有可能取值;expression是对应choices的目标变量新值的表达式形式。
变量赋值语句是顺序语句的一种,只能在process、function和procedure内部使用,且变量的赋值是立即生效的。
例2.2 变量赋值语句示例
示例一定义了记录类型bit_record和该类型的变量a,定义了bit类型变量e和integer类型变量i。语句1和语句2是对bit_record类型变量a的bit_field和int_field赋值;语句3是将变量a包含的值赋给变量e和变量i。

示例二与2.1的示例三实现相同的功能。但此处的data_out必须是变量,且示例二的选择变量赋值语句必须在process、function或prcedure中执行。

2.1.6 比较信号和变量
信号和变量之间的区别如表2.1所示。在顺序代码中,变量即时更新,信号却要到顺序代码段结束才会更新,这是实际项目中在信号和变量中做出选择需要考虑的因素之一。
表2.1 信号和变量的比较
