VHDL语法入门 (二) 数据类型

预定的数据类型

  • 位(BIT)和位矢量(BIT_VECTOR);

        值为“0”或“1”

        例

--信号的声明
signal x : bit;      --x为一位的BIT信号
signal y : bit_vector(3 downto 0);     --y为4位的位矢量信号,最左侧是最高位(MSB)
signal w : bit_vector(0 downto 7);     --w为8位的位矢量信号,最右侧是最高位(MSB)

--信号的赋值
x<='1';
y<="0111";     --当位宽大于1时,位矢量值放在双引号中
w<="01110001";
  • std_logic和std_logic_vector

        值可以取“0”,“1”,高阻态,不定态等8种

                'X' "强"不定值(综合后为不确定值)

                '0' ”强“0(综合后为0)

                '1' ”强“1(综合后为1)

                'Z' 高阻态(综合后为三态缓冲器)

                'W' ”弱“不确定值

                'L' ”弱“0

                'H' ”弱“1

                '-' 不可能出现的情况

        std_logic8个值中,只有“0”,“1”和“Z”是可综合的

        std_logic有8个值是因为当两个或以上输出端接到同一节点时,此时节点的电平不但与输入的电平有关,还与其强弱有关

signal y : std_logic_vector(3 downto 0) := "0001";
--声明一个位宽为4的矢量,用“:=”对信号进行赋初值
  • std_ulogic和std_ulogic_vector

        有9种数据类型,'X',‘0’,‘1’,‘Z',’W','L','H','-',‘U’

        std_logic是std_ulogic的子集

        ‘U’表示初始不定值

        与std_logic不同,std_ulogic没有指定两个std_ulogic信号连接到同一节点发生冲突后的逻辑值,因此要避免两个信号直接连接

  • 布尔值(BOOLEAN)

        只有两种取值“真”或”假“

  • 整数(INTEGER)

        32位的整数(范围是-2 147 483 647到2 147 483 647)

  • 自然数(NATURAL)

        非负的整数(范围是0到2 147 483 647)

  • 实数(REAL)

        实数的取值范围-10^38到10^38,不可综合

  • 物理量字符(physical literal)

        用于表示诸如时间和电压等物理量,仿真时可用,不可综合

  • 字符(CHARACTER)

        单个或是一串ASCⅡ字符

  • 有符号数(SIGNED)和无符号数(UNSIGNED)

        从外在表面上看,与std_logic_vector相同,但是能够支持与整型变量相似的算术运算

x0 <= "101111";    --二进制数
x1 <= B"101111";    --二进制数
x2 <= O"57";    --八进制数
x3 <= X"2F";    --十六进制数
IF true THEN ...;    --布尔运算,若true为真,就执行THEN之后的语句
y <= 1.2E-5;    --实数,不可综合
q <= d after 10 ns;    --物理量,不可综合

VHDL不允许不同类型的数据之间直接进行操作运算

用户定义的数据类型

--用户定义整数
type my_integer is range -32 to 32;    --用户定义的整数子集
type my_natural is range 0 to 100;     --用户定义的自然数
--用户定义枚举类型
type my_logic is ('0','1','z');    --用户定义的std_logic
type bit_vector is array(natural range<>) of bit;    --用户定义的bit_logic数据类型
                                                     --range<>表示取值范围没有约束,natural range<>表示数据值约束在自然数范围
type state is (idle,forward,backward,stop);    --枚举数据类型,常用于有限状态机

通常枚举类型的数据会自动进行编码,除非用户进行了特别声明。例如上述state类型中,“00”表示第一个状态(idle),“01”表示第二个状态(forward),“10”表示第三个状态(backward),“11”表示第三个状态(stop)

子类型

在原有类型之上加一些约束,定义该数据类型的子类型,通过定义新的数据类型可以达到同样的目的

subtype small_integer is integer range -32 to 32;    --整数子类型
subtype my_logic is std_logic range '0' to 'Z';    --由于std_logic=('x','0','1','z','w','h','l','-'),因此my_logic=('0','1','z')

数组

数组(array)是将相同类型的数据集合在一起形成的一种新的数据类型,可以是一维(1D),也可以是二维(2D)或者1x1维(1D x 1D)的。更高维数的数组通常是不可综合的。

VHDL语法入门 (二) 数据类型_第1张图片

 事实上,可以认为VHDL仅包含标量(单个体)和矢量(一维数组)两类。这两类中可综合的如下:

标量:bit,std_logic,std_ulogic,boolean
矢量:bit_vector,std_logic_vector,std_ulogic_vector,integer,signed和unsigned

定义数据的语法结构

type type_name is array (specification) of data_type;

--建立1x1数组
--第一种方法
type row is array (7 downto 0) of std_logic;    --一维数组
type matrix is array (0 to 3) of row;    --1x1维数组
signal x : matrix;    --1x1维信号
--第二种方法
type matrix is array(0 to 3) of std_logic_vector(7 downto 0);

--建立二维数组
type matrix2d is array(0 to 3,7 downto 0) of std_logic;

--数组的初始化
... := "0001";    --对一维数组进行初始化
... := ('0','0','0','1');    --对一维数组初始化
... := (('0','1','1','1'),('1','1','1','1'));    --二维数组的初始化

端口数组

在定义电路的输入输出端口时,有时需要将端口定义为矢量阵列,由于entity中不允许使用type进行类型定义,且预定义类型的数据中没有超过一维的,所以必须在包集中根据端口的具体信号特征建立用户自定义的数据类型,该数据类型可以供包括entity在内的整个设计使用。

