VHDL硬件描述语言是一种用于电路设计的硬件语言。出现在在80年代的后期,最初是由美国国防部开发出来供美军用来提高设计的可靠性和缩减开发周期的一种设计语言 。VHDL主要用于描述数字系统的结构,行为,功能和接口。
VHDL语言是用来设计FPGA/PLD硬件的。VHDL语言是基于行为描述的。更加重要的是VHDL语言设计是于硬件电路无关的,它能在任意厂家的FPGA芯片上进行设计。
通常一个完整的VHDL语言包含五个部分,分别是:库,程序包,实体,结构体,配置文件。
实体(ENTITY)
实体的作用是给出实际电路的外部视图(引脚的数目,引脚的作用等),它描述了电路的封装结构。一般一个实体的结构大致如下所示:
ENTITY 实体名 IS
PORT(端口名1:端口输入输出方向 端口数据类型;
端口名2:端口输入输出方向 端口数据类型;
端口名3:端口输入输出方向 端口数据类型;
......
端口名n:端口输入输出方向 端口数据类型);
END 实体名;
多个输入输出方向相同以及数据类型相同的端口可以放在同一行进行描述。注意最后一行的端口描述结束没有分号。VHDL语言并不区分大小写,但是习惯是将关键字写作大写,用户定义的使用小写。
端口(PORT)
在VHDL语言里的端口指的就是电路引脚,而非普通软件程序设计语言意义上的进程所拥有的端口。例如:一个2输入与门两个输入引脚,一个输出引脚就是端口。端口语句正如上面实体上定义的一样。
PROT(端口名称:端口输入输出方向 端口数据类型;);
在VHDL语言中,端口输入输出方向有4中,分别是IN,OUT,INOUT,BUFFER。
IN表示端口是用来输入的;
OUT表示端口是用来输出的;
INOUT表示端口是一个双向口;
BUFFER表示端口是一个准双向口。
一个文件只能有一个实体,并且部分编程环境要求文件名与实体名相同。
下面用一个例子来实际体验一下实体。
LIBRARY IEEE; --在VHDL语言中使用"--"开始一行注释,这一行打开IEEE库
USE IEEE.STD_LOGIC_1164.ALL; --调用1164程序包
ENTITY and2 IS
PORT(in1,in2:IN STD_LOGIC; --定义两个标准逻辑类型的输入端口
out1:OUT STD_LOGIC); --定义一个标准逻辑类型的输出端口
END and2;
结构体(ARCHITECTURE)
结构体的作用是具体描述一个实体的行为(描述实体所描述的电路的功能),元件以及元件内部的连接关系。一般一个结构体的形式如下:
ARCHITECTURE 结构体名 OF 实体名 IS
BEGIN
功能描述语句;
END 结构体名;
下面用结构体来描述上面的2输入与门电路。
ARCHITECTURE behavior_and2 OF and2 IS --表示该结构体是描述名为and2的实体的功能
BEGIN
out1 <= in1 AND in2; --in1与上in2的结果赋值给out1.
END behavior_and2;
结构体和实体,前者用来描述电路的行为(或者说是功能),后者用来描述电路的结构。一个具有实际意义的VHDL程序至少需要结构体和实体才能组成。
库(LIBRARY)
VHDL语言的库和普通的软件程序设计语言的库并没有什么大的区别。一个库的用法正如上面在实体中展示的那样。
LIBRARY 库名;
这样就能在你的VHDL程序中打开这个库了。在VHDL语言中,常用的库主要是IEEE,WORK以及STD这三种库。其中STD是VHDL语言自带的库,默认是打开的。WORK是用户库,让用户自定义自己的库。WORK库也是默认打开的。我们在使用的时候只需要打开IEEE库即可。例如:
LIBRARY IEEE
程序包(PACKAGE)
通常在我们的VHDL程序中,需要调用的程序包大多数是IEEE库的。一般我们在调用程序包的时候有下面两种形式:
USE 库名.程序包名.项目名;
USE 库名.程序包名.ALL;
这是我们在调用系统或者厂商提供给我们的程序包的方式。硬件开发者本身也是可以定义自己的程序包的。一个程序包可以分为两个部分,程序包首+程序包体,一般定义格式如下:
PACKAGE 程序包名 IS --程序包首
程序包首说明部分;
END 程序包名;
PACKAGE BODY 程序包名 IS --程序包体
程序包体说明部分;
END 程序包名;
在程序包首可以定义用户自定义的数据类型,元件,常量,信号,端口,函数等;程序包体内定义程序包首说明的过程体以及函数体。如果程序包首没有过程和函数,那么可以不定义程序包体。
配置(CONFIGURATION)
配置并不是一个VHDL程序必须的部分,配置语句主要用于给实体从多个结构体中选择一个去描述实体。一般的配置语句格式如下:
CONFIGURATION 配置名 OF 实体名 IS
配置说明;
END 配置名;
例如假设我对上面名为and2的电路还有另外一个结构体,现在我需要使用它来描述and2的行为,那么可以使用如下语句
CONFIGURATION cnf OF and2 IS
for behavior_and2_1 --表示使用名为behavior_and2_1的结构体来描述and2实体的行为
end behavior_and2_1;
END cnf;