FPGA学习之VHDL语法的总结

[TOC]

前言

FPGA作为提升处理性能的黑马,这些年越来越火热,不论对于未来是否从事这个方向的人来说,了解FPGA都是很有必要的,抱着学习的心态我学习了FPGA,这篇博文做记录

一、 VHDL是什么?

1. 缩写

VHDL:Very High Speed Integrated Circuit Hardware Description Language

2. 作用

  1. 传统的数字系统设计分为硬件设计、软件设计,VHDL打破了传统的软、硬件设计界限
  2. 类似C、C++代替汇编等语言一样,VHDL代替了原理图、逻辑状态图
  3. 电子系统设计者和EDA工具之间的桥梁
  4. EDA工具及 HDL的流行,促使电子系统向集成化、大规模和高速度等方向发展

3. VHDL与原理图描述的比较

  1. VHDL具有较强的抽象描述能力,可进行系统行为级别的描述。描述更简洁,效率更高;
  2. 原理图描述必须给出完整的、具体的电路结构图,不能进行描象描述。描述繁杂,效率低;
  3. VHDL描述与实现工艺无关;
  4. 原理图描述与实现工艺有关

4. VHDL语言特点

  1. VHDL具有强大的语言结构,系统硬件抽象描述能力强、设计效率高;
  2. VHDL语言可读性强,易于修改和发现错误;
  3. VHDL具有丰富的仿真语句和库函数,可进行早期行为仿真,利于大系统的设计与验证;
  4. VHDL设计与硬件电路关系不大;
  5. VHDL设计不依赖于器件,与工艺无关
  6. 移植性好;
  7. VHDL体系符合TOP-DOWN和CE设计思想;
  8. VHDL设计效率高,产品上市时间快,成本低;
  9. 易于ASIC实现

5. 与其他语言比较

常用硬件描述语言有VHDL、Verilog和ABEL语言。VHDL起源于美国国防部的VHSIC,Verilog起源于集成电路的设计,ABEL则来源于可编程逻辑器件的设计。VHDL语言是一种高级描述语言,适用于行为级和RTL级的描述,最适于描述电路的行为;Verilog语言和ABEL语言是一种较低级的描述语言,适用于RTL级和门电路级的描述,最适于描述门级电路。

二、VHDL程序架构

VHDL基本结构

  1. 实体(Entity)
  2. 结构体(Architecture)
  3. 配置(Configuration)
  4. 库(Library)、程序包(Package)
    在这里插入图片描述

    1. 实体 Entity

  5. 作用:定义系统的输入输出接口
  6. 用法格式:
1
2
3
4
5
ENTITY <entity_name> IS
Generic Declarations
Port Declarations
END <entity_name>; (1076-1987 version)
END ENTITY <entity_name> ; (1076-1993 version)
  • Generic:确定实体或组件中定义的局部常数。模块化设计时多用于不同层次模块之间信息的传递,可从外部改变内部电路和规模,必须放在端口说明之前

    Generic (

           常数名称:类型 [:= 缺省值]
          {常数名称:类型 [:= 缺省值]}
         );

    使用:

    1
    2
    3
    4
    entity and2 is
    generic(risewidth: time:= 1 ns;fallwidth: time:= 1 ns);
    port(a1: in std_logic;a0: in std_logic;z0: out std_loigc);
    end entity and2;
  • 端口声明:确定输入输出端口的数目和类型

    1
    2
    3
    4
    5
    Port (
    端口名称{,端口名称}:端口模式 数据类型;

    端口名称{,端口名称}:端口模式 数据类型
    );

    eg:

1
port(a1: in std_logic; a0: in std_logic; z0: out std_loigc);
  • 补充

1.端口模式的分类:
in 输入型,此端口为只读型。
out 输出型,此端口只能在实体内部对其赋值
inout 输入输出型,既可读也可赋值
buffer 缓冲型,与 out 相似,但可读

2.buffer、inout对比:
inout,输入输出双向端口,可读可写
buffer,为缓冲端口,可读可写,但要读入数据时,只允许内部回读内部产生的输出信号,即反馈
buffer,驱动只有一个源,不允许多重驱动,驱动源可以是其它实体的缓冲端口,也可以是设计实体的内部信号源,但不与其它实体的输出端口、双向端口相连
buffer,仅仅是一个数据缓存器,不能用于IO输出

3.数据类型:
指端口上流动数据的表达格式,为预先定义好的数据类型,如:bit、bit_vector、integer、real、std_logic、std_logic_vector 等

