VHDL程序结构
VHDL五大元素
-Entity
*Block的I/O port规格
-Architecture
*Block的内部电路
*可同时具有多个
-Configuration
*决定哪一个architecture被使用
-Package
-Lib
第一要素实体:
实体描述了模块的内部接口和外部接口的相关参数
在VHDL中实体描述的结构:
entity 实体名称 is
port (端口名称:端口模式 数据类型;
端口名称:端口模式 数据类型;
端口名称:端口模式 数据类型);
end 实体名称
1.端口名称
一般一个模块的实体包含不止一个端口,为了区别不同的端口,会将端口的含义包含在名称中。
端口模式:
in 输入,只能被读取,不能被赋值
out 输出,只能被赋值,不能被读取
inout 双向,可以被读取也可以被赋值,被读取时的值是从端口输入的值
buffer 缓冲输出,类似于out,但是值可以被读取,读取的值就是被赋的值
linkage 不指定方向
inout端口是双向端口,既可以做内部信号的输出端口,也可以做外部信号的输入端口,但是输入和输出是分复服
用的,输入的信号值是外部信号的驱动的值,而不是内部输出时驱动的值。
buffer是缓冲输出接口,使用buffer输出的信号在实体内部仍可以对其他信号进行赋值
基本数据类型:
bit
bit_vector(0 to 7)
Std_logic
Std_logic_vector(15 to 0)
bit只有0和1两种取值
Std_logic:有多种取值
'U'——初始值'
‘X’--不定
‘0’--0
‘1’--1
‘Z’--高阻
‘W’--弱信号不定
‘L’--弱信号0
‘H’--弱信号1
‘-’--不可能的情况
构造体:
通常用构造体对实体的内部实现做更加详细的描述。构造体是一个从属单元,不能独立于模块中,必须与实体声
明联合使用。而一个实体声明可以有多个构造体。
architecture 构造体名称 of 实体名称 is
{声明语句;}
begin
{并发语句}
end 构造体名称
构造体在描述模块的内部实现时通常有三种方式,行为描述,数据流描述和结构描述。
(1)行为描述是抽象层最高的描述。主要使用电路的行为特性来描述设计。在VHDL中通常用Process的方式进行
行为描述。
(2)数据流的描述方式主要使用VHDL语言的标准布尔函数,将信号之间的布尔代数关系用布尔方程式来表示。
(3)结构描述主要通过下层模块的声明和调用即端口映射将下层模块相连,构成电路的结构性描述。
声明语句:
声明语句在构造体的关键字“begin”之前,可用于下列描述语句:
“use”语句
子程序(subprogram)声明
子程序体(subprogram body)
类型(type)声明
子类型(subtype)声明
常量(constant)声明
信号(signal)声明
元件(component)声明
并发(concurrent)语句
并发语句:
构造体中的每一个并发语句都定义了一个运算单元,这个单元包括三个部分:
读取信号的值
用读取的信号的值进行运算
将运算的结果赋值给另外一个信号。
构造体中的所有并发语句都是同时执行的,与语句的书写顺序没有任何关系。并发语句有五种类型:
块(block)语句
元件(component)例化
过程(Procedure)调用
进程(process)
信号(signal)赋值
3.配置
一个实体声明可以有多个构造体,但这个实体被上层模块调用,并在最终形成电路时,只能使用一种结构体作为
实体功能实现的描述。这时就需要用配置结构经将实体与对应的结构体连接起来。
configuration 配置名称 of 实体名称 is
配置语句;
end 配置名称
Configuration cfg_nand2 of NAND2 is
for RTL
end for;
End cfg_nand2;
4.Package
package的作用就是程序包首的说明可收集多个VHDL设计所需的公共信息
包集合用于存储在工程设计中需要反复用到的常量定义、数据类型定义、子类型定义等
5.库
VHDL设计元素经过编译后,包含在库中,库和包集合构成了工程数据的管理结构
-标准库(IEEE)
-STD库:VHDL标准库,有标准的STANDARD包集合
-ASIC库:芯片厂商提供
-WORK库,类似于文件夹,所有单元都在词库中
-用户自定义库:用户自行开发
VHDL语言的对象和数据类型
1.VHDL语言的数据类型
VHDL对类型的要求很严格,所有的端口、常量、变量和信号在声明时都要显式的定义其对应的数据类型。不同类
型之间不能赋值,数据类型相同,而位长不同时也不能带入。
VHDL中定义了很多种数据类型:
标量类型(Scalar Type)
复合类型(Composite Type)
存取类型(Access Type)
文件类型(Files Type)
用户定义的子类型(Sub Type)
标量类型是VHDL中最基本的类型,用于描述一个单值数据对象。属于标量类型的数据有以下几种:
位型(BIT)
布尔型(BOOLEAN)
整型(INTEGER)
实型(REAL)
物理型
符号型(CHARACTER)
标准逻辑类型(STD_LOGIC)
枚举类型(ENUMERATE)
错误等级(SEVERITY_LEVEL)
(1)位
BIT型是数字逻辑中最基本的逻辑形式,BIT型在STD库中有明确的定义,其定义如下:
type BIT is('0','1');
从上面的定义可以看出,BIT类型的数据只能去两个值。
(2)布尔
BOOLEAN型相对于BIT型的抽象层次更高,BOOLEAN型的定义如下:
type BOOLEAN is(FALSE,TRUE)
(3)INTEGER
通常INTEGER在定义时,都要用"range"语句给出数据的取值范围,数据在后续使用过程中不能超出此范
围。"range"定义必须在-(2^31-1)--(2^31-1)
(4)实型(REAL)
VHDL语言中,实型REAL也叫浮点型。
(5)物理型
物理型数据用于表示一些物理量,如重量、长度、时间、或电压值等等,用户可以根据工程需要定义一些物理数
据类型。完整的物理类型数据包含数值和单位两部分,在定义一个物理类型的数据时,必须先给出一个基准单位,
其他的单位也必须是基准单位的倍数。VHDL中只定义了一个物理类型TIME。
(6)符号型(CHARACTER)
符号型数据量通常用单引号括起来。VHDL对大小写不敏感,但是字符中的大小写字符被认为是不一样的。
(7)标准逻辑类型(Std_Logic)
STD_LOGIC也是单个数字信号逻辑的
(8)枚举类型
在VHDL中,也支持类似于其他编程语言中常用的枚举类型。
枚举类型的描述结构为
type 类型名称 is(元素,元素...);
(9)错误等级
错误等级用于表征系统的运行状态,有四种状态可用:NOTE(注意),WARNING(警告),ERROR(错误)和
FAILURE(失败)
复合类型
复合型的数据是指由多个单值数据组合起来的一组为数据,复合型数据是以向量、数组或记录的形式存在
属于复合类型的数据有以下几种:
位矢量型(BIT_VECTOR)
标准逻辑矢量型(STD_LOGIC_VECTOR)
字符串型(STRING)
数组型(ARRAY)
记录型(RECORD)
(1)位矢量型
位矢量型是由多个位型数据组合起来的一组数据。
(2)标准逻辑矢量型(STD_LOGIC_VECTOR)
标准逻辑矢量型是由多个标准逻辑数据组合起来的。
(3)字符串型(STRING)
字符串类型是由多个类型的字符类数据组合起来的。
(4)数组型(ARRAY)
数组型是由多个相同类型的数据组成的集合,组成集合的数据类型可以是任意的。
一个数组可以对另外一个数组进行赋值,但是互相赋值的两个数组必须是相同类型的,而且数组的长度必须相同。
数组之间在赋值时,是用对应位置的值进行赋值的。
数组也可再用一种便捷的方式进行赋值,即联合赋值。联合赋值不仅在数组中可以使用,多个标量对象在赋值时
也可以采用这种形式。使用联合赋值时,出现在赋值符号左侧的联合体只能由标量类型组成。
(5)记录型(RECORD)
与数组型类似,记录型也是有多个数据组成的集合,但组成的集合的数据至少有两种以上不同的类型。
RECORD类型数据定义结构为:
type 记录名称 is
record
元素名称:数据类型名称
。。。
end record
文件类型
VHDL中的文件类型是由某种类型的数据组成的数据流,可以在仿真中读入和写出。
一个文件类型的实例如下:
type TEXT is file of STRING;
file MY_INFILE:TEXT is in "myinfile.txt";
file MY_OUTFILE:TEXT is out "myoutfile.dat"
用户定义的子类型:
用户可以根据工程设计的需要,修改已定义数据类型的方位限定,形成新的数据类型。这种类型称为子类型
(subtype)。子类型定义结构如下:
subtype 子类型名称 is 已定义类型名称;
例如:
subtype MY_INT is INTEGER range 0 to 255;
2.VHDL语言的对象类型:
在VHDL中,可以被赋值的对象都被称为对象(Object),对象有很多种,常用的端口有(Port)、常量(Constant)、
信号(Signal)、变量(Variable)
端口(Port):
端口定义了实体的信号传递接口,在端口的定义中,数据类型是不可缺少的一部分。
常用的端口类型有输入in输出out双向inout缓冲输出buffer四种,其中input、inout,buffer端口可以对其他对
象赋值,outPut,inOUT和buffer可以被其他对象赋值。
常量:
常量是一个固定的值。常量在被创建时就被赋值为一个固定的值,并且常量的值在使用过程中只能对其他对象赋
值,不能被修改。
常量可以在结构体、包集合、实体、快语句、过程语句和子函数中声明,在结构体中声明的常量是本地常量,只
能在结构体中使用。
常量声明的结构为:constant 常量名称:数据类型:=常量表达式
变量
变量是用于存储信息的一种对象。变量在被创建时也可以赋初始值,但与常量相反,变量在使用过程中既可以对
其他对象进行赋值,也可以被修改。
变量是一个局部量,不能在结构体中声明,而只能在进程语句(Process)、函数语句(Function)和过程
(Procedure)语句中声明。
变量声明的结构为:
variable 变量名称:数据类型[:=初始值表达式]
变量用":="符号进行赋值操作,例如:
V:="0111"
信号(Signal)
信号是电路底层硬件单元连接的抽象。在VHDL中,信号可以用于在结构体的不同并发语句之间进行消息传递,也
可以通过端口与其他实体传递消息。从某种意义上讲,端口也是信号的一种,但是被限定了输入/输出特性,因此
也可以通过创建端口来创建一个信号,而端口的赋值方式也与信号相同。
信号可以在实体(Entity)、结构体(Architecture)和块语句(Block)中声明,不能在进程(Process)语句
,函数(function)语句和过程(Procedure)语句中声明,但可以在进程(Process)、函数(Function)和过
程(Procedure)中私用。
变量和信号的区别:
(1)声明和使用的位置不同
变量只能在进程语句(Process)、函数(Function语句,过程(Procedure)语句中进行声明,也只能在这些语
句内部使用,因此是一个局部对象。
信号可以在实体(Entity)、结构体(Architecture)和块语句(Block)中声明,在在进程语句(Process)、
函数(Function语句,过程(Procedure)语句中使用,因此可以在不同的进程之间传递消息,是一个全局对象
(2)赋值符号与延迟不同
变量用":="赋值,信号用"<="赋值。
变量被赋值时,可以被看作是右侧表达式的代名词,在使用变量是,可以用其所带的表达式替代。如果赋值的过
程被分为获取数据值、数值计算、用计算结果进行赋值这三个步骤,那么变量在赋值的过程中,第三部"用计算的
结果进行赋值"这个操作时即时的。而信号是物理单元的抽象,因此第三个步骤是有时延的。
VHDL操作运算符:
1.逻辑运算符
2.关系运算符
3.移位运算符
sla 算术向左移位时,填入的位值为最后一个位值;算术向右移位时,填入的位值为第一个位值;逻辑向左和逻
辑向右移位时,默认新填入的值都为0;向左旋转时,填入的位值为第一个位值;向右旋转时,填入的位值为最后
一个位值。
4.算术运算符
5.并置运算符
并置运算符"&"用于标量和复合类型数据的并置连接,使用并置运算符可以很灵活地将标量或数组组织在一起,形
成更大的数组。
VHDL语言的描述语句
2.顺序语句
赋值语句
IF语句
CASE语句
LOOP语句
EXIT语句
NEXT语句
WAIT
NULL
ASSERT
VHDL中的断言语句类似于C语言中的断言语句,它是人机会话的一种手段。使用断言语句可以检测某一特定的条件
是否满足,如果不满足,可以给出相应的报告,它的语法结构为:
assert条件表达式(report 字符串信息)[severity 级别]