- 人工智能硬件电路设计基础及应用
- 廖永波编著
- 1775字
- 2022-05-06 17:41:34
2.1 常量、信号和变量
在VHDL程序中,所有的数据信息都需要存储在一个数据容器中,动态数据用信号(signal)和变量(variable)存储,静态数据用常量(constant)存储。本节将介绍常量、信号和变量,并比较信号与变量的异同。
2.1.1 常量
在VHDL语言中,使用constant标识符定义用来存储静态数据的数据容器被称为常量。
常量的值在定义后就不可改变,不可以对常量进行赋值。定义常量的语法规范如下。
![](https://epubservercos.yuewen.com/B3251C/23020659009785406/epubprivate/OEBPS/Images/43035_29_1.jpg?sign=1739044423-vUapIYq4GuPqdtue0e3DAnKbJp5PNNUK-0-4ef6dc9e2a50ec92f7449d6f9526e71a)
其中,identifier_list为常量名,subtype_indication为常量的类型,conditional_expression为常量的初始值。
常量定义示例如下。
![](https://epubservercos.yuewen.com/B3251C/23020659009785406/epubprivate/OEBPS/Images/43035_29_2.jpg?sign=1739044423-lrgklUHFoboIeRyaOtfiRyjsqBxh9KXM-0-db67149b381388629b15cdae46a1e4bf)
常量可以在包集、实体和结构体中声明。声明了包含常量声明的包集后,VHDL程序内就可以直接调用常量进行赋值、运算等操作。同样,实体的所有结构体都可以调用实体内声明的常量;结构体中声明的常量仅可在结构体内部调用。
2.1.2 信号
在VHDL语言中,信号可以看作逻辑电路中的连线。电路的输入输出端口、电路内部各个单元的连接都需要用到信号。与常量不同,信号存储的数据是可以更改的。对信号进行赋值使用符号<=。定义信号的语法规范如下。
![](https://epubservercos.yuewen.com/B3251C/23020659009785406/epubprivate/OEBPS/Images/43035_29_3.jpg?sign=1739044423-hJb0f6WkXZo5cHtLWC6jL30rAxnd1Qke-0-2f9d18674c1708a9064f5b04f6c37ae0)
其中,identifier_list为信号名,subtype_indication为信号的类型,signal_kind为信号种类,conditional_expression为信号的初始值。
信号定义及赋值示例如下。
![](https://epubservercos.yuewen.com/B3251C/23020659009785406/epubprivate/OEBPS/Images/43035_30_1.jpg?sign=1739044423-HOPcr5j3ekBaqyzj8R0kCWgeApVlWV9e-0-21011d8700dfcfcac05946985c851b9c)
信号一般在实体和结构体中声明。实体中声明的信号可以在实体的所有结构体重调用;结构体中声明的信号仅可在结构体内部调用。
在顺序语句中,如函数(function)等,更改信号的值不会立刻生效,信号只有在相应的函数、进程、过程结束时才会更新信号的值。
2.1.3 信号赋值语句
信号赋值语句是实现对信号进行赋值的语句,修改一个或多个信号驱动的输出波形。信号赋值语句可以分为3种,分别是简单信号赋值语句、条件信号赋值语句、选择信号赋值语句。
简单信号赋值语句的语法结构如下。
![](https://epubservercos.yuewen.com/B3251C/23020659009785406/epubprivate/OEBPS/Images/43035_30_2.jpg?sign=1739044423-hF74jfPCotny1gWJQ7WLNU17TKwQMysb-0-23f7fa7ef48fb13a04e2b7e9b0b57304)
其中,signal_name是需要赋值的目标信号;waveform是目标信号新的输出波形。
条件信号赋值语句的语法结构如下。
![](https://epubservercos.yuewen.com/B3251C/23020659009785406/epubprivate/OEBPS/Images/43035_30_3.jpg?sign=1739044423-v47knQcfwFBpAnoG2NDdkA6NLXvYNTHy-0-83161708ab7511b958496164b8438a15)
其中,signal_name是需要赋值的目标信号;condition是对目标信号赋予新输出波形的条件;waveform是对应的condition为真时,目标信号新的输出波形。
选择信号赋值语句的语法结构如下。
![](https://epubservercos.yuewen.com/B3251C/23020659009785406/epubprivate/OEBPS/Images/43035_30_4.jpg?sign=1739044423-yQ5cTYZK3oK4kvXM3pJNQ77HEgrFRDhx-0-624cf1293b2add8dee35eb3e9bbd4458)
其中,expression是进入赋值分支的判断表达式;signal_name是需要赋值的目标信号;choices是构成表达式的取值列表,并且必须涵盖表达式的所有可能取值;waveform是对应choices的目标信号的新的输出波形。
信号赋值语句可作为并行语句使用,也可作为顺序语句使用。需要注意的是,信号的赋值需要等到process结束时才会生效。
例2.1 信号赋值语句示例
示例一中,将信号a和信号b的异或操作和与操作的结果分别赋值给信号s和信号c,实现半加器的功能。
![](https://epubservercos.yuewen.com/B3251C/23020659009785406/epubprivate/OEBPS/Images/43035_31_1.jpg?sign=1739044423-qXCFxDTY7TPzrrVIOExD4q0E3aL04OsE-0-79d753969b3e8f4f81aa965a8baddd2f)
示例二中,通过条件赋值语句实现4位优先级编码器。
![](https://epubservercos.yuewen.com/B3251C/23020659009785406/epubprivate/OEBPS/Images/43035_31_2.jpg?sign=1739044423-U7UcesDnLLWOekXxHN1fV4o6vx1xYJ7p-0-99e54dabc63c4fd732a7be500561cb45)
示例三中,将command作为判断表达式,根据command的值实现各种基础的门电路,如command为“000”时,选择赋值语句为输入与门;command为“100”时,选择赋值语句为异或门。
![](https://epubservercos.yuewen.com/B3251C/23020659009785406/epubprivate/OEBPS/Images/43035_31_3.jpg?sign=1739044423-4QOMg11R3k5bkFtut9133l1jBVJsX5gs-0-a15b5bcda65acb3e45cf83cbbbc86686)
2.1.4 变量
变量是另外一种存储动态数据的容器。与信号不同,变量只能在函数、进程和过程的内部使用,在局部电路中使用。另外,对变量进行赋值,变量的值是立即生效的。对变量进行赋值,使用符号:=。定义变量的语法规范如下。
![](https://epubservercos.yuewen.com/B3251C/23020659009785406/epubprivate/OEBPS/Images/43035_32_1.jpg?sign=1739044423-l2crdhN8da1sQUGVEzqXEq9Vy9eZhypX-0-7309efe5ed2c39c0efad3218d89681b5)
其中,shared可以定义共享变量,identifier_list为信号名,subtype_indication为信号的类型,signal_kind为信号种类,generic_map_aspect为类属映射表,conditional_expression为信号的初始值。
变量定义及赋值示例如下。
![](https://epubservercos.yuewen.com/B3251C/23020659009785406/epubprivate/OEBPS/Images/43035_32_2.jpg?sign=1739044423-dwE7oBbbtfNyb9GOCtY9tFO86hjvvAKd-0-2b2503c9da1bede135d4bc8c97a13a04)
信号一般在函数、进程和过程中声明和调用。但是,共享变量可以在包集、实体和结构体中声明,也可以在相应的部分调用信号。
2.1.5 变量赋值语句
变量赋值语句是实现对变量进行赋值的语句,将变量的当前值修改为一个新的值。变量赋值语句可以分为两种,分别是简单变量赋值语句、选择变量赋值语句。
简单变量赋值语句的语法结构如下。
![](https://epubservercos.yuewen.com/B3251C/23020659009785406/epubprivate/OEBPS/Images/43035_32_3.jpg?sign=1739044423-hGzY01aphvj0XStOFUWlhMicADK0RIod-0-3d60a1d6fea88d3e1d0ce8ed6223849a)
其中,variable_name是需要赋值的目标变量;expression是目标变量新值的表达式形式。
选择信号赋值语句的语法结构如下。
![](https://epubservercos.yuewen.com/B3251C/23020659009785406/epubprivate/OEBPS/Images/43035_33_1.jpg?sign=1739044423-M9xII0T8tuECIy8Ijp0uHuN7q73cPRXq-0-7445f5af60cc710c4ca9db223ff85086)
其中,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。
![](https://epubservercos.yuewen.com/B3251C/23020659009785406/epubprivate/OEBPS/Images/43035_33_2.jpg?sign=1739044423-UWgSFbBkvkTakU6jDbq8tPo2n5YL7KhX-0-6362c80f58d5e1d17a1d02bc7cd049a7)
示例二与2.1的示例三实现相同的功能。但此处的data_out必须是变量,且示例二的选择变量赋值语句必须在process、function或prcedure中执行。
![](https://epubservercos.yuewen.com/B3251C/23020659009785406/epubprivate/OEBPS/Images/43035_33_3.jpg?sign=1739044423-4JNyYubqdTsk76qarktozgLKYlq1LaER-0-69da03e6d6ccef3a1455ac3527e94a26)
2.1.6 比较信号和变量
信号和变量之间的区别如表2.1所示。在顺序代码中,变量即时更新,信号却要到顺序代码段结束才会更新,这是实际项目中在信号和变量中做出选择需要考虑的因素之一。
表2.1 信号和变量的比较
![](https://epubservercos.yuewen.com/B3251C/23020659009785406/epubprivate/OEBPS/Images/43035_34_1.jpg?sign=1739044423-eQs3GES2sbFDcFlO7O8I9wtkhj1sUcxP-0-b31de9f75229b0c214df510a906b6b7d)