2.结构体 Architecture

  1. 作用:
    定义系统(或模块)的行为、元件及内部的连接关系,即描述其逻辑功能。
  2. 组成部分:

-. 说明部分:对数据类型、常数、信号、子程序、元件等元素的说明
-. 逻辑功能描述部分:以各种不同的描述风格描述系统的逻辑功能。常见的有行为描述/数据流描述以及结构化描述
一个设计实体可有多个结构体,代表实体的多种实现方式。各个结构体的地位相同

在这里插入图片描述
3. 语法:

1
2
3
4
5
6
7
architecture  结构体名称  of   实体名称  is 
[说明语句]内部信号、常数、
数据类型、子程序(函数、过程)、
元件等的说明;
begin
[并行处理(功能描述)语句];
end [architecture] 结构体名称;

注:同一实体的结构体不能同名。定义语句中的常数、信号不能与实体中的端口同名。

使用方式:

1
2
3
4
5
6
7
8
9
10
11
entity test1 is
port(sig,count:in bit;
out1,out2:out bit);
end test1;

architecture Behavioral of test1 is
signal sig:bit;
constant const:bit:='1';
begin

end Behavioral;

eg:

1
2
3
4
5
6
7
8
9
architecture art2 of nand is
begin
c<=‘1’ when (a=‘0’) and (b=‘0’) else
1’ when (a=‘0’) and (b=‘1’) else
1’ when (a=‘1’) and (b=‘0’) else
0’ when (a=‘1’) and (b=‘1’) else
0’;
end architecture art2;

