自定义数据类型
VHDL 允许用户自行定义类型;
自定义类型的元素实际上全部来自预定义类型;
用户定义类型必须在使用以前进行类型说明;
(在结构体、函数、过程、进程的说明部分进行说明)
最常用的用户定义类型形式为:
子类型 枚举型 数组型
子类型:从已有类型中取连续子集合加以定义
子类型说明语句 p.272 表 4-31
subtype subetype-name is type-name range start to end;
subtype subetype-name is type-name range start downto end;
例:
subtype twoval_logic is std_logic range `0` to `1` ;
subtype bitnum is integer range 31 downto 0 ;
子类型是从已定义的类型中取出一部分加以定义;
子类型一定是原类型的一个连续子集,但可以按顺序或反序
定义 ; to 和 downto 表达了顺序和大小排列关系;
采用子类型可以缩小数据范围(表达所需位数),提高综合效
率;
预定义的子类型
subtype natural is integer range 0 to highest-integer ;
subtype positive is integer range 1 to highest-integer ;
枚举型:
从已有类型中取离散子集合加以定义:列举全部元素
枚举型类型说明语句 p.272 表 4-31
type type-name is ( value list) ;
在括号中按顺序列举该类型中的全部元素;
列举的顺序可用于关系比较:从左到右---从小到大
在予定义类型中,boolean 、 bit 、 severity_level 都属于枚
举类型;
例 数字电路设计中最重要的类型:
type std_logic is ( `U`, `X`, `0`, `1`, `Z`,
`W`, `L`, `H`, `-`);
含义:`U` 未初始化 `X` 强未知 `0` 强 0 `1` 强 1
`Z` 高阻 `W` 弱未知 `L` 弱 0 `H` 弱 1
`-` 无关
未知状态:信号初始状态/ 出现总线冲突时的值
std_logic,std_logic_vector 类型在 ieee.std_logic_1164 包集合
中定义,使用时必须先行说明;
此类型的作用主要体现在仿真过程中,从综合的观点来看,
目前在数字器件中能够实现的只有`0`, `1`, `Z`,`-` 四种值;
在编写程序时,采用引号的字符必须区分大小写;
std_logic 的与 运算表:p.278 表 4-37
U X 0 1 Z W L H -
U U
X U X
0 0 0 0
1 U X O 1
Z U X 0 X X
W U X 0 X X X
L 0 0 0 0 0 0 0
H U X 0 1 X X 0 1
- U X 0 X X X 0 X X
std_logic 的非 运算表:
U X 0 1 Z W L H -
U X 1 0 X X 1 0 X
数组型类型说明语句 p.274 表 4-33
type type-name is array (start to end) of element-type;
type type-name is array (start downto end) of element-type;
数组:同类型元素的有序排布(从左向右),每一元素与一个
数组指标对应,数组指标通常为整数;
例: p.275 表 4-34
type monthly_count is array (1 to 12) of integer;
type byte is array (7 downto 0) of std_logic;
constant word_len: integer := 32;
type word is array (word_len-1 downto 0)of std_logic;
constant num_regs: integer := 8;
type reg_file is array (1 to num_regs)of word;
数组下标也可以采用枚举类型的元素来表达:
type traffic_light_state is (reset, stop, wait, go);
type statecount is array (traffic_light_state) of integer;
数组类型定义的要点
必须先进行元素类型的定义(或说明),才能进行数组型
定义;
数组定义中通过范围指定数组的大小、数组指标的开始
值和结束值,指标的排列可以从小到大,也可以从大到小;
数组指标不是整数类型的时候,必须先加类型说明,并从该
类型中连续取值;
数组指标的起点和终点可以采用表达式,这样可以增加
数组应用的灵活性;
数组范围也可以不限定,例如:
type std_logic_vector is array ( natural range <> ) of std_logic;
在此,范围由信号说明语句等确定。
数组元素的赋值方式
可以整体赋值,也可以各位单独赋值;
单字符赋值采用单引号,字符串赋值采用双引号;
例如:
type byte is array (7 downto 0) of std_logic;
signal b :byte;
b<="10111110";
b(7)<=`1`; b(6 downto 4)<="011";
b(0 to 3)<="0111";
b<= ( 6=>`0`,0=>`0`,others=>`1`);
通常一维数组用于描述总线信号(多位信号);
若数组的元素也是数组,则构成多维数组;多维数组没
有物理对应,不能生成逻辑电路,只能用于抽象模型。
在预定义类型中,bit_vector 和 string 属于数组类型;
bit_vector bit 元素构成的数组
如:“11010010”
string caracter 元素构成的数组
如:“after you"
最常用数组为 std_logic_vector,由 std_logic 元素构成
如:“01xx0110”
数组的连接运算
连接运算符号“& ”只用于数组类型;
数组可以通过连接运算进行扩展或改变;
例 : `0`&`1`&"1z" 成为 "011z"
B(6 downto 0)&B(7) 循环右移一位
类型的转换
类型转换主要是由于运算的需要;
例如 std_logic 类型和 bit 类型通常不能进行算术运算;
整数不能进行逻辑运算;
个别非常关联的类型可以通过赋值进行直接转换;
子类型与基本类型之间可以直接赋值,不需要进行类型
转换;
一般的类型转换通常由专门的函数进行,这些函数存放
在特定的包集合中;
常用的类型转换函数如下 :
包集合:ieee.std_logic_1164
bit→std_logic : to_stdlogic( a)
std_logic→bit : to_bit (a)
bit_vector→std_logic_vector : to_stdlogicvector( a)
std_logic_vector→bit_vector : to_bitvector (a)
包集合:ieee.std_logic_unsigned
std_logic→integer : conv_integer (a)
包集合:ieee.std_logic_arith
integer→std_logic : conv_std_logic_vector( a, l )
注:a 为待转换量,l 为转换后数组的位长度;
赋值时对数组类型的限定
在进行赋值或代入时,若右端数据类型难以判断,可以
在数据前加上“类型名' ”进行限定。
例 a0<=std_logic_vector' (“01101010”);