VHDL学习笔记

一、VHDL简介

VHDL

VHDL(Very High Speed Hardware Description Language)超高速硬件描述语言。VHDL是工业标准的文本格式语言,支持仿真和综合,是一种并发执行的语言。VHDL支持结构化设计和TOP-DOWN设计方法。其描述与工艺无关,支持多风格的描述方法。

VHDL的历史:

  • 1982年,诞生于美国国防部赞助的VHSIC(Very High Speed Integrated Circuit)项目。
  • 1987年底,VHDL被IEEE和美国国防部确认无标准硬件描述语言,即IEEE-1076(简称87版)
  • 1993年,IEEE对VHDL进行了修订,共不了新版本的VHDL,即IEEE标准的1076-1993(1164)版
  • 1996年,IEEE-1076.3成为VHDL综合标准。

VHDL的基本设计单元

  1. Library和Package(库和程序包)
    --库主要存放已经编译过的实体、结构体、程序包和配置;
    --程序包主要用来存放各个设计都能共享的数据类型、子程序说明、属性说明、元件说明等部分。
  2. Entity(实体)--用来说明模型的外部特征
  3. Architecture(结构体/构造体)--来定义模型的功能
  4. Configuration(配置)--将实体和它的结构体联系起来



图1.VHDL的基本设计单元


VHDL基本设计单元(例子)

例:用VHDL语言设计一个2选1的数据选择器

--实体声明
entity mux21 is
port(a,b:in bit;--输入-数据(bit类型)
   s:in bit;--输入-选择信号(bit类型)
   y:out bit--输出(bit类型)
   );
end entity mux21;
--结构体(实体内部逻辑)
architecture one of mux21 is
signal d,e:bit;--临时中间变量
begin
d<=a and (not s);    --左边三行可以用下面的语句代替。
e<= b and s;          --y<= a when s=’0’ else
y<= d or e;           -- b;
end architecture one;

二、VHDL结构

库和程序包


  • 库是专门用于存放预先编译好的程序包的地方,对应一个文件目录,程序包的文件就放在此目录中,其功能相当于共享资源的仓库,所有已完成的设计资源只有存入某个“库”内才可以被其他实体共享。库的说明总是放在设计单元的最前面,表示该库资源对以下的设计单元开放。库语句格式如下:
    LIBRARY 库名 ;
    常用的库有IEEE库、STD库和WORK库:

    • IEEE库:是VHDL设计中最常用的资源库,包含IEEE标准的STD_LOGIC_1164、NUMERIC_BIT、NUMERIC_STD以及其他一些支持工业标准的程序包。其中最重要和最常用的是STD_LOGIC_1164程序包,大部分程序都是以此程序包中设定的标准为设计基础。
    • STD库:是VHDL的标准库,VHDL在编译过程中会自动调用这个库,所以使用时不需要用语句另外说明。
    • WORK库:是用户在进行VHDL设计时的现行工作库,用户的设计成果将自动保存在这个库中,是用户自己的仓库,同STD库一样,使用该库不需要任何说明。
  • 程序包
    程序包是用VHDL语言编写的一段程序,可以供其他设计单元调用和共享,相当于公用的“工具箱”,各种数据类型、子程序等一旦放入了程序包,就成为共享的“工具”,类似于C语言的头文件,使用它可以减少代码的输入量,使程序结构清晰。在一个设计中,实体部分所定义的数据类型、常量和子程序可以在相应的结构体中使用,但在一个实体的声明部分和结构体部分中定义的数据类型、常量及子程序却不能被其他设计单元使用。因此,程序包的作用是可以使一组数据类型、常量和子程序能够被多个设计单元使用。
    程序包分为包头和包体两部分。包头(也称程序包说明)是对包中使用的数据类型、元件、函数和子程序进行定义,其形式与实体定义类似。包体规定了程序包的实际功能,存放函数和过程的程序体,而且还允许建立内部的子程序、内部变量和数据类型。包头、包体均以关键字PACKAGE开头。程序包格式如下。

    --包头格式:
    PACKAGE 程序包名 IS
    [包头说明语句]
    END 程序包名;
    
    --包体格式:
    PACKAGE BODY 程序包名 IS
    [包体说明语句]
    END 程序包名;
    

    调用程序包的通用模式为:USE 库名.程序包名.ALL;

    常用预定义程序包有以下四个:

    • 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的转换函数。
    • 4.STD_LOGIC_UNSIGNED程序包
      该程序包用来定义无符号数的运算,其他功能与STD_LOGIC_SIGNED相似。

