VHDL语言基础
Posted uhanhi
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了VHDL语言基础相关的知识,希望对你有一定的参考价值。
目录:
2.3.3.2 RTL(寄存器传输级)描述, 又称数据流描述
3.3 数据类型
3.3.1 标准定义的数据类型
3.3.2 IEEE预定义的标准逻辑位与矢量
3.3.3 用户自定义的数据类型
3.4 运算符
3.4.1 算术运算符
3.4.2 关系运算符
3.4.3 逻辑运算符
3.4.4 赋值运算符
3.4.5 关联运算符
3.4.6 其他运算符
3.4.7 运算符优先级
3.4.8 运算符表格速览
4 VHDL语句
4.1 并行语句
4.1.1 并行语句的特点
4.1.2 并行语句的格式
4.1.3 并行语句的种类
4.1.3.1 并行信号赋值语句
4.1.3.2 条件信号赋值语句
4.1.3.3
4.2 顺序语句
正文:
1 VHDL简介
VHDL的全称为VHSIC硬件描述语言(VHSIC Hardware Description Language),VHSIC: Very High Speed Integrated Circuit
1.1 历史
1980 – 美国国防部设立一个基金,在VHSIC项目之下开设了一个子课题,研究标准的硬件描述语言,1982诞生VHDL。
1987 – IEEE 将其修正为 IEEE 标准:1076
1993 – 修正了VHDL语言,升级至IEEE 1076-1993
1.2 产生原因
为什么使用VHDL ?原理图图形化设计缺点?
答:
大型设计,原理图连接太复杂,检查错误太困难
通过使用高级语言对你的设计做描述,可以分析语法错误,综合后效率可能更高,时间成本更好。
2 VHDL的基本结构
VHDL的基本设计单元结构:程序包说明、实体说明、结构体说明三部分。
-- 库、程序包的说明调用 Library IEEE; use IEEE.Std_Logic_1164.ALL; -- 实体声明 Entity FreDevider is port ( Clock: IN Std_logic; Clkout: OUT Std_logic ); END; -- 结构体定义 Architecture Behavior Of FreDevider is signal Clk:Std_Logic; -- 中间临时变量 begin process(Clock) begin IF rising_edge(Clock) THEN Clk <= NOT Clk; END IF; END process; Clkout <= Clk; END
2.1 库和程序包
2.1.1 库
库是专门用于存放预先编译好的程序包的地方,对应一个文件目录,程序包的文件就放在此目录中,其功能相当于共享资源的仓库,所有已完成的设计资源只有存入某个“库”内才可以被其他实体共享。库的说明总是放在设计单元的最前面,表示该库资源对以下的设计单元开放。库语句格式如下:
常用的库有IEEE库、STD库和WORK库:
- IEEE库:是VHDL设计中最常用的资源库,包含IEEE标准的STD_LOGIC_1164、NUMERIC_BIT、NUMERIC_STD以及其他一些支持工业标准的程序包。其中最重要和最常用的是STD_LOGIC_1164程序包,大部分程序都是以此程序包中设定的标准为设计基础。
- STD库:是VHDL的标准库,VHDL在编译过程中会自动调用这个库,所以使用时不需要用语句另外说明。
- WORK库:是用户在进行VHDL设计时的现行工作库,用户的设计成果将自动保存在这个库中,是用户自己的仓库,同STD库一样,使用该库不需要任何说明。
库的作用范围:
库说明语句的作用范围从一个实体说明开始到它所属的构造体、配置为止。当一个源程序中出现两个以上的实体时,两条作为使用库的说明语句应在每个实体说明语句前重复书写。
2.1.2 程序包
程序包是用VHDL语言编写的一段程序,可以供其他设计单元调用和共享,相当于公用的“工具箱”,各种数据类型、子程序等一旦放入了程序包,就成为共享的“工具”,类似于C语言的头文件,使用它可以减少代码的输入量,使程序结构清晰。在一个设计中,实体部分所定义的数据类型、常量和子程序可以在相应的结构体中使用,但在一个实体的声明部分和结构体部分中定义的数据类型、常量及子程序却不能被其他设计单元使用。因此,程序包的作用是可以使一组数据类型、常量和子程序能够被多个设计单元使用。
程序包分为包头和包体两部分。包头(也称程序包说明)是对包中使用的数据类型、元件、函数和子程序进行定义,其形式与实体定义类似。包体规定了程序包的实际功能,存放函数和过程的程序体,而且还允许建立内部的子程序、内部变量和数据类型。包头、包体均以关键字PACKAGE开头。程序包格式如下:
- 1.STD_LOGIC_1164程序包
STD_LOGIC_1164程序包定义了一些数据类型、子类型和函数。数据类型包括:STD_ULOGIC、STD_ULOGIC _VECTOR、STD_LOGIC和STD_LOGIC _VECTOR,用的最多最广的是STD_LOGIC和STD_LOGIC_VECTOR数据类型。调用STD_LOGIC_1164程序包中的项目需要使用以下语句:
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
该程序包预先在IEEE库中编译,是IEEE库中最常用的标准程序包,其数据类型能够满足工业标准,非常适合CPLD(或FPGA)器件的多值逻辑设计结构。 - 2.STD_LOGIC_ARITH程序包
该程序包是美国Synopsys公司的程序包,预先编译在IEEE库中。主要是在STD_LOGIC_1164程序包的基础上扩展了UNSIGNED(无符号)、SIGNED(符号)和SMALL_INT(短整型)三个数据类型,并定义了相关的算术运算符和转换函数。 - 3.STD_LOGIC_SIGNED程序包
该程序包预先编译在IEEE库中,也是Synopsys公司的程序包。主要定义有符号数的运算,重载后可用于INTEGER(整数)、STD_LOGIC(标准逻辑位)和STD_LOGIC _VECTOR(标准逻辑位向量)之间的混合运算,并且定义了STD_LOGIC _VECTOR到INTEGER的转换函数。还定义了STD_LOGIC _VECTOR类型的符号数算数运算子程序。 - 4.STD_LOGIC_UNSIGNED程序包
该程序包用来定义无符号数的运算,其他功能与STD_LOGIC_SIGNED相似。
2.2 实体(Entity)
实体描述了设计单元的输入输出接口信号或引脚,是设计实体经封装后对外的一个通信界面。
- 端口n的声明最后一定不能加";",不然会报错误:next process的")" expect ";"
- port中端口默认类型为signal
2.2.1 类属:
-
类属说明的书写格式是:
-
其他
类属 GENERIC 参量是一种端口界面常数,常以一种说明的形式放在实体或块结构体前的说明部分。比较常见的情况是利用类属来动态规定一个实体的端口的大小,或设计实体的物理特性,或结构体中的总线宽度,或设计实体中底层中同种元件的例化数量等等。一般在结构体中,类属的应用与常数是一样的,其中的常数名是由设计者确定的类属常数名,数据类型通常取 INTEGER 或TIME 等类型,设定值即为常数名所代表的数值,但需注意 VHDL 综合器仅支持数据类型为整数的类属值。例如:
2.2.2 端口
- 端口语句的格式:
- 端口模式有:
- IN : 在实体中只读,接受外来数据. 只能出现在赋值语句的右侧。
- OUT: 在实体中只能更新,不可读。只能出现在赋值语句的左侧。
- INOUT: 在实体内部可更新、可读,可出现在赋值语句的两侧。
- BUFFER: 可用作内部赋值,可出现在赋值语句的两侧。在可综合代码中不推荐使用。
2.3 结构体
2.3.1 结构体的作用和特点
2.3.1.1 作用
结构体的任务是:定义结构体中的各项内部使用元素,如数据类型(TYPE),常数(CONSTAND),信号(SIGNAL),元件(COMPONENT),过程(POCEDURE),变量(VARIABLE)和进程(PROCESS)等。通过VHDL语句描述实体所要求的具体行为和逻辑功能。描述各元件之间的连接。
2.3.1.2 特点
- 用于描述模型的功能
- 必须和一个 Entity相关联
- 一个Entity可有多个 Architectures
- Architecture 语句并发执行.
2.3.2 结构体的格式:
2.3.3 结构体的四种描述方式
结构化描述、数据流描述、行为描述、混合。
2.3.3.1 结构描述
原件和内联,通过低级器件的内联实现。
特点:
- 描述电路的功能和结构。
- 可调用专用硬件。
- 可综合。
- 结构化、模块化。
- 结构化描述易于理解,接近于原理图,使用简单的模块组成逻辑电路,实现逻辑功能。
- 组件以层次化相连接。
- 结构化描述可以将简单门、甚至更复杂的逻辑门连接在一起。
- 结构化描述在团队协作时非常有用。
2.3.3.2 RTL(寄存器传输级)描述, 又称数据流描述
描述数据在系统中的流动过程,数据流使用一系列的并发语句实现逻辑,数据流的描述是在控制逻辑函数已经获得的条件下实现,数据流代码亦称为并发代码。
注意:并发语句在编译中被同时评估,因此语句的顺序无关紧要。
特点:
- 直接使用基本门和扩展门实现,没有结构化。
- 逻辑表达式在编码之前需要写好。
- 没有特定的硬件约束。
- 可以综合。
- 数据流使用一系列的并发语句实现逻辑. 。
- 数据流的描述是在控制逻辑函数已经获得的条件下实现。
- 数据流代码亦称为并发代码。
举例:
- input: x1, x2, x3, ... , xn;
- output: y1, y2, y3, ..., yn;
- 数据流描述:
2.3.3.3 行为描述
顺序和并发语句,通过输入输出响应描述。
特点:
- 电路的功能,无关结构(用于数学模型或系统工作原理的仿真)。
- 不面向特定硬件。
- 不一定可综合。
- 易于理解,因为行为描述更像人类的语言。
- 它精确地表示了在“黑盒子”内部发生的输入-输出之间的关系。
- 在VHDL中,通常使用PROCESS(进程)实现。
举例:
- input: x1, x2, x3, ... , xn;
- output: y1, y2, y3, ..., yn;
- 行为描述:
2.3.3.4 举例说明,下面是一个两位相等比较器的例子
用行为描述方式设计的全加器
2.3.4 块语句结构:
2.3.5 进程语句结构:
2.4 配置(Configuration)
2.4.1 配置的作用
- 用于实现模型的关联,可将一个 Entity 和一个Architecture关联起来,也可将一个 component 和一个 entity-architecture关联起来。
- 目的是为了在一个实体中灵活的使用不同的Architecture。可以在仿真环境中大量使用,但是在综合环境中限制使用。
2.4.2 配置的格式
2.4.3 配置举例
2.5 子程序模块
能被主程序反复调用并能将处理结果传送到主程序的程序模块,子程序分为过程语句(Procedure)和函数(Functure)两种。子程序中的参数说明是局部的,只能在子程序体内起作用。
2.5.1 过程语句(Procedure)
2.5.2 函数(Functure)
3 VHDL基本语法
3.1 标识符
标识符用来定义常数、变量、信号、端口、子程序或者参数的名字。由字母(A~Z, a~z)、数组(0~9)和下划线(_)字符组成。
3.1.1 标识符规则:
- 首字符必须是字母
- 末字符不能为下划线
- 不允许出现两个连续的下划线
- 不区分大小写
- VHDL定义的保留字(关键字),不能用作标识符
- 标识符字符最长可以是32个字符
- 注释由两个连续的下划线(--)引导
3.1.2 关键字 (保留字)
关键字(keyboard)是VHDL中具有特别含义的单词,只能作为固定的用途,用户不能用其做为标识符。
3.2 数据对象
3.2.1 信号(SIGNAL)
为全局变量,在程序包说明、实体说明、结构体描述中使用,用于声明内部信号,而非外部信号(外部信号为IN、OUT、INOUT、BUFFER),其在元件之间起互联作用,可以赋值给外部信号。
定义格式:
赋值格式:
常在结构体中用赋值语句完成对信号赋初值的任务,因为综合器往往忽略信号声名时所赋的值。
3.2.2 变量(VARIABLE)
只在给定的进程(process)中用于声明局部值或用于子程序中,变量的赋值符号为“:=”,和信号不同,信号是实际的,是内部的一个存储元件(SIGNAL)或者是外部输入(IN、OUT、INOUT、BUFFER),而变量是虚的,仅是为了书写方便而引入的一个名称,常用在实现某种算法的赋值语句当中。
定义格式:
变量赋值符号":=",变量赋值立刻更新。
3.2.3 常量(CONSTAT)
在结构体描述、程序包说明、实体说明、过程说明、函数调用说明和进程说明中使用,在设计中描述某一规定类型的特定值不变,如利用它可设计不同模值的计数器,模值存于一常量中,对不同的设计,改变模值仅需改变此常量即可,就如上一章所说的参数化元件。
定义格式:
3.2.4 信号与变量的区别
信号与变量最大的不同在于,如果在一个进程中多次为一个信号赋值,只有最后一个值会起作用,而当为变量赋值时,变量的值改变是立即发生的。
3.3 数据类型
VHDL是一种强类型语言,对于每一个常数、变量、信号、函数及设定的各种参量的数据类型(DATA TYPES)都有严格要求,相同数据类型的变量才能互相传递和作用,标准定义的数据类型都在VHDL标准程序表STD中定义,实际使用中,不需要用USE语句以显式调用。
VHDL常用的数据类型有三种:
- 标准定义的数据类型
- IEEE预定义标准逻辑位
- 矢量及用户自定义的数据类型。
3.3.1 标准定义的数据类型
- 布尔:(Boolean)
Type BOOLEAN IS (FALSE, TRUE);
取值为FALSE和TRUE,不是数值,不能运算,一般用于关系运算符
- 位:(Bit)
TYPE BIT IS (‘0‘, ‘1‘);
取值为0和1,用于逻辑运算
- 位矢量:(Bit_Vector)
TYPE BIT_VECTOR IS ARRAY(Natural range<>) OF BIT;
基于Bit类型的数组,用于逻辑运算
SIGNAL a: Bit_Vector (0 to 7); Signal a: Bit_Vector (7 to 0);
- 字符:(character)
TYPE CHARACTER IS (NUL, SOH, STX, ..., ‘‘, ‘!‘, ...);
通常用‘‘引号引起来,区分大小写
- 字符串:(String)
通常用""双引号引起来,区分大小写
VARIABLE string_var: STING (1 to 7);
string_var := "ABCD"
- 整数:(Integer)
取值范围,可用32位的有符号的二进制数表示
VARIABLE a: INTEGER -63 to 63
在实际应用中,VHDL仿真器将ITEGER作为有符号数处理,而VHDL综合器将Integer作为无符号数处理
要求用range子句为所定义的数限定范围,以便根据范围来决定表示此信号或变量的二进制的位数。
- 实数:(real)
实数类型仅能在VHDL仿真器中使用,综合器不支持
取值范围
- 时间:(Time)
物理量数据,包括整数和单位两个部分
时间类型仅能在VHDL仿真器中使用,综合器不支持
范围从
表达方法包含数字、(空格)单位两部分,如(10 PS)
常用单位:fs,ps,ns,us,ms,sec,min,hr
- 错误等级:(severity level)
表示系统状态
该类型仅能在VHDL仿真器中使用,综合器不支持
TYPE severity_lever IS (NOTE, WARNING, ERROR, FAILURE)
3.3.2 IEEE预定义的标准逻辑位与矢量
STD_LOGIC
:工业标准的逻辑类型,取值为‘0’(强制为高)、‘1’(强制为低)、‘Z’(高阻态)、‘X’(强未知)、‘W’(弱未知;弱信号不定)、‘L’(弱0;弱低)、‘H’(弱1;若高)、‘-’(忽略;不关心)、‘U’(未初始化),只有前四种具有实际物理意义,其他的是为了与模拟环境相容才保留的。STD_LOGIC_VECTOR
:工业标准的逻辑类型集,STD_LOGIC的组合。
3.3.3 用户自定义的数据类型
- 枚举类型
- 格式:
TYPE 数据类型名 IS (枚举文字,枚举文字,. . . .)
- 格式:
- 整数类型和实数类型
- 整数类型与实数类型是标准包中预定义的整数类型的子集,由于综合器无法综合未限定范围的整数类型的信号或变量,故一定要用RANGE子句为所定义整数范围限定范围以使综合器能决定信号或变量的二进制的位数。
- 格式:
TYPE 数据类型名 IS RANGE 约束范围;(如-10到+10)
- 数组类型
- 格式:
TYPE 数据类型名 IS ARRAY(下限 TO 上限) OF 类型名称
- 格式:
- 记录类型
- 格式:
3.4 运算符
3.4.1 算术运算符
- +, -, *, /
- MOD: 取模,取模运算(a MOD b)的符号与b相同,其绝对值小于b的绝对值。如:-5 MOD 2 = 1,5 MOD -2 = -1。
- REM: 取余,取余运算(a REM b)的符号与a相同,其绝对值小于b的绝对值。如:-5 REW 2 = -1,5 MOD -2 = 1。
- 多数语言对取余和取整不区分,比如python都是用%符号。详情见https://blog.csdn.net/origin_lee/article/details/40541053。
- SLL(Shift Left Logical): 逻辑左移,将位向量左移,右边移空位补零。
- SRL(Shift Right Logical): 逻辑右移,将位向量右移,左边移空位补零。
- SLA(Shift Left Arithmetic): 算数左移,将位向量左移,右边第一位数值保持不变。
- SRA(Shift Right Arithmetic): 算数右移,将位向量右移,左边第一位数值保持不变。
- ROL(rotate left): 循环左移。
- ROR(rotate right): 循环右移。
- **: 乘方。
- ABS(absolute): 取绝对值。
3.4.2 关系运算符
- =,/=,<,>,<=,>=
3.4.3 逻辑运算符
- AND, OR
- NAND, NOR, NOT
- XNOR: 同或, XOR: 异或
3.4.4 赋值运算符
- <=: 信号赋值,最后赋值。
- :=:逻辑赋值,即时赋值。
3.4.5 关联运算符
- =>
3.4.6 其他运算符
- +,-
- &:并置操作符
3.4.7 运算符优先级
3.4.8 运算符表格一览
关于运算符的分类暂不详究。。。
4 VHDL语句
顺序语句和并行语句是VHDL程序设计中两大基本描述语句系列。顺序语句(Sequential Statements)用来实现模型的算法描述;并行语句(Concurrent Statements)用来表示各模型算法描述之间的连接关系,这些语句从多侧面完整地描述数字系统的硬件结构和基本逻辑功能,其中包括通信的方式、信号的赋值、多层次的元件例化以及系统行为等。
4.1 并行语句
4.1.1 并行语句的特点
- 相对于传统的软件描述语言,并行语句结构是最具VHDL特色的:并行运行。
- 物理意义:硬件连接关系
- 每一并行语句内部的语句运行方式可以有两种不同的方式,即并行执行方式(如块语句)和顺序执行方式(如进程语句)。因此,VHDL并行语句勾画出了一幅充分表达硬件电路的真实的运行图景。
4.1.2 并行语句的格式
4.1.3 并行语句的种类
- 并行信号赋值语句(CONCURRENT SIGNAL ASSIGNMENTS)
- 条件/选择信号赋值语句(CONDITIONAL/SELECTED SIGNAL ASSIGNMENTS)
- 进程语句(PROCESS STATEMENTS)
- 块语句(BLOCK STATEMENTS)
- 元件例化语句(COMPONENT INSTANTIATIONS)
- 生成语句(GENERATE STATEMENTS)
- 并行过程调用语句(CONCURRENT PROCEDURE CALLS)
4.1.3.1 并行信号赋值语句
4.1.3.2 条件信号赋值语句
4.1.3.3
4.2 顺序语句
以上是关于VHDL语言基础的主要内容,如果未能解决你的问题,请参考以下文章