VHDL设计方法大纲1.docx
《VHDL设计方法大纲1.docx》由会员分享,可在线阅读,更多相关《VHDL设计方法大纲1.docx(26页珍藏版)》请在冰点文库上搜索。
VHDL设计方法大纲1
VHDL设计方法
—用VHDL语言实现可编程数字系统设计
●VHDL概述
●VHDL的设计单元
●VHDL的基本语法结构
第一部分VHDL概述
VHDL的含义
VHSIC(VeryHighSpeedIntegratedCircuit)
Hardware
Description
Language
VHDL特点
●与其他的硬件描述语言相比,VHDL具有更强的行为描述能力
●VHDL丰富的仿真语句和库函数,使得在设计的早期就能查验设计系统的功能可行性,随时可对设计进行仿真模拟
●VHDL语句的行为描述能力和程序结构决定了他具有支持大规模设计的分解和已有设计的再利用功能
●对于用VHDL完成的一个确定的设计,可以利用EDA工具进行逻辑综合和优化,并自动的把VHDL描述设计转变成门级网表
●VHDL对设计的描述具有相对独立性,设计者可以不懂硬件的结构,也不必管理最终设计实现的目标器件是什么,而进行独立的设计
VHDL与其他HDL比较
●VHDL
—“告诉我你想要电路做什么,我给你提供能实现这个功能的硬件电路”
●Verilog
—和VHDL类似
●ABEL、AHDL
—“告诉我你想要什么样的电路,我给你提供这样的电路”
典型的综合流程
典型的仿真流程
第二部分VHDL的设计单元
VHDL的设计单元
●Entity(实体)
用来说明模型的外部输入输出特征
●Architecture(构造体)
用来定义模型的内容和功能
●每一个构造体必须有一个实体与它相对应,所以两者一般成对出现
实体
●类似一个“黑盒”,实体描述了“黑盒”的输入输出口
实体举例
ENTITYblack_boxIS
Generic(constantwidth:
integer:
=7;);
PORT(
clk,rst:
INstd_logic;
d:
INstd_logic_vector(widthDOWNTO0);
q:
OUTstd_logic_vector(widthDOWNTO0);
co:
OUTstd_logic);
ENDblack_box;
Generic
●类属参量
一种端口界面常数,用来规定端口的大小、实体中子元件的数目等
●与常数不同,常数只能从内部赋值而类属参量可以由实体外部赋值
●数据类型通常取Integer或Time
●综合器仅支持数据类型为整数的类属值。
PORTS
●端口(PORT)是实体的一部分
–PORT类似于器件的管脚,主要用于信号的传输
–PORT一般有Name,Mode,和Type
●端口说明格式
PORT
([SIGNAL]Name:
ModeType[BUS]
[:
=表达式],…)
端口类型
IN:
数据只能从端口流入实体
OUT:
数据只能从端口流出实体
INOUT:
数据从端口流入或流出实体
BUFFER:
数据从端口流出实体,同时可被内部反馈
数据类型
●BIT:
位类型,其值只能为‘0’或‘1’
●BIT_VECTOR:
位矢量类型,包含一组位类型
●BOOLEAN:
布尔类型,其值可为‘TRUE’或‘FALSE’
●INTEGER:
整型,范围为-214783647到214783647(232),综合时,要对范围加以限制。
常用于循环语句的循环次数、常量、数学函数或模式仿真
●Natural:
自然数类型,整型的子类型,含零和正整数
●Positive:
正整数类型,整型的子类型,含非零和非负整数
●REAL:
浮点类型,范围为:
-1.0E38到1.0E38很多综合器不支持该类型
●枚举类型:
用户定义的数据类型
例:
TYPEtraffic_lightIS(red,yellow,green)
TYPEintISRANGE0TO100
●数组类型:
分一维数组和二维数组,限定性和非限定性数组
例:
TYPEBit_VectorISARRAY(NaturalRANGE<>)OFBit;
TYPEWordISARRARY(31downto0)OFBit;
●SUBTYPE:
子类型,一般用来对其父类型加以限制
例:
SUBTYPEStd_LogicISresolvedStd_Ulogic
●TIME:
时间类型,范围和整型一样,表达时要包括数值和单位两部分。
单位包括:
fs、ps、ns、us、ms、sec、min、hr。
一般用于仿真
●记录类型
TYPEMonth_NameIS(Jan,Fab,Mar,Apr,May,Jun,Jul,Aug,Sep,Oct,Nov,Dec);
TYPEdateISRECORD
day:
IntegerRANGE1TO31;
month:
Month_Name;
year:
IntegerRANGE0to3000;
ENDRECORD;
VARIABLEtoday:
date;
today:
=(15,may,1995);
Std_Logic数据类型
●IEEE1164中定义的一种数据类型,它包含9种取值分别为:
‘U’未初始化用于仿真
’X’强未知用于仿真
’0’强0用于综合与仿真
’1’强1用于综合与仿真
’Z’高阻用于综合与仿真
’W’弱未知用于仿真
’L’弱0用于综合与仿真
’H’弱1用于综合与仿真
’_’忽略用于综合与仿真
●它是数字电路设计的工业标准逻辑类型
●它增加了VHDL语言编程、综合和仿真的灵活性
●在多值逻辑系统中STD_LOGIC和STD_LOGIC_VECTOR用于取代BIT和BIT_VECTOR
●若电路中有三态逻辑(Z)必须用STD_LOGIC和STD_LOGIC_VECTOR
●要使用这种类型代码中必须申明库和程序包说明语句LIBRARYieee;
USEieee.std_logic_1164.ALL;
构造体
●用来描述实体的内部结构和逻辑功能
●必须和实体(ENTITY)相联系
●一个实体(ENTITY)可以有多个构造体
●构造体的运行是并发的
●构造体描述方式包括:
—行为描述
—结构描述
—混合描述
实体和构造体之间的关系
构造体—行为描述举例
●2X8InputANDgate:
ENTITYblack_boxIS
PORT(a,b:
INstd_logic_vector(7DOWNTO0);
y:
OUTstd_logic_vector(7DOWNTO0));
ENDblack_box;
ARCHITECTUREexampleOFblack_boxIS
BEGIN
y<=aANDb;
ENDexample;
数据对象—常数
●指在设计中不会变的值
●改善代码可读性,便于代码修改
●必须在程序包、实体、构造体或进程的说明区域加以说明
●一般要赋一初始值
●保留字——CONSTANT
例:
CONSTANTWidth:
Integer:
=8
数据对象-信号
●可代表连线、内连元件、或端口
●用“<=”来给信号赋值
●SIGNAL
SIGNALCount:
Bit_Vector(3downto0);
IFRising_Edge(clk)THEN
Count<=Count+1;
ENDIF;
●信号在Package、Entity、Architecture中声明
信号举例
LIBRARYieee;
USEieee.std_logic_1164.all;
ENTITYsimpIS
PORT(a,b,c,d:
INStd_Logic;
g:
OUTStd_Logic);
ENDsimp;
ARCHITECTURElogicOFsimpIS
SIGNALe,f:
Std_Logic;
BEGIN
e<=aorb;
f<=not(cord);
g<=eandf;
ENDlogic;
信号赋值
●SIGNALtemp:
Std_Logic_Vector(7downto0);
●整体赋值:
temp<=“10101010”;
temp<=x”AA”;
●逐位赋值:
temp(7)<=‘1’;
●多位赋值:
●temp(7downto4)<=“1010”;
数据对象—变量
●仅用于进程和子程序
●必须在进程和子程序的说明性区域说明
●不能表达连线和存储元件
●保留字——VARIABLE
VARIABLEtmp:
Bit;
tmp:
=‘1’;
变量赋值
●整体赋值:
temp:
=“10101010”;
temp:
=x”AA”;
●逐位赋值:
temp(7):
=‘1’;
●多位赋值
temp(7downto4):
=“1010”;
信号和变量的作用范围
信号和变量的区别
算术运算符
关系运算符
逻辑运算符
其他运算符
运算优先级
**ABSNOT
*/MODREM
+正-负
+-&
SLLSLASRLSRAROLROR
=<=<>>=
ANDORNANDNORXORXNOR
运算重载
●若两信号类型不同,不能将一个信号的值赋给另一信号
●数据转换必须要用运算重载
●一般可用IEEE.1164中的标准重载函数实现
LIBRARYIEEE;
USEIEEE_Std_Logic_1164.all;
USEIEEE_Std_Logic_Arith.all;
USEIEEE_Std_Logic_unsigned.all
USEIEEE_Std_Logic_signed.all
并行语句
●VHDL语言与传统软件描述语言最大的不同
●有多种语句格式,包括:
并行信号赋值语句、进程语句、块语句、条件信号赋值语句、元件例化语句、生成语句、并行过程调用语句
●各种并行语句在结构体中的执行是同步进行的,或者说是并行运行的,其执行方式与书写的顺序无关。
●在执行中,并行语句之间可以有信息往来,也可以是互为独立、互不相关、异步运行的(如多时钟情况)。
●每一并行语句内部的语句运行方式可以有两种不同的方式,即并行执行方式(如块语句)和顺序执行方式(如进程语句)。
布尔表达式
●VHDL支持所有的标准逻辑运算符
●AND,OR,NOT,XOR,XNOR,NAND
●例:
x<=(aANDNOT(s
(1))ANDNOT(s(0)))OR
(bANDNOT(s
(1))ANDs(0))OR
(cANDs
(1)ANDNOT(s(0)))OR
(dANDs
(1)ANDs(0));
y<=aORbORc;
With_Select_When选择信号语句
●所有的“WHEN”子句必须是互斥的
●一般用“WhenOthers”来处理未考虑到的情况
●只有一个参考信号和赋值符(<=)
●每一子句结尾是逗号,最后一句是分号
WITHselection_signalSELECT
signal_name<=value_1WHENvalue_a,
value_2WHENvalue_b,
...
value_nWHENvalue_n,
value_xWHENOTHERS;
With_Select_When语句举例
LIBRARYieee;
USEieee.std_logic_1164.all;
ENTITYcmpl_sigIS
PORT(a,b,c,d,s:
INSTD_LOGIC;
x:
OUTSTD_LOGIC);
ENDcmpl_sig;
ARCHITECTURElogicOFcmpl_sigIS
BEGIN
WITHsSELECT
x<=aWHEN“00”,
bWHEN“01”,
cWHEN“10”,
dWHENOTHERS;
●每个WHEN子句可以包含多个条件:
WITHsSELECT
x<=aWHEN”000”|“001”|“010”,
bWHEN"101"|"111",
cWHENOTHERS;
When_Else选择信号语句
●根据指定条件对信号赋值,条件可以为任意表达式
●根据条件的出现的先后次序隐含优先权
●最后一个ELSE子句隐含了所有未列出的条件
●每一子句的结尾没有标点,只有最后一句有分号
signal_name<=value_1WHENcondition1ELSE
value_2WHENcondition2ELSE
...
value_nWHENconditionnELSE
value_x;
When_Else语句举例
x<=awhen(s=“00”)else
bwhen(s=“01”)else
cwhen(s=“10”)else
d;
j<=wwhen(a=‘1’)else
xwhen(b=‘1’)else
ywhen(c=‘1’)else
zwhen(d=‘1’)else
‘0’;
进程语句
●VHDL中最重要的语句,具有并行和顺序行为的双重性
●进程和进程语句之间是并行关系
●进程内部是一组连续执行的顺序语句
●进程语句与构造体中的其余部分进行信息交流是靠信号完成的
●基本格式:
[进程标号:
]PROCESS[(信号敏感表)]IS
〈说明区〉
BEGIN
〈顺序语句〉
ENDPROCESS[进程标号];
信号敏感表
●进程赖以启动的敏感表。
对于表中列出的任何信号的改变,都将启动进程,执行进程内相应顺序语句
●一些VHDL综合器,综合后,对应进程的硬件系统对进程中的所有输入的信号都是敏感的,不论在源程序的进程中是否把所有的信号都列人敏感表中
●为了使软件仿真与综合后的硬件仿真对应起来,应当将进程中的所有输人信号都列入敏感表中
顺序语句
●每一条顺序语句的执行(指仿真执行)顺序是与它们的书写顺序基本一致的
●顺序语句只能出现在进程(Process)、函数(Funcation)和过程(Procedure)中
●顺序语句包括:
赋值语句、流程控制语句、等待语句、子程序调用语句、返回语句、空操作语句
进程语句举例
LIBRARYieee;
USEieee.std_logic_1164.all;
ENTITYif_caseISPORT
(a,b,c,d:
INStd_Logic;
sel:
INStd_Logic_Vector(1downto0);
y,z:
OUTStd_Logic);
ENDif_case;
ARCHITECTURElogicOFif_caseIS
BEGIN
if_label:
PROCESS(a,b,c,d,sel)
BEGIN
IFsel="00"THENy<=a;
ELSIFsel="01"THENy<=b;
ELSIFsel="10"THENy<=c;
ELSEy<=d;
ENDIF;
ENDPROCESSif_label;
敏感表举例
latchlabel:
PROCESS(oe)
BEGIN
IFoe=‘1’THEN
y<=a;
ENDIF;
ENDPROCESSif_label;
latchlabel:
PROCESS(oe,a)
BEGIN
IFoe=‘1’THEN
y<=a;
ENDIF;
ENDPROCESSif_label;
顺序赋值语句举例
LIBRARYieee;
USEieee.std_logic_1164.all;
ENTITYttt1ISPORT
(en:
instd_logic;
y:
OUTStd_Logic_vector(0to7));
ENDttt1;
ARCHITECTURElogicOFttt1IS
SIGNALs1,s2:
Std_logic;
SIGNALt:
Std_Logic_vector(0to7);
BEGIN
PROCESS(s1,s2,en)
Variablev1,v2:
Std_logic;
Begin
ifen='1'then
V1:
='1';V2:
='1';
s1<='1';s2<='1';
t(0)<=v1;t
(1)<=v2;
t
(2)<=s1;t(3)<=s2;
v1:
='0';v2:
='0';
s2<='0';t(4)<=v1;
t(5)<=v2;t(6)<=s1;
t(7)<=s2;
endif;
Endprocess;
y<=t;
end;
在时序电路中的变量赋值
●变量在IF语句中被赋值,以用来表示随时钟的变化,不会产生触发器
●变量只代表临时存储,不反映实际硬件
●变量可用在表示一数据立即变化的表达式中,然后再将变量的值赋给信号
IF_THEN_ELSE语句
●只能在进程内使用
●至少应有一个条件句,条件句必须由布尔表达式构成。
●根据条件句产生的判断结果TRUE或FALSE,有条件地选择执行其后的顺序语句。
mux4_1:
PROCESS(a,b,c,d,s)
BEGIN
IFs=“00”THENx<=a;
ELSIFs=“01”THENx<=b;
ELSIFs=“10”THENx<=c;
ELSEx<=d;
ENDIF;
ENDPROCESSmux4_1;
ex1:
PROCESS(a,b)
BEGIN
IFa=‘1’THENc<=‘0’;--ifaandbare
ENDIF;--both‘1’then
IFb=‘1’THENc<=‘1’;--bhaspriority
ENDIF;--soc<=‘1’;
ENDPROCESSex1;
ex2:
PROCESS(a,b)
BEGIN
IFb=‘1’THENc<=‘1’;--ifaandbare
ENDIF;--both‘1’then
IFa=‘1’THENc<=‘0’;--ahaspriority
ENDIF;--soc<=‘0’;
ENDPROCESSex2;
CASE_WHEN语句
●表达式可以是一个整数类型或枚举类型的值,也可以是由这些数据类型的值构成的数组
●条件句中的选择值必在表达式的取值范围内。
●除非所有条件句中的选择值能完整覆盖CASE语句中表达式的取值,否则最末一个条件句中的选择必须用“OTHERS”表示。
●CASE语句中每一条件句的选择值只能出现一次,不能有相同选择值的条件语句出现。
●CASE语句执行中必须选中,且只能选中所列条件语句中的一条。
mux4_1:
PROCESS(a,b,c,d,s)
BEGIN
CASEsIS
WHEN"00"=>x<=a;
WHEN"01"=>x<=b;
WHEN"10”=>x<=c;
WHENOTHERS=>x<=d;
ENDCASE;
ENDPROCESSmux4_1;
LOOP语句
基本格式:
[LOOP标号:
]
[重复模式]LOOP
顺序语句;
ENDLOOP[LOOP标号]
组合电路举例
LIBRARYieee;
USEieee.std_logic_1164.ALL;
ENTITYcompareISPORT(
a,b:
INstd_logic_vector(0TO3);
aeqb:
OUTstd_logic);
ENDcompare;
ARCHITECTUREarchcompareOFcompareIS
BEGIN
aeqb<='1'WHENa=bELSE'0';
ENDarchcompare;
时序电路举例
LIBRARYieee;
USEieee.std_logic_1164.all;
ENTITYdff_aISPORT(d:
instd_logic;
clk:
instd_logic;
q:
outstd_logic);
ENDdff_a;
ARCHITECTUREbehaviorOFdff_aIS
BEGIN
PROCESS(clk)
BEGIN
IFclk'eventandclk='1'THENq<=d;
ENDIF;
ENDPROCESS;
ENDbehavior;
三态电路举例
ENTITYtest_threeIS
PORT(oe:
INstd_logic;
data:
OUTstd_logic_vector(0to7));
ENDtest_three;
ARCHITECTUREarchtest_threeOFtest_threeIS
BEGIN
PROCESS(oe)
BEGIN
IF(oe='1')THENdata<="01100100";
ELSEdata<="ZZZZZZZZ";ENDIF;
ENDPROCESS;
ENDarchtest_three;
双向口举例
ENTITYldcntIS
PORT(clk,ld,oe:
INstd_logic;
count:
INOUTstd_logic_vector(7DOWNTO0));
ENDldcnt;
ARCHITECTUREarchldcntOFldcntIS
SIGNALint_count:
std_logic_vector(7DOWNTO0);