实体

  • 实体格式

    名称 内容
    引导语句 ENTITY 实体名 IS
    类属表 GENERIC(------)
    端口表 PORT(------)
    结束语句 END 实体名
  • VHDL的结构关系图



    图1.VHDL的基本设计单元


类属

  • 类属说明的书写格式是:
    GENERIC(常数名:数据类型:设定值);

  • 其他
    类属 GENERIC 参量是一种端口界面常数,常以一种说明的形式放在实体或块结构体前的说明部分。比较常见的情况是利用类属来动态规定一个实体的端口的大小,或设计实体的物理特性,或结构体中的总线宽度,或设计实体中底层中同种元件的例化数量等等。一般在结构体中,类属的应用与常数是一样的,其中的常数名是由设计者确定的类属常数名,数据类型通常取 INTEGER 或TIME 等类型,设定值即为常数名所代表的数值,但需注意 VHDL 综合器仅支持数据类型为整数的类属值。例如:

    ENTITY mcu1 IS
    GENERIC (addrwidth : INTEGER := 16);
    PORT(
        add_bus : OUT STD_LOGIC_VECTOR(addrwidth-1 DOWNTO 0) );
        ...
    

    在这里 GENERIC 语句对实体 mcu1 作为地址总线的端口 add_bus 的数据类型和宽度作了定义 即定义 add_bus 为一个 16 位的标准位矢量 定义 addrwidth 的数据类型是整数INTEGER 其中 常数名addrwidth减 1 即为 15 所以这类似于将上例端口表写成PORT (add_bus : OUT STD_LOGIC_VECTOR (15 DOWNTO 0));

端口

  • 端口语句的格式:
    PORT(端口信号名:端口模式 数据类型;
    端口信号名:端口模式 数据类型);
    
  • 端口模式有:
    • IN 输入;
    • OUT 输出;
    • INOUT 双向;
    • BUFFER 缓冲

结构体

  • 作用
    结构体的任务是:定义结构体中的各项内部使用元素,如数据类型(TYPE),常数(CONSTAND),信号(SIGNAL),元件(COMPONENT),过程(POCEDURE),变量(VARIABLE)和进程(PROCESS)等。通过VHDL语句描述实体所要求的具体行为和逻辑功能。描述各元件之间的连接。

  • 结构体格式:

    结构体名 OF 实体名 IS
    定义语句法;
    BEGIN
    功能描述语句法;
    END 结构体名称;
    
  • 结构体的三种描述方式:

    • 行为描述
    • 数据流描述
    • 寄器传输(RTL)
    • 例:用行为描述方式设计的全加器
    LIBRARY IEEE;
    USE IEEE.STD_LOGIC_1164.ALL;
    
    ENTITY onebitadder IS
    PORT(a,b,cin:IN BIT;
    Sum,count:OUT BIT);
    END onebitadder;
    
    ARCHITECTURE behavior OF onebitadder IS
    BEGIN
    PROCESS(a,b,cin)
    BEGIN
    Sum<= a XOR b XOR cin;
    Count<=(a AND b) OR ((a XOR b) AND cin);
    END PROCESS;
    END behavior;
    
  • 块语句结构:

    块结构名:
    BLOCK 
    端口说明 类属说明
    BEGIN
    并行语句
    END BLOCK 块结构名;
    
  • 进程语句结构:

    进程名:
    PROCESS(敏感信号表) IS
    进程说明
    BEGIN
    顺序描述语句
    END PROCESS 进程名;
    

子程序模块

能被主程序反复调用并能将处理结果传送到主程序的程序模块,子程序分为过程语句(Procedure)和函数(Functure)两种。子程序中的参数说明是局部的,只能在子程序体内起作用。

  • 1.过程语句(Procedure)

    PROCEDURE 过程名(参数1;参数2;----) IS
    定义语句;
    BEGIN
    顺序处理语句;
    END 过程名;
    
  • 2.函数(Functure)

    FUNCTION 函数名(参数1;参数2;----)
    RETURN 数据类型 IS
    定义语句;
    BEGIN
    顺序处理语句;
    RETURN 返回变量名;
    

三、VHDL基本语法

1、标识符规则

  • 应以英文字母开头
  • 允许包含图形符号如回车符,换行符,空格符
  • 不能使用VHDL中的关键字
  • 标识符的下标加括号表示
  • VHDL的数据对象分为:常量,变量和信号

