第6章 VHDL程序设计.docx
《第6章 VHDL程序设计.docx》由会员分享,可在线阅读,更多相关《第6章 VHDL程序设计.docx(41页珍藏版)》请在冰点文库上搜索。
第6章VHDL程序设计
第六章:
VHDL程序设计
§6.1VHDL描述风格
·描述风格:
VHDL的构造体用于描述整个设计实体的逻辑功能。
对于相同的电路功能行为,可以用不同的描述方式来表达;对于相同的逻辑行为,可以用不同的语句来描述。
·类型:
行为描述;
寄存器传递(数据流)描述;
结构描述。
1.行为描述方式
·含义:
是对系统数学模型的描述。
·特点:
①只表示输入与输出间转换的行为,而不包含任何结构信息;
②主要使用函数、过程和进程语句,以算法形式描述数据的变换和传送;
③比寄存器传递和结构描述具有更高的抽象性;
④行为描述是VHDL编程的核心,可以说,没有行为描述就没有VHDL。
⑤通常不能直接进行逻辑综合,需要转化成RTL描述或结构描述。
·用途:
主要用于系统数学模型的仿真或系统工作原理的仿真。
[例6-1]用行为描述方式描述“二选一”电路功能。
LIBRARYIEEE;
USEIEEE.STD_LOGIC_1164.ALL;i0
USEIEEE.STD_LOGIC_UNSIGNED.ALL;
ENTITYmux2ISi1q
PROT(i0,i1,sel:
INSTD_LOGIC;
q:
OUTSTD_LOGIC);sel
ENDmux2;
ARCHITECTUREbehavOFmux2IS
BEGIN
CASEselIS
WHEN0=>q<=i0AFTER10ns;
WHEN1=>q<=i1AFTER10ns;
WHENOTHERS=>q<=’X’AFTER10ns;
ENDCASE
ENDbehav;
2.寄存器传递描述(RTL)方式
·含义:
是一种明确规定寄存器描述的方法。
·分类:
①采用寄存器之间的功能描述(类似行为描述);
②采用寄存器硬件直接描述(一一对应)。
·特点:
①RTL功能描述编程效率高、难度低,但可用的VHDL语句受限;②RTL硬件描述编程难度大、要求高,但可用的VHDL语句多。
[例6-2]用RTL硬件方式描述“二选一”电路功能。
LIBRARYIEEE;
USEIEEE.STD_LOGIC_1164.ALL;
USEIEEE.STD_LOGIC_UNSIGNED.ALL;
ENTITYmux2IS
PROT(i0,i1,sel:
INSTD_LOGIC;
q:
OUTSTD_LOGIC);
ENDmux2;
ARCHITECTURErtlOFmux2IS
SIGNALtemp1,temp2,temp3,:
STD_LOGIC;
BEGIN
Temp1<=i0ANDsel;
Temp2<=i1AND(NOTsel);
Temp3<=temp1ORtemp2;
q<=temp3;
ENDrtl;
3.结构描述方式
·含义:
在分层设计中,通过高层次的设计模块调用低层次的设计模块来构成一个复杂的逻辑电路的描述方法。
·特点:
①结构清晰,与硬件层层对应,如:
系统→板→元件;
②设计效率高,可方便地将已有设计成果用到新的设计中。
[例6-3]用结构描述方式描述“二选一”电路功能。
U3
d0aa
U4
U2
d1U1bbq
nsel
sel
LIBRARYIEEE;
USEIEEE.STD_LOGIC_1164.ALL;
USEIEEE.STD_LOGIC_UNSIGNED.ALL;
ENTITYmux2IS
PROT(d0,d1,sel:
INBIT;
q:
OUTBIT);
ENDmux2;
ARCHITECTUREstructOFmux2IS
COMPONENTand2
PROT(a,b:
INBIT;
c:
OUTBIT);
ENDCOMPONET;
COMPONENTor2
PROT(a,b:
INBIT;
c:
OUTBIT);
ENDCOMPONET;
COMPONENTinv
PROT(a:
INBIT;
c:
OUTBIT);
ENDCOMPONET;
SIGNALaa,bb,nsel:
BIT;
BEGIN
U1:
invPORTMAP(sel,nsel);
U2:
and2PORTMAP(d1,nsel,bb);
U3:
and2PORTMAP(d0,sel,aa);
U4:
or2PORTMAP(aa,bb,q);
ENDstruct;
说明:
①COMPONENT语句用来说明在该电路中所使用的已生成的模块and2,…;
②PORTMAP()语句将已生成模块的端口与所设计的各模块U1,U2…的端口连接起来。
§6.2组合逻辑电路设计
1.基本门电路
[例6-4]用VHDL程序描述二输入“异或”门电路。
LIBRARYIEEE;
USEIEEE.STD_LOGIC_1164.ALL;
ENTITYxor2IS
PORT(a,b:
INSTD_LOGIC;
y:
OUTSTD_LOGIC);
ENDxor2;
ARCHITECTURExor2_1OFxor2IS
BEGIN
y<=aXORb;
ENDxor2_1;
[例6-5]用VHDL程序描述二输入“异或”门电路。
LIBRARYIEEE;
USEIEEE.STD_LOGIC_1164.ALL;
ENTITYxor2IS
PORT(a,b:
INSTD_LOGIC;
y:
OUTSTD_LOGIC);
ENDxor2;
ARCHITECTURExor2_2OFxor2IS
BEGIN
PROCESS(a,b)
VARIABLEcomb:
STD_LOGICVECTOR(1DOWNTO0);
BEGIN
Comb:
=a&b;
CASEcombis
WHEN“00”=>y<=’0’;
WHEN“01”=>y<=’1’;
WHEN“10”=>y<=’1’;
WHEN“11”=>y<=’0’;
WHENOTHERS=>y<=’X’;
ENDCASE;
ENDPROCESS;
ENDxor2_2;
2.加法器
(1)半加器
真值表电路符号
二进制输入和进位
basco
as
0000
0110bco
1010
1101
逻辑表达式:
S=(a+b)·/(a·b)
C0=/(a·b)
[例6-6]用VHDL程序描述半加器电路功能。
LIBRARYIEEE;
USEIEEE.STD_LOGIC_1164.ALL;
ENTITYhalf_adderIS
PORT(a,b:
INSTD_LOGIC;
s,co:
OUTSTD_LOGIC);
ENDhalf_adder;
ARCHITECTUREhalf1OFhalf_adderIS
SIGNALc,d:
STD_LOGIC;
BEGIN
c<=aORb;
d<=aNANDb;
s<=cANDd;
co<=NOTd;
ENDhalf1;
(2)全加器
[例6-7]用VHDL程序描述全加器电路功能。
u1
ciu1_ss
u0
au0_su1_co
co
bu0_co
分析:
·用两个半加器构成一个全加器;
·原理电路图示意;:
·采用元件例化语句COMPONET---PORTMAP()。
LIBRARYIEEE;
USEIEEE.STD_LOGIC_1164.ALL;
ENTITYfull_adderIS
PORT(a,b,ci:
INSTD_LOGIC;
s,co:
OUTSTD_LOGIC);
ENDfull_adder;
ARCHITECTUREfull1OFfull_adderIS
COMPONENThalf_adder
PORT(a,b:
INSTD_LOGIC;
s,co:
OUTSTD_LOGIC);
ENDCOMPONENT;
SIGNALu0_s,u0_co,u1_s,u1_co:
STD_LOGIC;
BEGIN
U0:
half_adderPORTMAP(a,b,u0_s,u0_co);
U1:
half_adderPORTMAP(ci,u0_s,u1_s,u1_co);
s<=u1_s;
co<=u0_coORu1_co;
ENDfall1;
3.其它
编码器(优先级)/译码器(3-8)/选择器(四选一)/缓冲器(单/双)等
(自学)
§6.3时序电路设计
1.时钟信号
(1)含义:
周期性系列脉冲
(2)作用:
是描述时序电路的VHDL程序执行的条件。
(3)描述方式:
以进程的形式描述时序电路。
1时钟信号是进程的敏感信号
如:
PROCESS(clk_signal)
BEGIN
IF(clock_edge_condition)THEN
Signal_out<=signal_in
…
ENDIF;
ENDPROCESS;
2时钟信号是进程中的激活信号
如:
PROCESS
BEGIN
WAITON(clock_signal)UNTIL(clock_edge_condition)
Signal_out<=signal_in
…
ENDPROCESS;
(4)边沿触发
1上升沿clk=’1’
·图形描述:
clk’EVENT
clk’LAST_VALUE=’0’
·语句描述:
IFclk=’1’ANDclk’LAST_VALUE=’0’ANDclk’EVENT;
2下升沿clk’LAST_VALUE=’1
clk’EVENT
·图形描述:
clk=’0’
·语句描述:
IFclk=’0’ANDclk’LAST_VALUE=’1’ANDclk’EVENT;
2.复位信号
(1)类型:
·同步复位:
当复位信号有效且给定时钟边沿到来时,触发器才被复位。
·非同步复位(异步复位):
一旦复位信号有效,触发器就被复位。
(2)描述方式:
1同步复位:
一定在以时钟为敏感信号的进程中定义,且用IF语句来描述必要的复位条件。
如:
PROCESS(clock_signal)
BEGIN
IF(clock_edge_condition)THEN
IF(reset_condition)THEN
Signal_out<=reset_value;
ELSE
Signal_out<=signal_in;
…
ENDIF;
ENDIF;
ENDPROCESS;
2异步复位:
在进程的敏感信号中,时钟和复位信号同时存在,用IF语句描述复位条件,用ELSE语句描述时钟事件。
如:
PROCESS(reset_signal,clock_signal)
BEGIN
IF(reset_condition)THEN
Signal_out<=reset_value;
ELSIF(clock_eventANDclock_edge_condition)THEN
Signal_out<=signal_in;
…
ENDIF;
ENDPROCESS;
说明:
若没有ELSIF语句,当复位信号变化但复位条件不满足时…。
3.触发器
[例6-8]用VHDL程序描述D触发器功能
LIBRARYIEEE;
USEIEEE.STD_LOGIC_1164.ALL;
ENTITYdff1IS
PROT(d,clk:
INSTD_LOGIC;
q:
OUTSTD_LOGIC);
ENDdff1;
ARCHITECTURErtlOfdff1IS
BEGIN
PROCESS(clk)
BEGIN
IF(clk=’1’)AND(clk’EVENT)THEN
q<=d;
ENDIF;
ENDPROCESS
ENDrtl;
讨论:
①本例是一个上升沿触发的D触发器程序;
②若改为下降沿触发:
clk’EVENTANDclk=’1’→clk=’0’
③若改用WAIT语句、上升沿触发:
IF→WAITUNTILclk’EVENTANDclk=’1’
④若改用WAIT语句、下降沿触发:
IF→WAITUNTILclk’EVENTANDclk=’0’
[例6-9]用VHDL程序描述异步置位/复位锁存器功能
LIBRARYIEEE;
USEIEEE.STD_LOGIC_1164.ALL;
ENTITYdffcsIS
PROT(d,clk,clr,set:
INSTD_LOGIC;
q:
OUTSTD_LOGIC);
ENDdffcs;
ARCHITECTURErtlOfdffcsIS
BEGIN
PROCESS(clk,clr,set)
BEGIN
IF(clr=’0’)THEN
Q<=’0’;
ELSIF(SET=’0’)THEN
Q<=’1’;
ELSIF(clk’EVENTANDclk=’1’)THEN
Q<=d;
ENDIF;
ENDPROCESS
ENDrtl;
[例6-10]用VHDL程序描述J-K触发器功能
LIBRARYIEEE;
USEIEEE.STD_LOGIC_1164.ALL;
ENTITYjkffIS
PROT(j,k,clk,clr,set:
INSTD_LOGIC;
Q,qb:
OUTSTD_LOGIC);
ENDjkff;
ARCHITECTURErtlOfjkffIS
SIGNALq_s,qb_s:
STD_LOGIC;
BEGIN
PROCESS(clk,clr,set,j,k)
BEGIN
IF(clr=’0’)AND(set=’1’)THEN
Q_s<=’0’;
Qb_s<=’1’;
ELSIF(clr=’1’)AND(set=’0’)THEN
Q_s<=’1’;
Qb_s<=’0’;
ELSIF(clk’EVENTANDclk=’1’)THEN
IF(j=’0’)AND(k=’1’)THEN
Q_s<=’0’;
Qb_s<=’1’;
ELSIF(j=’1’)AND(k=’0’)THEN
Q_s<=’1’;
Qb_s<=’0’;
ELSIF(j=’1’)AND(k=’1’)THEN
Q_s<=NOTq_s;
Qb_s<=NOTqb_s;
ELSE
Q_s<=q_s;
Qb_s<=qb_s;
ENDIF;
Q<=q_s;
Qb<=qb_s;
ENDPROCESS
ENDrtl;
4.寄存器
[例6-11]用VHDL语言设计一硬件电路,实现8位并入/并出移位寄存器循环左移3位。
分析:
①电路符号
dout(0)
(1)dout(7)
s(0)enb
s
(1)
s
(2)clk
Din(0)
(1)din(7)
其中:
din(0)~din(7):
8个数据输入端;
dout(0)~dout(7):
8个数据输出端;
s(0)~s
(2):
移位位数控制输入端;
enb:
移位/数据输出控制端;
当enb=‘1’时,移位寄存器椐s(0)~s
(2)输入的数据确定循环左移的位数;
当enb=‘0’时,输出dout=din
clk:
移位时钟输入端。
②工作原理
sc=3位(左移)
din(7)din(0)
MSBLSB
······
MSBLSB
Dout(7)dout(0)
③首先设计一个8位循环左移寄存器过程,以供其他调用;
④调用上述过程,设计一8位并入/并出移位寄存并循环左移3位。
※※用VHDL语言设计一循环左移“shift过程”
LIBRARYIEEE;
USEIEEE.STD_LOGIC_1164.ALL;
USEIEEE.STD_LOGIC_ARITH.ALL;
USEIEEE.STD_LOGIC_UNSIGNED.ALL;
PACKAGECPACIS
PROCEDUREshift(din,s:
INSTD_LOGIC_VECTOR;
SIGNALdout:
OUTSTD_LOGIC_VECTOR);
ENDCPAC;
PACKGEBODYCPACIS
PROCEDUREshift(din,s:
INSTD_LOGIC_VECTOR;-过程名(参数)
SIGNALdout:
OUTSTD_LOGIC_VECTOR)IS
VARIABLEsc:
INTEGER;--定义变量
BEGIN
SC:
=CONV_INTEGER(S);---位矢量→整数
FORIINdin’RANGELOOP
IF(sc+i<=din’LEFT)THEN---3+I<=7
Dout(sc+I)<=din(i);--左边5位处理
ELSE
dout(sc+I-din’LEFT-1)<=din(i);--右边3位处理
ENDIF;
ENDLOOP;
ENDshift;
ENDCPAC;
※※用VHDL语言通过调用上面程序包中的“shift过程”,实现3位循环左移。
LIBRARYIEEE;
USEIEEE.STD_LOGIC_1164.ALL;
USEWORK.CPAC.ALL;
ENTITYbsrIS
Port(din:
INSTD_LOGIC_VECTOR(7DOWN0);
S:
INSTD_LOGIC_VECTOR(2DOWN0);
Dout:
OUTSTD_LOGIC_VECTOR(7DOWN0);
Clk,enb:
INSTD_LOGIC);
ENDbsr;
ARCHITECTURErtlOFbsrIS
BEGIN
PROCESS(clk)
BEGIN
IF(clk’EVENTANDclk=’1’)THEN
IF(enb=’0’)THEN
Dout<=din;
ELSE
Shift(din,s,dout);---调用程序包CPAC中的“shift过程”
ENDIF;
ENDIF;
ENDPROCESS;
ENDrtl;
5.计数器
·分类:
同步:
在计数时钟控制下,构成计数器的各触发器状态同步发生变化;
异步:
低位计数输出作为高一位计数器的时钟信号,一级一级串行连接。
[例6-12]用VHDL语言设计一六十进制计数器。
分析:
①用一个六进制和一个十进制计数器连接起来→60进制计数器
②电路引脚图
clk
datain(0)
(1)
(2)
(3)
bcd1(0)
bcd1w
(1)
(2)
(3)
bcd10(0)
cin
(1)
bcd10w
(2)
con
③引脚说明:
clk:
时钟输入
bcd1w:
个位置数控制端
bcd10w:
十位置数控制端
cin:
个位向十位进位输入端
con:
十位进位输出端
datain(0)~(3):
个位/十位预制数据输入端
bcd1(0)~(3):
个位数据输出端
bcd10(0)~(3):
十位数据输出端(最大为5)
④工作原理:
·bcd1w和bcd10w与datain(0)~(3)配合完成个位和十位预置数。
因公用一组输入数据线,所以分别用两个进程串行完成;
·用三个进程分别处理个位、十位计数和进位处理。
VHDL语言源程序
LIBRARYIEEE;
USEIEEE.STD_LOGIC_1164.ALL;
USEIEEE.STD_LOGIC_UNSIGNED.ALL;
ENTITYbcd60countIS
Port(clk,bcd1w,bcd10w,cin:
INSTD_LOGIC;
co:
OUTSTD_LOGIC;
Datain:
INSTD_LOGIC_VECTOR(3DOWN0);
Bcd1:
OUTSTD_LOGIC_VECTOR(3DOWN0);
Bcd10:
OUTSTD_LOGIC_VECTOR(2DOWN0));
ENDbcd60count;
ARCHITECTURErtlOFbcd60countIS
SIGNALbcd1n:
STD_LOGIC_VECTOR(3DOWN0);
SIGNALbcd10n:
STD_LOGIC_VECTOR(2DOWN0);
BEGIN
Bcd1<=bcd1n;
Bcd10<=bcd10n;
PROCESS(clk,bcd1w)---个位置数/计数
BEGIN
IF(bcd1w=’1’)THEN
Bcd1n<=datain;
ELSIF(clk’EVENTANDclk=’1’)THEN
IF(cin=’1’)THEN----加1计数
IF(bcd1n=’9’)THEN
Bcd1n<=”0000”;
ELSE
Bcd1n<=bcd1n+1;
ENDIF;
ENDIF;
ENDIF;
ENDPROCESS;
PROCESS(clk,bcd10w)---十位置数/计数
BEGIN
IF(bcd10w=’1’)THEN
Bcd10n