4.库 Libraty 程序包 Package

  1. 程序包定义:
    已定义的常数、数据类型、元件(调用)说明、子程序的一个集合。

  2. 库定义:多个程序包构成库

  3. 两者目的:方便公共信息、资源的访问和共享
    程序包的结构包括:程序包说明(包首)和程序包主体(包体)

  4. 程序包说明

  • 语法:
    package 程序包名 is

              {包说明项}

    end 程序包名;

  • 包说明项:
    use 语句(用来包括其它程序包)
    类型说明、子类型说明、常量说明;
    信号说明、子程序说明、元件说明
    (程序包体仅用于子程序的描述,只有在程序包中要说明子程序时,程序包体才是必须的

eg:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
package seven is
subtype segments is bit_vector(0 to 6);
type bcd is range 0 to 9;
end seven;
library work;
use work.seven.all;
entity decoder is
port(input: in bcd;
drive: out segments);
end decoder;
architecture art of decoder is
begin
with input select
drive<=B“1111110” when 0,
B“0110000” when 1,
B“1101101” when 2,
B“1111001” when 3,
B“0110011” when 4,
B“1011011” when 5,
B“1011111” when 6,
B“1110000” when 7,
B“1111111” when 8,
B“1111011” when 9,
B“0000000” when others;
end architecture art;
  1. 库:
    STD库:包含的程序包为standard,定义最基本的数据类型,如bit,bit_vector ,boolean,integer,real,and time,其中的bit为二值系统(只有‘0’、‘1’)
    IEEE库:定义了四个常用的程序包
    std_logic_1164 (std_logic types & related functions)
    std_logic_arith (arithmetic functions)
    std_logic_signed (signed arithmetic functions)
    std_logic_unsigned (unsigned arithmetic functions)

  2. 库及程序包的使用:

库及程序包的说明应放在实体单元前面
library 库名; library ieee;
use 库名.程序包名.项目名 use ieee.std_logic_1164.all;
use 库名.程序包名.All; use ieee.std_logic_unsigned.conv_integer;

库及程序包的作用范围:仅限于所说明的设计实体(每一个设计实体都必须有自己完整的库及程序包说明语句)

三、VHDL语言要素

1.四类语言要素:

数据对象(Data Object)

  1. 变量(Variable)

物理含义:
暂存某些值的载体,常用于描述算法
局部量,定义于process、function、procedure
具体说明:
变量说明格式
variable 变量名:数据类型 约束条件:= 表达式;
如:variable a, b : bit;
variable count : integer range 0 to 255 := 10;
局部量,只能在进程和子程序中定义、使用,其作用范围仅局限于定义变量的进程和子程序中。
变量的初值可用于仿真,但综合时被忽略

  1. 常量(Constant)

物理含义:
电源、地、恒定逻辑值等
全局量,可定义于上面两种场合
常量说明:
对某一个常量名赋予一个固定的值
constant 常数名:数据类型:= 表达式;
constant data: bit_vector(3 downto 0):=“1010”
constant width: integer: = 8;
constant x: new_bit: = ‘x’;
常量数据类型必须与表达式的数据类型一致
常量是全局量,其作用范围取决于常量被定义的位置。

  1. 信号(Signal)

物理含义
是硬件连接线,端口
全局量,定义于architecture、package、entitiy
具体说明:
电子硬件系统运行的基本特性
各部分电路工作的并行特性;
信号传输过程中的延时特性;
多驱动源的总线特性;
时序电路中触发器的记忆特性
信号是电子系统内部硬件连接和硬件特性的抽象表示:
signal 信号名:数据类型 约束条件:= 表达式;
如:signal s2 : std_logic_vector(15 downto 0);
综合时初值被忽略
信号是全局量,可在结构体、实体、块中 说明和使用信号
在进程和子程序中只能使用信号,不能说明信号
信号与端口的区别:信号本身无方向,可读可写;端口是一种有方向的隐形信号

数据类型(Data Type)

VHDL是一种强数据类型语言
设计实体中每一个常数、信号、变量、函数以及设定的各种参量都必须事先说明数据类型
同类型才能互相传递和作用

操作数(Operands)

操作对象常量或变量

操作符(Operator)

分类:

  1. 逻辑操作符(Logical Operator)
    6种:and、or、nand、nor、xor、not
    操作数类型必须相同,可为如下类型:bit、bit_vector、std_logic、std_logic_vector、boolean,数组操作数的维数、大小必须相同

  2. 关系操作符(Relational Operator)

    用于比较相同父类的两个操作数,返回boolean值
    6 种:=、/=、<、<=、>、>=

  3. 算术操作符(Arithmetic Operator)

    加操作符“+”、减操作符“-”
    串联(并置)操作符“&”:通过连接操作数来建立新的数组。操作数可以是一个数组或数组中的一个元素

  4. 重载操作符(Overloading Operator)

    仅有一个操作数的操作符,包括:“+”、“-”
    乘除操作符
    用于整数类型:“*”、“/”、“mod”、“rem”
    综合的限制:“/ ”、“mod”、“rem” 三种操作符的右操作数必须为 2 的正整数次幂,即 2n。实际电路用移位实现
    A rem B 余数运算符,利用操作数A决定结果的正负号;A mod B 取模运算符,利用操作数B决定结果的正负号

四、VHDL顺序语句

  1. 执行顺序与书写顺序一致,与传统软件设计语言的特点相似

  2. 顺序语句只能用在进程与子程序中

  3. 可描述组合逻辑、时序逻辑

  4. 常用的顺序描述语句:
    赋值语句; if语句;case语句;loop语句;
    next语句;exit语句;子程序;return语句;
    wait语句;null语句

注明:

  1. 变量赋值和信号赋值
    赋值标识符的不同
    变量:= 表达式;
    信号 < = 表达式
  2. 硬件实现的功能不同
    信号代表电路单元、功能模块间的互联,代表实际的硬件连线
    变量代表电路单元内部的操作,代表暂存的临时数据;
  3. 有效范围的不同
    信号:全局量,程序包、实体、结构体
    变量:局部量,进程、子程序
  4. 赋值行为的不同
    信号赋值延迟更新数值
    变量赋值立即更新数值
  5. 信号的多次赋值
    一个进程:最后一次赋值有效
    多个进程:多源驱动,线与、线或、三态

五、VHDL并发语句

常用的并发描述语句有:进程(process)语句、块(block)语句、顺序描述语句的并行版本、并行过程调用语句、元件例化语句、生成语句

  1. 进程(process)语句最具VHDL语言特色。提供了一种用算法描述硬件行为的方法:
    进程与进程,或其它并发语句之间的并发性
    进程内部的顺序性
    进程的启动与挂起
    进程内要读取的所有敏感信号(包括端口)的列表。每一个敏感信号的变化,都将启动进程。如果有 wait 语句,则不允许有敏感信号表。
  2. 块语句
    块语句将一系列并行描述语句进行组合,目的是改善并行语句及其结构的可读性。可使结构体层次鲜明,结构清晰
  3. 并行信号赋值语句包括三种
    简单并行信号赋值
    条件信号赋值
    选择信号赋值
    赋值目标必须是信号,与其它并行语句同时执行,与书写顺序及是否在块语句中无关,每一信号赋值语句等效于一个进程语句,所有输入信号的变化都将启动该语句的执行

总结

以上就是今天要讲的内容,本文仅仅简单总结了FPGA的基本语法,更多的提高还是要多做实践

wechat