2、数据对象

  • 信号SIGNAL
    为全局变量,在程序包说明、实体说明、结构体描述中使用,用于声明内部信号,而非外部信号(外部信号为IN、OUT、INOUT、BUFFER),其在元件之间起互联作用,可以赋值给外部信号。
    定义格式:SIGNAL 信号名: 数据类型[:=初始值];
    赋值格式:目标信号名<=表达式
    常在结构体中用赋值语句完成对信号赋初值的任务,因为综合器往往忽略信号声名时所赋的值。
  • 变量(VARIABLE)
    只在给定的进程中用于声明局部值或用于子程序中,变量的赋值符号为“:=”,和信号不同,信号是实际的,是内部的一个存储元件(SIGNAL)或者是外部输入(IN、OUT、INOUT、BUFFER),而变量是虚的,仅是为了书写方便而引入的一个名称,常用在实现某种算法的赋值语句当中。
    定义格式:VARIABLE 变量名: 数据类型[:=初始值]
  • 常量
    在结构体描述、程序包说明、实体说明、过程说明、函数调用说明和进程说明中使用,在设计中描述某一规定类型的特定值不变,如利用它可设计不同模值的计数器,模值存于一常量中,对不同的设计,改变模值仅需改变此常量即可,就如上一章所说的参数化元件。
    定义格式:CONSTANT 常数名:数据类型:=表达式;
  • 信号与变量的区别
    \color{red}信号和变量最大的不同在于,如果在一个进程中多次为一个信号赋值,只有最后一个值会起作用,而当为变量赋值时,变量的值改变是立即发生的。

3、数据类型

VHDL是一种强类型语言,对于每一个常数、变量、信号、函数及设定的各种参量的数据类型(DATA TYPES)都有严格要求,相同数据类型的变量才能互相传递和作用,标准定义的数据类型都在VHDL标准程序表STD中定义,实际使用中,不需要用USE语句以显式调用。

  • VHDL常用的数据类型有三种:

    • 标准定义的数据类型
    • IEEE预定义标准逻辑位
    • 矢量及用户自定义的数据类型。
  • 标准定义的数据类型

    • Boolean布尔量:取值为FALSE和TRUE
    • CHARACTER字符:字符在编程时用单引号括起来,如‘A’
    • STRING字符串:双引号括起来,如“ADFBD”
    • INTEGER整数:整数范围从-(231-1)到(231-1);
    • REAL实数:实数类型仅能在VHDL仿真器中使用,综合器不支持
    • BIT位:取值为0或1;
    • TIME时间:范围从-(231-1)到(231-1),表达方法包含数字、(空格)单位两部分,如(10 PS);
    • BIT_VECTOR位矢量:其于BIT数据的数组,使用矢量必须注明宽度,即数组中的元素个数和排列,如SIGNAL A: BIT_VECTOR(7 DOWNTO 0)
    • NATUREAL自然数:整数的一个
    • POSITIVE正整数
    • SEVRITY LEVEL错误等级:在VHDL仿真器中,错误等级用来设计系统的工作状态,共有四种可能的状态值:NOTE,WARNING,ERROR和FAILURE
  • IEEE预定义的标准逻辑位与矢量

    • STD_LOGIC:工业标准的逻辑类型,取值为‘0’、‘1’、‘Z’、‘X’(强未知)、‘W’(弱未知)、‘L’(弱0)、‘H’(弱1)、‘—’(忽略)、‘U’(未初始化),只有前四种具有实际物理意义,其他的是为了与模拟环境相容才保留的。
    • STD_LOGIC_VECTOR:工业标准的逻辑类型集,STD_LOGIC的组合。
  • 用户自定义的数据类型

    • 枚举类型
      • 格式:TYPE 数据类型名 IS (枚举文字,枚举文字,. . . .)
    • 整数类型和实数类型
      • 整数类型与实数类型是标准包中预定义的整数类型的子集,由于综合器无法综合未限定范围的整数类型的信号或变量,故一定要用RANGE子句为所定义整数范围限定范围以使综合器能决定信号或变量的二进制的位数。
      • 格式:TYPE 数据类型名 IS RANGE 约束范围;(如-10到+10)
    • 数组类型
      • 格式:TYPE 数据类型名 IS ARRAY(下限 TO 上限) OF 类型名称
    • 记录类型
      *格式:
      TYPE 记录类型名 IS RECODE
      元素名: 数据类型名;
      元素名: 数据类型名;
      END RECODE
      

4、运算符

  • 算术运算符:+、-、、/、*、MOD、REM、ABS
  • 关系运算符:=、/=、<、<=、>、>=
  • 逻辑运算符:AND、OR、NOT、NAND、NOR、XOR、NOR
  • 连接运算符:&,将多个对象或矢量连接成维数更大的矢量