------包集------
LIBRARY ieee;
USE ieee.std_logic_1164.all;

PACKAGE my_data_type IS
    TYPE vector_array IS array (natural range<>) OF std_logic_vector(7 downto 0);
END my_data_type;
------主代码------
LIBRARY ieee;
USE ieee.std_logic_1164.all;
USE work.my_data_type.all;    --用户自定义的包集

ENTITY mux IS
    PORT (
        inp : IN vector_array(0 to 3);
        ...
    );
END mux;
    ...;

记录类型(record)

记录类型和数组类型相似,两者唯一的区别在于数组类型(array)只能包含相同的数据,记录类型(record0)内部可有包含不同类型的数据

type birthday if record
    day : integer ranger 1 to 31;
    month : month_name;
end birthday;

数据类型转换

在VHDL中有两种进行数据转换的方法

一是写一段专用于数据转换的代码

二是使用包集std_logic_1164中的一些数据类型转换函数

  • conv_integer(p):将数据类型为integer,unsigned,signed,std_ulogic或std_logic的操作数p转换成integer类型。注意不能转换std_logic_vector类型。
  • conv_unsigned(p,b):将数据类型为integer,unsigned,signed,std_ulogic的操作数p转换为位宽为b的unsigned类型
  • conv_signed(p,b):将数据类型为integer,unsigned,signed,std_ulogic的操作数p转换为位宽为b的signed类型
  • conv_std_logic_vector(p,b):将数据类型为integer,unsigned,signed,std_logic的操作数p转换为位宽为b的std_logic_vector类型

VHDL中可综合的数据类型

数据类型

可综合的数值

bit,bit_vector

'0','1'

std_logic,std_logic_vector

'x','0','1','z'

std_ulogic,std_ulogic_vector

'x','0','1','z'

boolean

true,false

natural

0到2147483647

integer

-2147483647到2147483647

signed

-2147483647到2147483647

unsigned

0到2147483647

用户自定义整型

integer的子集

用户自定义枚举类型

根据用户定义进行编码得到

subtype

任何预定义或用户自定义的子集

array

任意上述单一类型数据的集合

record

任意上述多种类型数据的集合

实例

下面列出一些合法和非法的赋值操作

type byte is array (7 downto 0) of std_logic;    --一维数组
type mem1 is array (0 to 3,7 downto 0) of std_logic;    --二维数组
type mem2 is array (0 to 3) of byte;    --1x1维数组
type mem3 is array (0 to 3) of std_logic_vector(0 to 7);    --1x1维数组
signal a: std_logic;    --标量信号
signal b: bit;    --标量信号
signal x: byte;    --一维信号
signal y: std_logic_vector(7 downto 0);    --一维信号
signal v: bit_vector(3 downto 0);    --一维信号
signal z: std_logic_vector(x'high downto 0);    --一维信号,这里x’high表示x信号的上界,
signal w1: mem1;    --二维信号
signal w2: mem2;    --1x1维信号
signal w3: mem3;    --1x1维信号

----------------合法的标量赋值--------------------
x(2) <= a;    --同类型(std_logic),使用正确
y(0) <= x(0);    --同类型(std_logic),使用正确
z(7) <= x(5);    --同类型(std_logic),使用正确
b <= v(3);    --同类型(bit),使用正确
w1(0,0) <= x(3);    --同类型(std_logic),使用正确
w1(2,5) <= y(7);    --同类型(std_logic),使用正确
w2(0)(0) <= x(2);    --同类型(std_logic),使用正确
w2(2)(5) <= y(7);    --同类型(std_logic),使用正确
w1(2,5) <= w2(3)(7);    --同类型(std_logic),使用正确

----------------非法的标量赋值--------------------
b <= a;    --bit和std_logic数据类型不匹配
w1(0)(2) <= x(2);    --w1的索引必须是二维的
w2(2,0) <= a;    --w2的索引必须是1x1维的

----------------合法的矢量赋值--------------------
x <= "11111110";
y <= ('1','1','1','1','1','1','0','z');
z <= "11111"&"000";
x <= (others => '1');
y <= (7 => '0', 1 => '0', others => '1');
z <= y;
y(2 downto 0) <= z(6 downto 4);
w2(0)(7 downto 0) <= "11110000";
w3(2) <= y;
z <= w3(1);
z(5 downto 0) <= w3(1)(2 to 7);
w3(1) <= "00000000";
w3(2) <= y;
z <= w3(1);
z(5 downto 0) <= w3(1)(2 to 7);
w3(1) <= "0000000";
w3(1) <= (others => '0');
w2 <= ("11111100",('0','0','0','0','z','z','z','z'),(others => '0'),(others => '0'));
w1 <= ((others => 'z'),"11110000","11110000",(others =>'0'));

----------------合法的数组赋值--------------------
x <= y;
y(5 to 7) <= z(6 downto 4);
w1 (0, 7 downto 0) <= "11111111";
w2 <= (others => 'z');
w2(0, 7 downto 0) <= "11110000";


----------------对数组进行初始化的实例--------------------
for i in 0 to 3 loop
    for j in 7 downto 0 loop
        x(j) <= '0';
        y(j) <= '0';
        z(j) <= '0';
        w1(i,j) <= '0';
        w2(i),(j) <= '0';
        w3(i)(j) <= '0';
    end loop;
end loop; 

你可能感兴趣的:(VHDL语法入门,fpga开发,嵌入式硬件,单片机,开发语言)