本文主要参考b站视频:【考研】EDA技术(vhdl技术),建议有时间的跟着听一下,从第8节开始,一直到31节都是讲VHDL,讲的很全面,赶时间的可以直接看我这个笔记。
一、概述
1.1 什么是VHDL
VHDL:超高速集成电路硬件描述语言
VHSIC(Very High Speed Integrated Circuit,超高速集成电路)
Hardware
Description
Language
1.2 VHDL历史
- 80年代初由美国国防部在实施超高速集成电路(VHSIC)项目时开发的。
- 1987年由IEEE协会批准为IEEE工业标准,称为IEEE1076-1987。
- 各EDA公司相继推出支持VHDL的设计环境。
- 1993年被更新为93标准,即EEE1076-1993。
- 进一步提高抽象描述层次,扩展系统描述能力。
- 很多EDA工具只能支持87标准
1.3 VHDL作用
1.3.1 VHDL打破软、硬件的界限
传统的数字系统设计分为:
硬件设计(硬件设计人员)
软件设计(软件设计人员)
是电子系统设计者和EDA工具之间的界面,EDA工具及HDL的流行,使电子系统向集成化、大规模和高速度等方向发展。美国硅谷约有80%的ASIC和FPGA/CPLD已采用HDL进行设计。
1.3.2 VHDL与C、C++的比较
C、C+代替汇编等语言;VHDL代替原理图、逻辑状态图等
1.3.3 VHDL与电原理图描述的比较
- VHDL具有较强的抽象描述能力,可进行系统行为级别的描述。描述更简洁,效率更高。VHDL描述与实现工艺无关。
- 电原理图描述必须给出完整的、具体的电路结构图,不能进行描象描述。描述繁杂,效低。电原理图描述与实现工艺有关。
1.3.4 VHDL语言特点
①VHDL具有强大有语言结构,系统硬件描述能力强、设计效率高;具有较高的抽象描述能力。
如:一个可置数的16位计数器的电原理图:
library ieee;
use ieee. std_logic_1164. all;
use ieee. std_logic_unsigned.all;
entity cnt16b is
port(clk, clr, en, load: in std_logic;
din: in std_logic vector(15 downto 0);
dout: out std _logic vector(15 downto 0));
end cnt16b;
architecture rtl of cnt16b is
signal count16: std_logic_vector(15 downto 0);
begin
dout<=count16;
procese(clk, clr, en, load) begin
if(clr='1') then count16<=(oethers=>'0');
elsif(load='1') then count16<=din;
elsif(clk' event and clk='1') then
if(en='1') then count16<=count16+1;
end if;
endif
end process;
end rtl;
②VHDL语言可读性强,易于修改和发现错误。
③VHDL具有丰富的仿真语句和库函数,可对VHDL源代码进行早期功能仿真,有利于大系统的设计与验证。
④VHIDL设计与硬件电路关系不大。
⑤VHDL设计不依赖于器件,与工艺无关。
⑥移植性好。
⑦VHDL体系符合TOP-DOWN和CE(并行工程)设计思想。
⑧上市时间快,成本低。
⑨易于ASIC实现。
1.1.5 VHDL与其他硬件描述语言的比较
- VHDL:具有较强的系统级抽象描述能力,适合行为级和RTL级的描述。设计者可不必了解电路细节,所作工作较少,效率高。但对综合器的要求高,不易控制底层电路的生成。IEEE标准,支持广泛。
- RTL: Register Translate Level
- Verilog HDL:系统级抽象描述能力比VHDL稍差;门级开关电路描述方面比VHDL强。适合RTL级和门电路级的描述。设计者需要了解电路细节,所作工作较多。IEEE标准,支持广泛。
- ABEL、PALASM、AHDL(Altera HDL):系统级抽象描述能力差,一般作门级电路描述。要求设计者对电路细节有详细的了解。对综合器的性能要求低,易于控制电路资源。支持少。
1.1.6 VHDL设计简述
VHDL主要用于描述数字系统的结构、行为、功能和接口。
VHDL将一个设计(元件、电路、系统)分为:
外部(可视部分、端口)内部(不可视部分、内部功能、算法)
外部叫实体(entity),代表系统的端口信息;内部叫结构体(architecture)。
2选1选择器的VHDL描述
-- 库和程序包的调用
library ieee;
use ieee. std _logic_1164.all;
-- 端口信息
entity mux2l is
port(a,b: in std_logic;
s: in std_logic;
y: out std_logic);
end mux21;
-- 结构体部分
architecture max_arch of mux21 is
begin
y<=a when s='0' else
b when s='1';
end mux_arch;
VHDL语言的一些基本特点
- VHDL语言由保留关键字组成;
- 一般,VHDL语言对字母大小写不敏感;例外:’’、“”所括的字符、字符串
- 每条VHIDL语句由一个分号(;)结束;
- VHDL语言对空格不敏感,增加可读性;
- 在“–”之后的是VHDL的注释语句;
- VHDL有以下描述风格:
- 行为描述;
- 数据流(寄存器传输RTL)描述;
- 结构化描述;
1.2 VHDL程序基本结构
基本结构包括:
- 库(Library)、程序包(Package)
- 实体(Entity)
- 结构体(Architecture)
- 配置(Configuration)
- 配置部分:当一个实体entity具有多个结构体的时候,需要在仿真或者综合的时候对结构体指定一个特定的实体,称为配置部分。
1.2.1 实体(说明)
实体(说明):定义系统的输入输出端口
语法:
ENTITY <entity_name> IS
-- 类属说明,实体后面结构体中用到的一些常数
Generic Declarations
-- 端口说明,实体的输入输出端口情况
Port Declarations
END <entity_name>;(1076-1987 version)
END ENTITY <entity_name>;(1076-1993
version)
1.2.1.1 类属说明
类属说明:确定实体或组件中定义的局部常数。模块化设计时多用于不同层次模块之间信息的传递。可从外部改变内部电路结构和规模。必须放在端口说明之前。
Generic(
常数名称:类型[:=缺省值]
{常数名称:类型[:=缺省值]}
);
注:
- VHDL都是以;作为结尾的
- 如果类型和缺省值都相同,那么多个常数可以写到一行,用“,”分隔
类属常用于定义:实体端口的大小、设计实体的物理特性、总线宽度、元件例化的数量等。
例:
entity mck is
generic(width:integer:=16);
port(add _bus:out std _logic_vector(width-1 downto 0));
...
例:2输入与门的实体描述
entity and2 is
generic(risewidth:time:=1 ns;
fallwidth:time:=1 ns);
port(a1:in std_logic;
a0:in std logic;
z0:out std _logic);
end entity and2;
注:数据类型time用于仿真模块的设计。综合器仅支持数据类型为整数的类属值。
1.2.1.2 端口声明
端口声明:确定输入输出端口的数目和类型。
port(
端口名称{, 端口名称}:端口模式 数据类型;
端口名称{, 端口名称}:端口模式 数据类型
);
其中,端口模式:
- in 输入型,此端口为只读型。
- out 输出型,此端口只能在实体内部对其赋值。
- inout 输入输出型,既可读也可赋值。
- buffer 缓冲型,与out相似,但可读。
数据类型:指端口上流动的数据的表达格式。为预先定义好的数据类型。如:bit、bit vector、integer、std_logic、std_logic_vector等。
例:
entity nand2 is
port(
a,b: in bit;
z: out bit
);
1.2.2 结构体
作用:定义系统(或模块)的行为、元件及内部的连接关系,即描述其逻辑功能。
两个组成部分:
- 结构体说明:对数据类型、常数、信号、子程序、元件等元素的说明部分。
- 结构体功能描述:以各种不同的描述风格描述的系统的逻辑功能部分。常用的描述风格有:行为描述、数据流描述、结构化描述。
实体与结构体的关系:
一个设计实体可有多个结构体,代表实体的多种实现方式。各个结构体的地位相同。
结构体的语法:
architecture 结构体名称 of
实体名称 is
[说明语句]内部信号、常数、数据类型、子程序(函数、过程)、元件等的说明;begin
[并行处理(功能描述)语句];
end [architecture] 结构体名称;
注:同一实体的结构体不能同名。定义语句中的常数、信号不能与实体中的端口同名。
例:一个完整描述(3bit计数器)
采用out形式
entity counter3 is
port(clk, reset: in bit;
count: out integer range 0 to 7);
end counter3
architecture my_arch of counter3 is
signal count_tmp: integer range 0 to 7;
begin
process begin
wait until (clk'event and clk='1');
if reset='1' or count_tmp=7 then
count_tmp<=0;
else
count_tmp<=count_tmp+1;
end if
end process;
count<=count_tmp;
end my_arch;
采用buffer形式
entity counter3 is
port(clk, reset: in bit;
count: buffer integer range 0 to 7);
end counter3
architecture my_arch of counter3 is
begin
process begin
wait until (clk'event and clk='1');
if reset='1' or count=7 then
count<=0;
else
count<=count+1;
end if
end process;
end my_arch;
1.2.3 配置
配置:从某个实体的多种结构体描述方式中选择特定的一个。
简单配置的语法:
configuration 配置名of 实体名 is
for 选配结构体名
end for;
end 配置名;
例:一个与非门不同实现方式的配置如下:
library ieee;
use ieee. std_logic_1164.all;
entity nand is
port(a: in std_logic;
b: in std_logic;
c: out std _logic);
end entity nand;
architecture art1 of nand is
begin
c<=not(a and b);
end arehitecture art1;
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;
configuration first of nand is
for art1
end for;
end first;
configuration second of nand is
for art2
end for;
end second;
例:一个对计数器实现多种形式的配置如下:
entity counter is
port(clear,clk:in bit;
date_out:out integer);
end counter;
architecture count_255 of counter is --8 bit counter
begin
process(clk)
variable count:integer:=0;
begin
if clear='1' then count:=0;
-- 判断上升沿的一种标准格式
elsif clk'event and clk='1' then
if count=255 then
count:=0;
else
count:=count+1;
end if;
end if;
data _out<=count;
end process
end count_255;
architecture count_64k of counter is --16 bit counter
begin
process(clk)
variable count:integer:=0;
begin
if clear='1' then
count:=0;
elsif clk'event and clk='1' then
if count=65535 then
count:=0;
else
count:=count+1;
end if;
end if;
data_out<=count;
end process;
end count_64k;
configuration small_count of counter is
for count_255
end for;
end small_count;
configuration big_count of counter is
for count_64k
end for;
end big_count;
1.2.4 程序包、库
- 程序包:已定义的常数、数据类型、元件调用说明、子程序的一个集合。
目的:方便公共信息、资源的访问和共享。 - 库:多个程序包构成库。
- 程序包的结构包括:程序包说明(包首)程序包主体(包体)
- 程序包说明的内容:常量说明;VHDL数据类型说明;元件说明;子程序说明;
1.2.4.1 程序包说明(包首)语法:
package 程序包名 is
{包说明项}
end 程序包名;
包声明项可由以下语句组成:
use语句(用来包括其它程序包);类型说明;子类型说明;常量说明;信号说明;子程序说明;元件说明。
例:程序包说明
package example is
type byte is range 0 to 255;
subtype nibble is byte range 0 to 15;
constant byte_ff:byte:=255;
signal addend:nibble;
-- 元件说明
component byte_adder
port(a,b:in byte;
c:out byte;
overflow:out boolean);
end component;
function my_function(a:in byte)
return byte;
end example;
1.2.4.2 程序包包体
程序包的内容:子程序的实现算法。
包体语法:
package body 程序包名 is
{包体说明项}
end 程序包名;
包体说明项可含:
use 语句;子程序说明;子程序主体(包体比包首多出来的);类型说明;子类型说明;常量说明。
包体主要完成子程序主体的算法描述部分,若没有子程序说明这一项,则子程序主体不是必须的。
程序包首与程序包体的关系:
程序包体并非必须,只有在程序包中要说明子程序时,程序包体才是必须的。
程序包首可以独立定义和使用。如下:
package seven is
subtype segments is bit_vector(0 to 6);
type bcd is range 0 to 9;
end seven;
-- 用户定义完程序包后要进行编译,编译结果会自动放在work库
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 arehitecture art;
1.2.4.3 库的种类
VHDL库可分为5种:
- 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 function)
Type STD_LOGIC
9 logic value system('U','X','0','1','Z','W', 'L','H','-')
'W','L','H' weak values(Not supported by Synthesis)
'X'-(not'x')used for unknown
'Z'-(not 'z')used for tri-state
'-' Don't Care
- STD库(默认库)
库中程序包为:standard,定义最基本的数据类型:Bit,bit_vector,Boolean,Integer,Real and Time
注:Type BIT: 2 logic value system(‘0’, ‘1’) - 面向ASIC的库
- WORK库(默认库)
- 用户定义库
STD库和WORK库都是默认库,自动调用
1.2.4.4 库及程序包的使用
库及程序包的说明总是放在实体单元前面,默认库及程序包可不作说明。用关健字library说明要使用的库,用关健字use说明要使用的库中的程序包。
库及程序包的作用范围:仅限于所说明的设计实体。
每一个设计实体都必须有自已完整的库及程序包说明语句。
库的使用语法:
library 库名;
程序包的使用有两种常用格式:
use 库名.程序包名.项目名;
use 库名.程序包名.all;
例:
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.conv_integer;
2选1选择器的VHDL描述
-- 库和程序包的调用
library ieee;
use ieee. std _logic_1164.all;
-- 端口信息
entity mux2l is
port(a,b: in std_logic;
s: in std_logic;
y: out std_logic);
end mux21;
-- 结构体部分
architecture max_arch of mux21 is
begin
y<=a when s='0' else
b when s='1';
end mux_arch;
2选1选择器的另一种VHDL描述
-- 默认库和程序包
entity mux2l is
port(a,b: in bit;
s: in bit;
y: out bit);
end mux21;
architecture max_arch of mux21 is
begin
y<=a when s='0' else
b when s='1';
end mux_arch;