5、顺序语句

  • 1、赋值语句
    赋值语句分为变量赋值和信号赋值,它们的赋值是有区别的。
    首先在格式上,变量赋值格式为“变量名:=表达式”,而信号的赋值格式为“信号名<=表达式;
    其次体现在所用的地方,变量说明和使用都只能在顺序语句中(进程、函数、过程和块模块),而信号的说明只能在同步语句中,但可以在顺序语句和同步语句中使用;
    再次体现在赋值过程,变量的赋值是立即的,而信号的赋值的执行和信号值的更新至少要延时DELTA延时,只有延时后信号才能得到新值,否则将保持原值,在进程中,信号赋值在结束时起作用。

  • 2、WAIT语句
    WAIT语句属于敏感信号激励信号,一个进程语句含有敏感信号时,进程中不能出现WAIT等待语句;当进程语句不含有敏感信号时,进程语句必须含有其他形态的敏感信号激励。
    WAIT语句有五种形式:
    * WAIT ——无限等待;
    * WAIT ON (敏感信号1,敏感信号2,敏感信号N) ——敏感信号变化,表中的信号产生变化时才往下运行;
    * WAIT UNTIL 布尔表达式 ——为TRUE时,进程启动,为FARLSE是等待
    * WAIT FOR 时间表达式 ——到时进程才会启动
    * WAIT UNTIL 布尔表达式 ON (敏感信号1,敏感信号2,敏感信号N) FOR 时间表达式 ——多条件等待语句,注意在多条件等待语句的表达式中,至少应有一个信号量,因为处于等待进程中的变量是不可改变的。

  • 3、IF语句

    [IF标号:] IF <条件> THEN
    <顺序处理语句>;
    [ELSIF <条件> THEN
    <顺序处理语句>;]
    …….
    [ELSE
    <顺序处理语句>;]
    END IF [IF标号]
    
  • 4、 CASE语句

    CASE 〈条件表达式〉 IS
    WHEN 〈条件取值〉 =>顺序处理语句;
    WHEN 〈条件取值〉 =>顺序处理语句;
    WHEN 〈条件取值〉 =>顺序处理语句;
    WHEN   OTHERS =>顺序处理语句;
    END CASE;
    
  • 5、 LOOP循环语句

    • LOOP格式:
    [LOOP 标号:] [重复模式]LOOP
    〈顺序处理语句〉;
    END LOOP [LOOP标号] ;
    
    • FOR模式
    FOR模式的LOOP语句格式:
    [LOOP标号:] FOR 循环变量 IN 离散范围 LOOP
    〈顺序处理语句〉;
    END LOOP [LOOP标号];
    
    • WHILE模式
    WHILE模式的LOOP语句格式:
    [LOOP标号:] WHILE〈条件〉LOOP
    〈顺序处理语句〉;
    END LOOP[LOOP标号];
    
  • 6、 NEXT和EXIT语句
    这两种语句都是用于跳出LOOP循环的,NEXT语句是用来跳出本次循环的,而EXIT语句是用于跳出全部循环的。格式:
    NEXT或EXIT [LOOP标号] [WHEN条件]

  • 7、 NULL空操作语句
    书写格式:NULL;
    作用:使程序流程运行到下一个语句,常用于CASE语句当中

  • 8、 RETURN语句
    用在一段子程序结束后,用来返回到主程序的控制语句,一般情况之下,有两种书写格式,分别是:
    VHDL RETURN; —只能用于进程返回 RETURN 表达式;——只能用于函数返回
    在实际的应用中,一般的VHDL综合工具要求函数中只能包含一个RETURN,并规定这条RETURN语句只能写在函数末尾,但一些VHDL综合工具允许函数中出现多个RETURN语句。

  • 9、 ASSERT断言语句
    主要用于程序仿真、调试中的人机对话,它可以给出一个文字串作为警告和错误信息,基本书写格式如下:

    ASSERT〈条件〉
    REPORT〈输出信号〉   ——字符串
    SEVERITY〈错误级别〉;——有四种NOTE、WARNING、ERROR和FAILURE
    

    如果程序在仿真或调试过程中出现问题,断方语句就会给出一个文字串作为提示信息,当程序执行到断言语句时,就会对ASSERT条件表达式进行判断,如果返回值为TRUE则断言语句不做任何操作,程序向下执行,如果返回值为FALSE,则输出指定的提示信息和出错级别。
    断言语句可以分为顺序断言语句和并行断言语句。

  • 10、 REPORT语句
    报告语句是93版VHDL标准提供的一种新的顺序语句,该语句没有增加任何功能,只是提供了某些形式的顺序断言语句的短格式,也算是ASSERT语句的一个精简,格式如下:
    REPORT 〈输出信息〉[SEVERITY〈出错级别〉]

你可能感兴趣的:(VHDL学习笔记)