![人工智能硬件电路设计基础及应用](https://wfqqreader-1252317822.image.myqcloud.com/cover/533/43738533/b_43738533.jpg)
2.2 数据类型
本节主要介绍VHDL预定义的数据类型,包括以下5种:标量类型、复合类型、存取类型、文件类型和保护类型。
2.2.1 标量类型
标量类型包含一个单值。标量类型可分为枚举类型、整型类型、物理类型和浮点类型。枚举类型和整数类型是离散类型。整数类型、物理类型和浮点类型是数字类型。所有的标量类型都是有序的,离散类型和物理类型的位置序号都是整数。
枚举类型
枚举类型是一组具有明确值的集合。枚举中的值是一个命名项或者一个字符。定义枚举类型的语法规范如下。
![](https://epubservercos.yuewen.com/B3251C/23020659009785406/epubprivate/OEBPS/Images/43035_34_2.jpg?sign=1739147568-optzlit6fQE3lvGlvRWMQ9mLBRnW0WVB-0-35a2136193c9e2c014a497a1b3a4714b)
其中,type_name为类型名,enumeration_literal为枚举元素。枚举类型的枚举元素可以是标识符,也可以是字符。相同的枚举元素不可以出现在同一个枚举类型中,但可以存在于不同的枚举类型里。所有的枚举类型都是有序排列的。枚举类型中第一个枚举元素对应的序号是0,后面元素的序号依次加1。IEEE库中的类型大都是基于枚举类型定义的,这部分内容会在后文介绍。
枚举类型定义示例如下。
![](https://epubservercos.yuewen.com/B3251C/23020659009785406/epubprivate/OEBPS/Images/43035_35_1.jpg?sign=1739147568-bq2fuPeYcfhHw3hrJvzW6gBIvIGMifkO-0-82bfb0a444bbbde0c3c5eee678635820)
std库内预定义了许多枚举类型,如character、bit、boolean。预定义的character类型定义了一个字符的枚举类型,包含了ISO/IEC8859-1字符集的256个字符,其定义如下。
![](https://epubservercos.yuewen.com/B3251C/23020659009785406/epubprivate/OEBPS/Images/43035_35_2.jpg?sign=1739147568-744DJ5qr9GQRrKyyqJ6VZEkkCNNZHa50-0-83e9f30a813cc147d2a52f2f24cddd9b)
整数类型
整数类型定义了一个在特定约束范围内取值的整数的数据类型。一个整数类型定义了其本身和该类型的子类型。整数类型是匿名类型,其取值范围应在实现时确定。在调用整数类型的信号和变量时,其值不能超过取值的范围。定义整数类型的语法规范如下。
![](https://epubservercos.yuewen.com/B3251C/23020659009785406/epubprivate/OEBPS/Images/43035_36_1.jpg?sign=1739147568-WYF2Ivfg3KsolfR2pa1iQwANc9Iweclm-0-3276171ff32278fde9de9ccf5d6223d5)
其中,type_name是类型名;range_constraint是取值范围。一般取值范围有3种写法:范围描述名、范围表达式和简单范围。在数据取值没有约束时,可以使用范围描述名<>作为range_constraint,表示该类型在合法范围内取值不受限制。简单范围也是较为常用的,其语法规范如下。
![](https://epubservercos.yuewen.com/B3251C/23020659009785406/epubprivate/OEBPS/Images/43035_36_2.jpg?sign=1739147568-HCYI8CqiyxI4nlp0izg0azsNnLXMZd8P-0-726cd8cd31407ab7cdcf3a9057425b0d)
simple_expression是范围上下限的简单表达式;direction是范围排列的类型,可用to或downto。L to R是递增范围,当L>R时为无效范围;L downto R是递减范围,当L<R时为无效范围。
整数类型定义示例如下。
![](https://epubservercos.yuewen.com/B3251C/23020659009785406/epubprivate/OEBPS/Images/43035_36_3.jpg?sign=1739147568-XR43jBOCcHFM2eJFsoCIWgp0ezT0uDoN-0-a11e7b5294790bbabb19651ce70cd99c)
std库内预定义的唯一的整数类型是integer。integer类型的范围取决于实现,并且应包括-263到263-1之间的范围(递增范围,含-263和-263-1),其定义如下。
![](https://epubservercos.yuewen.com/B3251C/23020659009785406/epubprivate/OEBPS/Images/43035_36_4.jpg?sign=1739147568-oUZ0BzIcd1ZZTLqgQO9ApnFjVWDIXnYu-0-8e4267722f9502fc3e22c44771f43ce6)
物理类型
物理类型定义了一个物理量的数据类型,该类型值表示量度。物理类型的取值应该是该类型基本度量单位的整数倍。物理类型定义的语法规范如下。
![](https://epubservercos.yuewen.com/B3251C/23020659009785406/epubprivate/OEBPS/Images/43035_36_5.jpg?sign=1739147568-TGPI4gZC0734RI2mnguxz5xJnqCuMCOL-0-3e0bbfa939c7cff4d450e6b7ab66a5ce)
![](https://epubservercos.yuewen.com/B3251C/23020659009785406/epubprivate/OEBPS/Images/43035_37_1.jpg?sign=1739147568-MH3ymLyeJvqFnZLbkJ63m9MzoZvsYG1y-0-939a2bb114f1c02b7154a673716e7adc)
其中,type_name是类型名;range_constraint是取值范围约束;primary_unit_declaration是物理类型的基本度量单位的声明;secondary_unit_declaration是基于基本度量单位的二级度量单位。
物理类型定义示例如下。
![](https://epubservercos.yuewen.com/B3251C/23020659009785406/epubprivate/OEBPS/Images/43035_37_2.jpg?sign=1739147568-2ZJokJbJ1u0GHlYwT863HnZENyEFX7Av-0-3054a787b1db51a7b8c8f4256b679e0f)
![](https://epubservercos.yuewen.com/B3251C/23020659009785406/epubprivate/OEBPS/Images/43035_38_1.jpg?sign=1739147568-XE0uDwPZKG3LuJ7EJ4TGHixn7qcGVZC7-0-4b4fafdb8d45dd330099fc6b193a87ec)
std库内预定义的唯一的整数类型是time。time类型的范围取决于实现,并且应包括-263到263-1之间的范围(递增范围,含-263和-263-1)。VHDL程序中所有的延迟和脉冲抑制极限必须是time类型的信号或者变量。time类型的定义如下。
![](https://epubservercos.yuewen.com/B3251C/23020659009785406/epubprivate/OEBPS/Images/43035_38_2.jpg?sign=1739147568-QmDbYsk8IB96DwkCpkZ0QpF5I38ZGd0R-0-1fcd2c0c2f60a5bb9cb02de8bf673451)
浮点类型
浮点类型定义了一个实数近似值的数据类型,用于通过浮点的方式存储实数。浮点类型定义中的范围约束的每个边界应为浮点类型的静态表达式,并且允许使用负浮点数。
![](https://epubservercos.yuewen.com/B3251C/23020659009785406/epubprivate/OEBPS/Images/43035_38_3.jpg?sign=1739147568-KAHvgwx3a5ATlJndDSPQcNxYVItNYkcB-0-5a0b01b820d2d4fe4fc3eddf905c63e2)
其中,type_name是类型名;range_constraint是取值范围约束。
浮点类型的表示方式必须与std库中预定义匿名类型universal_real类型的表示方式相同;对于不相符的浮点类型,可以通过转换函数将universal_real类型转换为该浮点类型。
std库内预定义的唯一的整数类型是real。real类型的范围取决于运行平台,并且取值范围是所允许的最大范围(递增范围)。real类型的定义如下。
![](https://epubservercos.yuewen.com/B3251C/23020659009785406/epubprivate/OEBPS/Images/43035_39_1.jpg?sign=1739147568-IukoGdDxqNPxG5SHbw3EQTNatZaAaBJG-0-8c0bbdf69f15c73db6137be348b2fa26)
标量类型的预定义运算操作
std库为所有的标量类型预定义了运算操作,其声明如下。
![](https://epubservercos.yuewen.com/B3251C/23020659009785406/epubprivate/OEBPS/Images/43035_39_2.jpg?sign=1739147568-YQbEQJgI8xG9yU7dasEL8W9GqIOgimZK-0-cf8ccf6fd85509a5aaf4b362fbd9bf3e)
boolean和bit是std库预定义的枚举类型,其定义如下。
![](https://epubservercos.yuewen.com/B3251C/23020659009785406/epubprivate/OEBPS/Images/43035_39_3.jpg?sign=1739147568-z3waKbuOTg9nBGwJVDiEdbcMHk9TJ353-0-9a33ba447398dab88bfc2ea0f4acdf21)
std库还为以上两种类型定义了边沿判断函数,声明如下。
![](https://epubservercos.yuewen.com/B3251C/23020659009785406/epubprivate/OEBPS/Images/43035_39_4.jpg?sign=1739147568-BRqcZcJosULY0SG0r6jAxboR8bCehKX9-0-64cdba4fe9a0aa3e91b4c4e20f13f997)
2.2.2 复合类型
复合类型是多个元素的集合类型,可分为数组类型和记录类型。
数组类型
数组类型是仅包含相同数据类型元素的集合类型。数组类型定义分为无约束定义和有约束定义两种。无约束数组类型定义如下。
![](https://epubservercos.yuewen.com/B3251C/23020659009785406/epubprivate/OEBPS/Images/43035_39_5.jpg?sign=1739147568-0qIsosvvEMdLGcRcZYazB87LzPVAJDBk-0-3b4c19cd9af65fbbefa7665d16c5cc59)
其中,type_name是类型名;type_mark是索引的类型;type_mark range<>是对单机索引的定义;element_subtype是数组内元素的类型。
有约束数组类型定义如下。
![](https://epubservercos.yuewen.com/B3251C/23020659009785406/epubprivate/OEBPS/Images/43035_40_1.jpg?sign=1739147568-IH4fJP11QrdfTNI9kQpnfAj3YOU0iZmC-0-cdc53f6df80b58487a3688fc8cbcbeaf)
其中,type_name是类型名;element_subtype是数组内元素的类型;index_constraint是索引约束,discrete_range是单级索引约束范围。
数组类型定义及对象声明示例如下。
![](https://epubservercos.yuewen.com/B3251C/23020659009785406/epubprivate/OEBPS/Images/43035_40_2.jpg?sign=1739147568-scx3b4NVUKkPm8f18HtnOQHqJj967WzM-0-dfab38f3e1882fd084ea296c4a38069c)
std库预定义了6种数组类型:string、boolean_vector、bit_vector、integer_vector、real_vector和time_vector。string类型是character类型的一位数组,索引为正数范围;boolean_vector、bit_vector、integer_vector、real_vector和time_vector分别是boolean、bit、integer、real和time类型的一位数组,索引为自然数范围。这些数组类型的定义如下。
![](https://epubservercos.yuewen.com/B3251C/23020659009785406/epubprivate/OEBPS/Images/43035_41_1.jpg?sign=1739147568-O6SZu9KZGYo4T6eBlubFpVz52Xi4cID7-0-070aa36bb0d3b82df9d1381b3277bbf8)
预定义数组类型对象声明如下。
![](https://epubservercos.yuewen.com/B3251C/23020659009785406/epubprivate/OEBPS/Images/43035_41_2.jpg?sign=1739147568-13OUMxrgWDK3M6dF8bHSZRkSkWOiCPc9-0-afc6612fee2b0c18836406875199f6c0)
std库为标量数组类型预定义了运算操作,其声明如下。
![](https://epubservercos.yuewen.com/B3251C/23020659009785406/epubprivate/OEBPS/Images/43035_41_3.jpg?sign=1739147568-ny4MRTWZg1fznEh9EPY16TNgt6qnjcSR-0-b030a398f8bbcf5d4eb6666fa10f7556)
![](https://epubservercos.yuewen.com/B3251C/23020659009785406/epubprivate/OEBPS/Images/43035_42_1.jpg?sign=1739147568-YkJoIGUkVYk4pGKNy0aakOCfzswDtJR8-0-ab177e1e6c15086fc576f6d1c91ebf1a)
记录类型
记录类型是一种符合类型,可包含不同数据类型的元素。如果一个记录类型对象的元素既不是保护类型,也不是文件类型,这个对象的值是由其包含的元素组成的复合值;否则,这个对象就不存在值。记录类型定义的语法规范如下。
![](https://epubservercos.yuewen.com/B3251C/23020659009785406/epubprivate/OEBPS/Images/43035_42_2.jpg?sign=1739147568-Wb2fAY14lxKyEXZP5zP365vts79Z7fFH-0-fc1d9f11ffda0fc12fdbf77ca7621683)
其中,type_name是类型名;identifier_list是元素的名称列表,由一个或多个元素名称组成,通过逗号隔开;element_subtype是元素的数据类型。
记录类型定义及对象声明示例如下。
![](https://epubservercos.yuewen.com/B3251C/23020659009785406/epubprivate/OEBPS/Images/43035_42_3.jpg?sign=1739147568-PfyXFZuWQBjwvTXI8RxL3H10UtaE6HBl-0-9d72d1041967ac462cd33a41f396ff15)
![](https://epubservercos.yuewen.com/B3251C/23020659009785406/epubprivate/OEBPS/Images/43035_43_1.jpg?sign=1739147568-iSPXCHpZ2X6bsD5f9VFEgMAvwe91Qy2p-0-244bf0d34b4359bb82654a40848435d6)
std库为所有标量类型及其子类型定义了取值范围的记录类型,定义如下。
![](https://epubservercos.yuewen.com/B3251C/23020659009785406/epubprivate/OEBPS/Images/43035_43_2.jpg?sign=1739147568-yc3bSsFdUWBMEaoYYURCFV66QKnXBdEX-0-77e389933d5c2f1742eb855ab9942ff9)
以integer类型为例,其范围记录类型为INTEGER_RANGE_RECORD,包含left、right和direction3个元素,分别表示取值范围的左边界、右边界和范围方向(递增或递减)。INTEGER_RANGE_RECORD类型的定义如下。
![](https://epubservercos.yuewen.com/B3251C/23020659009785406/epubprivate/OEBPS/Images/43035_43_3.jpg?sign=1739147568-9BHWT3MNAx1anOg8ckAZzVnnAPy2HFyu-0-7b141debc832add2c7660ce411bb8771)
对于可用字符串表示的记录类型,std库预定义了字符串转换函数to_string,可返回字符串表示形式。to_string函数定义如下。
![](https://epubservercos.yuewen.com/B3251C/23020659009785406/epubprivate/OEBPS/Images/43035_43_4.jpg?sign=1739147568-uaNtSwiF71xCN4rKM2U5YJI9jgEvPdOk-0-cc709e88fdd5a0315f9be7f5ecab0d1d)
2.2.3 存取类型
由对象声明定义的对象是通过对象声明的详细说明创建的,并用简单名称或者其他形式的名称标记的。相反,通过分配器创建的对象是没有简单名称的。对这类对象的访问操作是通过分配器返回的存取值来实现的;存取值指向了这个对象。存取类型与C语言和Pascal语言中的指针具有类似的定义。存取类型定义的语法规范如下。
![](https://epubservercos.yuewen.com/B3251C/23020659009785406/epubprivate/OEBPS/Images/43035_44_1.jpg?sign=1739147568-xWIZ62YkAeFJBozxYEMr0abCdvEP2Q9S-0-54856f17f4cbfe483bf0b57258e54cc9)
其中,type_name是类型名;data_type是存取类型指向的数据类型。
每一个存取类型对象的初始值是null,即存取类型还未指向其他对象。存取类型的值必须由分配器来返回,通过这个返回值,存取类型就指向了另一个数据类型,也称为被指向类型。存取类型的对象必须是变量。被指向类型的对象通常也是变量。共享变量不可以被定义为存取类型。
如果被指向类型是文件类型或者包含文件类型元素的复合类型,存取类型的存取值就指向文件对象。同样地,被指向类型是保护类型或者包含保护类型元素的复合类型,存取类型的存取值会指向带有保护类型的对象。
存取类型指向的数据不必在程序的声明部分定义,也不必等到程序段结束才释放,而是需要时随时开辟,不需要时随时释放。根据程序运行时的实际需要,可以随时向系统申请部分空间。由于这些对象没有在声明部分定义,因此,不能通过对象的名称去调用这些数据,需要通过存取类型来引用。当不再需要这些对象时,可以通过预定义的过程释放这部分空间。
存取类型定义示例如下。
![](https://epubservercos.yuewen.com/B3251C/23020659009785406/epubprivate/OEBPS/Images/43035_44_2.jpg?sign=1739147568-lJWZzGaU3E9CVchnRLLqeIazoFyxdvXL-0-98e2451c7bb4b25f54ff0c443f8ae755)
存取类型的递归示例如下。
![](https://epubservercos.yuewen.com/B3251C/23020659009785406/epubprivate/OEBPS/Images/43035_44_3.jpg?sign=1739147568-J8AeLr8G4bngxg6l9rHvCFKacUoNrGuB-0-52509517c1f28dac1d8283b3af29839c)
![](https://epubservercos.yuewen.com/B3251C/23020659009785406/epubprivate/OEBPS/Images/43035_45_1.jpg?sign=1739147568-SMVv17t0jW4QAORjauMcEr7qHqBdxeyv-0-1b99696cb60f1b3d006f6987b358d29a)
两个存取类型互相依赖的示例如下。
![](https://epubservercos.yuewen.com/B3251C/23020659009785406/epubprivate/OEBPS/Images/43035_45_2.jpg?sign=1739147568-1v3uA92yBEFobDu6gY0ZsUYC5fRE0d9g-0-0097698b667e77d1c1d7cb6b6a89b827)
std库为存取类型定义了释放过程deallocate,为不需要的存取类型指向对象释放空间。其声明如下。
![](https://epubservercos.yuewen.com/B3251C/23020659009785406/epubprivate/OEBPS/Images/43035_46_1.jpg?sign=1739147568-c4ZFzM2Qvr5kzm1LpPgWpw7PWKkqE8BR-0-81fdd2b441aee78a6c62d93773dcd529)
2.2.4 文件类型
文件类型用来描述主机系统环境内文件的数据类型。文件类型对象的值是主机系统文件内容的序列。
![](https://epubservercos.yuewen.com/B3251C/23020659009785406/epubprivate/OEBPS/Images/43035_46_2.jpg?sign=1739147568-FJSAOTPi64WHR7xSkaXl88C9uPgYKLcl-0-b4f9ca1cd2a35e80bc278e9a60c83dac)
其中,type_name是类型名;type_mark是文件中数据的类型。
文件类型定义示例如下。
![](https://epubservercos.yuewen.com/B3251C/23020659009785406/epubprivate/OEBPS/Images/43035_46_3.jpg?sign=1739147568-aVenigO919VBcEjvJo2xTEuB3M4LUvFj-0-bc304dd3a8955bd949f988a393778183)
std库为文件类型定义了一些文件读写操作的函数和过程。这些函数和过程声明如下。
![](https://epubservercos.yuewen.com/B3251C/23020659009785406/epubprivate/OEBPS/Images/43035_46_4.jpg?sign=1739147568-cxFrwtAigYI0vMVh7cFJQWz9Khp7zElB-0-7dd8415356474e0f09dc619d5f8b725e)
![](https://epubservercos.yuewen.com/B3251C/23020659009785406/epubprivate/OEBPS/Images/43035_47_1.jpg?sign=1739147568-rHk6aoXA4dPOSIGSBfiNpf7s9dSrnvKj-0-0d7e48d535ca89b0a9b4909b152297fe)
2.2.5 保护类型
为了解决多个进程同时访问共享变量的问题,IEEE 1076-2002号标准正式引入了保护类型。保护类型通过将数据结构和运算操作封装到一个容器中,实现对容器内代码访问控制,提高程序操作的安全性,类似于C++中类访问修饰符。引入保护类型这个概念之后,程序中的变量、函数、过程等数据和运算操作可以设置不同的访问级别,方便程序测试和编写。
保护类型的定义包括声明和实现两个部分。在保护类型中,可以定义过程、函数、变量等数据和操作。保护类型定义示例如下。
![](https://epubservercos.yuewen.com/B3251C/23020659009785406/epubprivate/OEBPS/Images/43035_48_1.jpg?sign=1739147568-l8SDDGo0J2gh3QlRS9ZA40pQ37drnDts-0-c5836a7f64bcc0a5c22397ffc144b098)
保护类型调用示例如下。
![](https://epubservercos.yuewen.com/B3251C/23020659009785406/epubprivate/OEBPS/Images/43035_48_2.jpg?sign=1739147568-eHyUYYodhX5cpZaOElIKyiZ61ltXt8Sa-0-a5b5c41643ec19634a97aa0dd5922354)
![](https://epubservercos.yuewen.com/B3251C/23020659009785406/epubprivate/OEBPS/Images/43035_49_1.jpg?sign=1739147568-LSvXLGTlWRXLqnBJVuwnWjh6tKNDKwGT-0-0404cc8248bcfcf63ea63ce6d74328b7)
保护类型可以通过类属映射来实现新的实例,类似于C++中的基类和派生类。