CH8 VHDL 结构与要素CH8.8 & CH8.9
数据类型• 标量类型( Scalar Type )
– 整数( Integer )– 实数( Real )– 枚举( Enumeration )– 时间( time )
• 复合类型( Composite Type )– 数组型( Array )– 记录型( Record )
• 存取类型 ( Access Type )• 文件类型 ( Files Type )
用户自定义的数据类型• 枚举类型( enumerated )• 整数类型( integer )• 数组类型( array )• 记录类型( record )等
Type 语句• 用户自定义的数据类型定义时用类型定于语
句 type 和子类型定义语句 subtype 实现 • Type 语句格式: Type 数据类型名 is 数据类型定义 of 基本数据类型;或 Type 数据类型名 is 数据类型定义 • Subtype 语句格式: Subtype 子类型名 is 基本数据类型 range 约束范围;
VHDL 数据类型--枚举• 列举数据对象可能存在的值,一般用于定义状态机的状态其定义格式: Type 数据类型名 is ( 元素 1 ,元素 2 ,…… );
– Type week is ( sun, mon, tue, wed, thu, fri, sat);– Type states is (start, running, pause, stop) Signal current_state , next_state: states;
• IEEE1076 标准中预定义了两个枚举类型– Type boolean is (False, True)– Type bit is (‘0’, ‘1’) Signal a : bit;
VHDL 数据类型--枚举• IEEE1164 标准中预定义了一个枚举类型
Type std_logic is(‘U’, ‘X’,‘0’, ‘1’, ‘Z’, ‘W’, ‘L’, ‘H’, ‘-’);– 该类型能比较全面地包括数字电路中信号会出现的几种状态,因此一般情况把这种类型代替 bit– 注意:这里的大小写是敏感的
VHDL 数据类型--整数• 整数类型在 VHDL 语言中已经存在,自定义一般指在原有的基础上加以限制,实际上原整数类型的子集,因此象这种方式的定义一般不能直接采用 Type ,而是采用 Subtype 。
– Subtype digits is integer range 0 to 9 • 在程序包 standard 中,已有两个预定义的子类型,即自然数类型( Natural Type )和正整数类型( Positive Type ),它们基本数据类型都
是 Integer 。
VHDL 数据类型--数组• 简单型的一维数组• 复杂型的多维数组• VHDL 仿真器支持多维数组,但综合器只支持一维数组• VHDL 允许两种不同类型数组
– 限定性数组– 非限定性数组
VHDL 数据类型--数组• 限定性数组语句格式
– Type 数组名 is array ( 数组范围 ) of 数据类型;• Eg1 : type stb is array (7 downto 0) of std_logic;• Eg2 : type x is (low, high); type data_bus is array (0 to 7, x) of bit;
• 非限定性数组语句格式– Type 数组名 is array ( 数组下标名 range <>) of 数据类型;
• Type std_logic_vector is array (Natural range<>) of std_logic; • 这里范围由“ range<>” 指定,这是一个没有范围限定的数组。在这种情况下,该范围在定义某一数据对象为 std_logic_vector时再确定。如: Signal ma: std_logic_vector( 3 downto 0 );
VHDL 数据类型--记录• 数组是同一数据类型的集合;记录则是不同类型的数据和数据名组织在一起而形成的新数据集合。 • 定义格式为:
– Type 数据类型名 is record 元素名 1 :数据类型名; 元素名 2 :数据类型名; end record;
VHDL 数据类型--记录• Type bank is record
Addr0 : std_logic_vector(3 downto 0); Addr1: std_logic_vector(2 downto 0); Ro : integer;
End record;
Signal r: bank:=(“1011”, “0010”,12);
VHDL 数据类型--记录 Type io is record Enable :bit; DataBus :bit_vector(7 downto 0); end record; singal bus : io; bus.Enable <= ‘1’; bus.DataBus <= “00110110”;
VHDL 的预定义数据类型• 布尔( boolean )数据类型
– 在程序包 standard 中定义的源代码为: Type boolean is (false, ture);
• 位( bit )数据类型– 在程序包 standard 中定义的源代码为: Type bit is (‘0’, ‘1’);
• 位矢量( bit_vector )数据类型– 在程序包 standard 中定义的源代码为:Type bit_vector is array (Natural range <>) of bit;– 使用矢量必须注明位宽,即数组中的元素个数和排列,例如:Signal a: bit_vector (7 downto 0)
VHDL 的预定义数据类型• 字符( character )类型
– VHDL 语言在 ieee.std_logic_1164 程序包体中有预定义的 128 个字符。– 字符的表示是用单引号括起来的。如‘ a’ ‘、 b’ 等。 – 在 VHDL 程序中,,标识符的大小写一般不区分,但是字符类型区分大小写。例如:
‘B’ ≠ ‘b’
VHDL 的预定义数据类型• 整数( integer )数据类型
– 包括正整数、负整数和零– 可以进行加减乘除等算术 运算– 在 VHDL 语言中,整数的表达范围为-2147483647 ~+ 2147483647 ,即 -(231-1) ~ (231-
1) ;– 尽管整数值在电子系统中是用一系列二进制位值来表示的,但整数不能看作是位矢量,也不能按位进行访问,对整数不能用逻辑操作符。
VHDL 的预定义数据类型• 实数 ( real )数据类型
– 范围: -1.0E38 ~ +1.0E38 ,– 目前对于实数, EDA 软件只能仿真,不能综合。
• 字符串( string )数据类型– VHDL 综合器支持字符串数据类型– 是用双引号括起来的一串字符,例如
• Variable dds : string (1 to 7);dds := “a b c d”
VHDL 的预定义数据类型• 时间( time )数据类型
– VHDL 中唯一的预定义物理类型– 整数和单位间至少留一个空格– Standard 程序包中定义的时间,如下:
• Type time is Range -2147483647 to 2147483647; units
fs; -- 飞秒, vhdl 中最小时间单位ps = 1000 fs; -- 皮秒ns = 1000 ps;us = 1000 ns;ms = 1000 us;sec = 1000 ms;
min = 60 sec; hour = 60 min; end units;
IEEE 预定义标准逻辑位与矢量• 标准逻辑位( std_logic )数据类型
– std_logic 具有多值性,在条件语句中,如果未考虑到 std_logic 所有可能的取值情况,有的综合器会插入不希望的锁存器。
• 标准逻辑矢量( std_logic_vector )数据类型– std_logic_vector 就是由多个 std_logic 组合在一起的数组。 – 在程序包中定义如下: Type std_logic_vector is array (Natural range<>) of
std_logic
其他预定义标准数据类型• IEEE 库中程序包 std_logic_arith 中定义了如下的数据类型:
– 无符号型( unsigned )– 有符号型( signed )– 小整型( small_int )
• Library ieee; use ieee.std_logic_arith.all• Numeric_std 和 numeric_bit 程序包
无符号数据类型( unsigned type )
• 在综合器中,被解释为一个二进制数,此二进制数的最左位为最高位。– 十进制的“ 8” 表示为: unsigned (“1000”) – Variable var : unsigned ( 0 to 10 ); var 所表达的范围为“ 0 ~ 2047”, 最高位为
var(0) ;– signal sig: unsigned ( 5 downto 0) sig 所表达的范围为“ 63 ~ 0” , 最高位为 sig(5)
• 不能用 unsigned 定义负数
有符号数据类型( signed type )
• signed 数据类型表达一个有符号的数值• 综合器将其解释为补码 • 数的最高位为符号位 ,例如:
– signed (“0101”) 代表 +5 , 5 – signed (“1011”) 代表 -5 – variable x : signed (0 to 10); 变量 x 有 11 位,最左边的一位 x ( 0 )是符号位,如为‘ 0’ 表示正数,‘ 1’ 为补码表示的负数
数据类型转换• 在 VHDL 语言中 , 不同数据类型之间是不能进行运算和赋值的。为了实现正确的操作就需要进行数据类型转换。• 自定义转换函数:利用类型转换函数来进行类型的转换需要定义一个函数,使其参数类型转换为被转换的类型,返回值为转换后的类型。• VHDL 中预定义了几种类型转换函数
基本类型转换函数表 函数名 功能
(1) std_logic_1164 程序包 to_stdlogicvector(a) to_bitvector(a) to_stdlogic(a) to_bit(a)
由 bit_vector转换为 std_logic_vector由 std_logic_vector转换为 bit_vector由 bit转换为 std_logic由 std_logic转换为 bit
(2) std_logic_arith 程序包 conv_std_logic_vector (a ,位长 )
conv_integer(a)
由 integer , unsigned , signed转换成 std_logic_vector 由 unsigned , signed转换为 integer
(3) std_logic_unsigned 程序包 conv_integer (a) 由 std_logic_vector转换为 integer
library IEEE;use IEEE.std_logic_1164.all;use IEEE.std_logic_arith.all;use IEEE.std_logic_ unsigned.all;entity ty is port ( a: in std_logic_vector (2 downto 0); b: in bit_vector (2 downto 0); c: out std_logic_vector (2 downto 0); e, d: out std_logic_vector (2 downto 0) );end ty;
Architecture ty_arch of ty is signal e: bit_vector(7 downto 0); signal f: std_logic_vector (7 downto 0);begin c<=a+to_stdlogicvector(b);e<=conv_std_logic_vector(conv_integer(a),3); end ty_arch;
to_stdlogicvector(a) conv_std_logic_vector (a ,位长 )
conv_integer(a)
由 bit_vector转换为 std_logic_vector由 integer , unsigned , signed转换成 std_logic_vector 由 std_logic_vector转换为 integer
VHDL 操作符• 在 VHDL 语言中主要有 5 种操作符• 逻辑操作符( logical operator )• 关系操作符( relational operator )• 算术操作符( Arithmetic operator )• 符号操作符( sign operator )• 重载操作符( overloading operator )
VHDL 操作符• 对于 VHDL 中的操作符与操作数间的运算有两点需要特别注意:
– 严格遵循在基本操作符间操作数的数据类型必须相同的规则;– 严格遵循操作数的数据类型必须与操作符所要求的数据类型完全一致的原则。
• 此外,注意操作符之间具有优先级别
逻辑操作符 • VHDL 语言中的逻辑运算符共有 7 种,分别是; NOT --取反;
AND --与; OR --或;
NAND --与非;NOR --或非;XOR --异或;
XNOR --同或; • 所要求操作数基本类型为:
bit 、 boolean 、 std_logic
逻辑操作符 在 VHDL 语言中,如果有多个操作符,它们之间没有左右差别,因此必须带括号。没有括号,则会产生语法错误。如果在一串运算中的运算符是 AND , OR , XOR三个的一种且运算符相同则括号可以省略。
例如: X<=(a and b)or(not c and d); —— 括号不能省略 Y<=a or b or c; —— 括号可以省略
Z<=(m nand t ) nand p; —— 括号不能省略
关系操作符• 是将相同数据类型的数据对象进行数值比较或关系排序判断,并将结果以布尔类型的数据表示出来,即
ture 或 false ;• VHDL提供 6 种关系运算操作符: = 、 /= 、 < 、 > 、
<= 、 >= ;• “=” 和“ /=” 可以适用所有类型的数据;• 其它关系运算符则可使用
integer 、 std_logic 、 std_logic_vector 、 bit 、 bit_vector 等。
• 关系运算符左右数据类型应相同,宽度也应相同。如宽度不同只能按自左至右的比较结果作为运算的结果。
关系操作符Eg : signal a: std_logic_vector(3 downto 0); signal b: std_logic_vector(2 downto 0);
signal c : std_logic_vector(3 downto 0); a<=“1010” ;
b<=“111” ;if (a>b) then c<=a;else c<=b;end if;运行结果是 c得到了 b 的值
关系操作符• 为了能使位矢量进行正确关系运算,在程序包“ std_logic_unsigned” 中对“ std_logic_vector”关系运算重新作了定义,使其可以正确进行关系运算。
– Unsigned “1010”> Unsigned “111”• 就综合而言,简单比较运算( = 、 /= )在实现硬件结构时,比排序操作符构成的电路芯片资源利用率要高。
算术操作符• 求和操作符
+ ------- 加 ; - ------- 减 ; & ------- 并置。– 加法、减法一般只能对 integer 类型进行运算,
非 integer 类型数据需用到运算符重载。
算术操作符• 求积操作符 * ------- 乘 ; / ------- 除 ; MOD ------- 求模 ; REM ------- 求余 ;
– 在 Max+plusⅡ 中两个信号的乘法运算是可以综合的。除法则对除数有一定的要求,除数和被除数应为整型数。从综合优化和节省芯片资源的角度出发,最好是利用综合软件所提供的乘法和除法模块。
算术操作符– Mod 和 rem 的第一操作数和第二操作数的类型只能是整数类型, Mod 和 rem 以及除法操作符不同的综合器支持的程度有很大的区别, Max+plusⅡ 对 Mod 和 rem 的运算不支持,对除法仅部分支持 。
• 符号操作符– 操作数只有一个,为整数类型。– 正号“ +” 对数据对象不作任何改变。– 负号“ -” 是对数据对象取负,其实质是求补运算。
算术操作符• 混合操作符 ** ------- 乘方(指数) ; ABS ------- 取绝对值 ;
– 操作数一般为整数类型;– 乘方运算左边可以为整数或浮点数,右边必须为整数,只有左边为浮点数时,右边才可以为负数。– Max + plus II 不支持混合操作符
算术操作符• 移位操作符
– 移位操作符有 6 种: SLL 、 SRL 、 SRA 、 SLA 、 ROL 和ROR 。
– 在 VHDL 中要操作的数据对象是一维数组且数据类型为 bit 或 boolean 类型。其它如std_logic 、 integer 等类型使用移位操作运算时需使用数据类型转换函数,将其它类型转换为 bit 类型。也可以编写重载函数以支持其它数据类型的移位操作。
SLL :逻辑左移,右边补零。SRL :逻辑右移,左边补零。ROL 、 ROR :循环左、右移;移出的位用于依次填补移空的位。SLA 、 SRA :算术移位操作符;其移空位用最初的首位来填补。 移位操作语句格式是: 数据对象 移位操作符 ,移位位数(整数);
Variable Ma : bit_vector(3 downto 0) :=“1011”
Ma SLL 1; - -( ma=“0110” )
Ma SLL -3 ; - -( ma=“0001” )
Ma SRL 1 ; - -( ma=“0101” )
Ma SRL -2 ; - -( ma=“1100” )
Ma SLA 1 ; - -( ma=“0111” )
Ma SLA -3 ; - -( ma=“1111” )
Ma ROL 1 ; - -( ma=“0111” )
Ma ROR -3 ; -- ( ma=“1101” )