




版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
EDA项目教程
——基于VHDL与FPGA项目5点阵广告牌的设计与实现本章要点
分频器的设计
寄存器的设计
点阵广告牌的设计与实现5.1分频器5.1.12N分频器2N(N为正整数)分频器是一种特殊的等占空比分频器,利用计数器计算时钟脉冲的个数,二进制计数器的最低位(20)就是时钟脉冲的2分频(一个时钟脉冲有效沿计为1,下一个时钟脉冲有效沿计为0,两个时钟脉冲有效沿构成一个周期)、次低位(21)就是4分频,依此类推,设计非常简单。1.设计题目设计一个可输出时钟脉冲2分频、4分频、8分频和16分频信号的分频电路,并使用QuartusⅡ进行仿真。2.实体的确定实体是设计外部电路的输入输出端口。根据设计题目分析,应该有1个时钟脉冲输入端和4个分频信号输出端。设时钟脉冲输入端为CLK,分频信号输出端分别为DIV2(2分频)、DIV4(4分频)、DIV8(8分频)和DIV16(16分频),数据类型都可以使用标准逻辑位类型(STD_LOGIC)。实体名为DIVF。实体的参考程序如下:ENTITYDIVFISPORT(CLK:INSTD_LOGIC;DIV2,DIV4,DIV8,DIV16:OUTSTD_LOGIC);ENDENTITYDIVF;3.结构体的确定结构体描述设计实体内部结构和实体端口之间的逻辑关系,是实体的一个组成单元。在结构体中设计一个计数器,定义一个四位临时信号存储计数值,信号的定义需要放在结构体的声明部分。参考程序如下:ARCHITECTUREARTOFDIVFISSIGNALQ:STD_LOGIC_VECTOR(4DOWNTO0);--定义临时信号QBEGINPROCESS(CLK)BEGINIFCLK'EVENTANDCLK='1'THEN--判断时钟脉冲的上升沿
Q<=Q+1;ENDIF;ENDPROCESS;DIV2<=Q(0);--输出2分频信号
DIV4<=Q(1);--输出4分频信号
DIV8<=Q(2);--输出8分频信号
DIV16<=Q(3);--输出16分频信号ENDARCHITECTUREART;4.库和程序包的确定由于实体中定义的信号类型不是VHDL默认类型,需要调用IEEE库中的STD_LOGIC_1164程序包;又由于结构体中使用了运算符“+”,需要调用IEEE库中的STD_LOGIC_UNSIGNED程序包,因此在实体的前面调用IEEE库,并使用这两个程序包。参考程序如下:LIBRARYIEEE;USEIEEE.STD_LOGIC_1164.ALL;USEIEEE.STD_LOGIC_UNSIGNED.ALL;5.波形仿真5.1.2偶数分频器偶数分频器的设计非常简单,通过计数器计数就完全可以实现。例如进行N(N为偶数)分频,就可以通过由待分频的时钟脉冲触发计数器计数,当计数器从0计数到(N/2)-1时,输出信号就进行翻转,形成半个周期,并给计数器清零,以便在下一个时钟脉冲有效沿到来时从零开始计数;当计数器又计到(N/2)-1时,输出信号再次翻转,形成另半个周期。以此循环,就可以实现任意的偶数分频。1.设计题目设计一个等占空比的六分频器,并使用QuartusⅡ进行仿真。2.实体的确定根据题目要求,等占空比的六分频器应该有1个时钟脉冲输入端、1个清零端和1个分频信号输出端。设时钟脉冲输入端为CLK、清零端为RESET、分频信号输出端为DIV6,数据类型都可以使用标准逻辑位类型(STD_LOGIC)。实体名为DIVSIX。实体的参考程序如下:ENTITYDIVSIXISPORT(CLK:INSTD_LOGIC;RESET:INSTD_LOGIC;DIV6:OUTSTD_LOGIC);ENDENTITYDIVSIX;3.结构体的确定
在结构体中设计一个计数器,由于是六分频(N=6),因此(N/2)-1=2,可定义1个信号count存储计数值;由于输出方向定义为OUT的信号DIV6不能出现在赋值语句的右侧,无法描述触发器的计数状态,需要设置1个临时信号CLKTEP,信号的定义需要放在结构体的声明部分。3.结构体的确定ARCHITECTUREARTOFdivsixISSIGNALcount:STD_LOGIC_VECTOR(1DOWNTO0);--计数值寄存器SIGNALclktemp:STD_LOGIC;--输出寄存器BEGINPROCESS(RESET,CLK)BEGINIFRESET='1'THEN--异步清零,高电平有效clktemp<='0';ELSIFRISING_EDGE(CLK)THEN--判断CLK
的上升沿3.结构体的确定IFcount="10"THENcount<="00";--计数到(N/2)-1(N=6)就清零clktemp<=NOTclktemp;--输出信号翻转,形成前
半个周期ELSEcount<=count+1;ENDIF;ENDIF;ENDPROCESS;DIV6<=clktemp;ENDARCHITECTUREART;4.库和程序包的确定由于实体中定义的信号类型不是VHDL默认类型,需要调用IEEE库中的STD_LOGIC_1164程序包;由于结构体中使用了运算符“+”,调用IEEE库中的STD_LOGIC_UNSIGNED程序包,因此需要在实体的前面调用IEEE库,并使用程序包。参考程序如下:LIBRARYIEEE;USEIEEE.STD_LOGIC_1164.ALL;USEIEEE.STD_LOGIC_UNSIGNED.ALL;5.波形仿真5.2寄存器的设计
寄存器是具有存储二进制数据功能的数字部件。寄存器分为基本寄存器和移位寄存器两类,基本寄存器只具有寄存数据的功能;移位寄存器除了具有存储二进制数据的功能以外,还具有移位功能。移位功能就是指寄存器里面存储的代码能够在时钟脉冲的作用下依次左移或右移,可以实现数据的串/并转换和数值运算。
5.2.1数据寄存器
1.题目要求利用QuartusⅡ软件的文本输入方式,设计一个具有三态输出的八位数码寄存器,完成编译和波形仿真后,下载到实验平台验证电路功能。
2.电路设计设d为数据输入端、oe为三态输出控制端(当oe=1时寄存器输出为高阻态;oe=0时为正常输出状态)、q为输出端。LIBRARYieee;USEieee.std_logic_1164.ALL;ENTITYregistISPORT(clk,oe:INstd_logic;d:INstd_logic_VECTOR(7DOWNTO0);q:BUFFERstd_logic_VECTOR(7DOWNTO0));ENDregist;ARCHITECTUREAOFregistISSIGNALqtemp:std_logic_VECTOR(7DOWNTO0);BEGINPROCESS(clk,oe)BEGINIFoe='0'THENIFclk'EVENTANDclk='1'THENqtemp<=d;ENDIF;ELSEqtemp<="ZZZZZZZZ";ENDIF;q<=qtemp;ENDPROCESS;ENDA;5.2.2循环移位寄存器
循环移位寄存器分为循环左移和循环右移两种,能够完成数码的逻辑运算。循环左移是数据由低位向高位移动,移出的高位又从低位端移入该寄存器,变成低位;循环右移是数据由高位向低位移动,移出的低位又从高位端移入该寄存器,变成高位。
1.题目要求利用QuartusⅡ软件的文本输入方式,设计一个五位循环左移寄存器,完成编译和波形仿真后,下载到实验平台验证电路功能。
2.电路设计设时钟输入端为CLK、并行数据输入端为DATA、数据加载控制端为LOAD、移位寄存器输出端为DOUT。LIBRARYIEEE;USEIEEE.STD_LOGIC_1164.ALL;USEIEEE.STD_LOGIC_UNSIGNED.ALL;ENTITYSHIFTREGISPORT(CLK,LOAD:INSTD_LOGIC;DATA:INSTD_LOGIC_VECTOR(4DOWNTO0);DOUT:BUFFERSTD_LOGIC_VECTOR(4DOWNTO0));ENDSHIFTREG;ARCHITECTUREaOFSHIFTREGISBEGINProcess(CLK)BEGINIFCLK'EVENTANDCLK='1'THENIFLOAD='1'THENDOUT<=DATA;ELSEDOUT(4DOWNTO1)<=DOUT(3DOWNTO0);DOUT(0)<=DOUT(4);ENDIF;ENDIF;ENDPROCESS;ENDa;5.2.3双向移位寄存器
双向移位寄存器可以在工作模式控制端的控制下,能够通过预置数据输入端输入并行数据,还能通过移位数据输入端输入串行数据,数据能从低位向高位移动,还能从高位移动到低位。
1.题目要求利用QuartusⅡ软件的文本输入方式,设计一个五位双向移位寄存器,完成编译和波形仿真后,下载到实验平台验证电路功能。
2.电路设计设时钟输入端为CLK、预置数据输入端为PRED、工作模式控制端为M(00是保持、01是右移、10是左移、11是预置数)、左移数据输入端为DSL、右移数据输入端为DSR、寄存器清零端为RESERT、移位寄存器输出端为DOUT。LIBRARYIEEE;USEIEEE.STD_LOGIC_1164.ALL;ENTITYDREGISPORT(CLK,RESERT,DSL,DSR:INSTD_LOGIC;M:INSTD_LOGIC_VECTOR(1DOWNTO0);PRED:INSTD_LOGIC_VECTOR(4DOWNTO0);DOUT:BUFFERSTD_LOGIC_VECTOR(4DOWNTO0));ENDDREG;ARCHITECTUREaOFDREGISBEGINProcess(CLK,RESERT)BEGINIFCLK'EVENTANDCLK='1'THENIFRESERT='1'THENDOUT<=(OTHERS=>'0');--相当于DOUT<=''00000''ELSEIFM(1)='0'THENIFM(0)='0'THENNULL;--NULL为空操作,保持ELSEDOUT<=DSR&DOUT(4DOWNTO1);--数据右移ENDIF;ELSIFM(0)='0'THENDOUT<=DOUT(3DOWNTO0)&DSL;--数据左移ELSEDOUT<=PRED;--预置数ENDIF;ENDIF;ENDIF;ENDPROCESS;ENDa;5.3.1用户自定义数据类型(1)枚举类型(ENUMERATED)
TYPE数据类型名IS(取值1,取值2,…);
这种数据类型应用广泛,可以用字符来代替数字,简化了逻辑电路中状态的表示。例如设计描述一周每一天状态的逻辑电路时,如果用数组000代表周一、001代表周二,依此类推,直到110代表周日。但这种表示方法对编写和阅读程序来说是不方便的。若改用枚举数据类型表示则方便得多,可以把一个星期定义成一个名为week的枚举数据类型:TYPEweekIS(Mon,Tue,Wed,Thu,Fri,Sat,Sun);这样,周一到周日就可以用Mon到Sun来表示,直观了很多。5.3.1用户自定义数据类型(2)数组类型(ARRAY)。TYPE数据类型名ISARRAY数组下标范围OF数组元素的数据类型;STANDARD程序包中预定义的整数类型表示范围是32位有符号的二进制数,这么大范围的数据之间的运算用硬件实现起来将消耗极大的资源,而应用中涉及的整数范围通常很小,例如一个数码管需要显示的数据仅为0~9。由于这个原因,VHDL使用整数时,要求用RANGE语句为定义的整数限定一个范围,VHDL综合器根据用户指定的范围在硬件中将整数用相应的二进制数据表示。用户自定义的整数类型可认为是STANDARD程序包中预定义整数类型的一个子类。其格式如下。TYPE整数类型名ISRANGE约束范围;例如用户定义一个用于数码管显示的数据类型,则可定义为:
TYPEdigitISRANGE0TO9;(3)用户自定义子类型SUBTYPE子数据类型名IS数据类型名RANGE数据范围;
数组类型是将相同类型的数据集合在一起所形成的数据类型,可以是一维的,也可以是多维的。数组类型定义格式如下:TYPE数据类型名ISARRAY数组下标范围OF数组元素的数据类型;
如果数据类型没有指定,则使用整数数据类型;如果用整数类型以外的其他类型,则需要在确定数据范围后加上数据类型名。例如:TYPEbusISARRAY(15DOWNTO0)OFBIT;数组名称为bus,共有16个元素,下标排序是15、14、…、1、0,各元素可分别表示为bus(15)、…、bus(0),数组类型为BIT。除了一维数组外,VHDL还可以定义二维、三维数组,例如定义一个16字、每字8位的RAM(随机存储器),可以定义为:TYPEram_16_8ISARRAY(0TO15)OFSTD_LOGIC_VECTOR(7DOWNTO0);5.3.1用户自定义数据类型
用户若对自己定义的数据作出一些限制,就形成了原自定义数据类型的子类型。对于每一个类型说明都定义了一个范围,一个类型说明与其他类型说明所定义的范围可以是不同的,在用VHDL对硬件描述时,有时一个对象可能取值的范围是某个类型定义范围的子集,这时就要用到子类型的概念。子类型的格式如下:SUBTYPE子数据类型名IS数据类型名RANGE数据范围;例如:在STD_LOGIC_VECTOR数据类型上所形成的子类型:SUBTYPEiobusISSTD_LOGIC_VECTOR(4DOWNTO0);
子类型可以对原数据类型指定范围而形成,也可以完全和原数据类型范围一致。子类型常用于存储器阵列等的数组描述场合。5.3.2数据类型间的转换程序包名称函数名称功能STD_LOGIC_1164TO_BIT由STD_LOGIC转换为BITTO_BITVECTOR由STD_LOGIC_VECTOR转换为BIT_VECTORTO_STDLOGIC由BIT转换为STD_LOGICTO_STDLOGICVECTER由BIT_VECTOR转换为STD_LOGIC_VECOTRSTD_LOGIC_ARITHCONV_INTEGER由UNSIGNED,SIGNED转换为INTEGERCONV_UNSIGNED由SIGNED,INTEGER转换为UNSIGNEDCONV_STD_LOGIC_VECTOR由INTEGER,UNSDGNED,SIGNED类型转换为
STD_LOGIC_VECTORSTD_LOGIC_UNSIGNEDCONV_INTEGER由STD_LOGIC_VECTOR转换为INTEGER5.3.2数据类型间的转换例如:把INTEGER数据类型的信号A转换为STD_LOGIC_VECTOR数据类型的信号B,程序如下:SIGNALA:INTEGERRANGER0TO15;--定义信号ASIGNALB:STD_LOGIC_VECTOR(3DOWNTO0);--定义信号BB<=CONV_STD_LOGIC_VECTOR(A);--调用转换函数注意:使用数据类型转换函CONV_STD_LOGIC_VECTOR,需要调用IEEE库中的STD_LOGIC_ARITH程序包。5.3.3元件例化语句1.元件声明语句(COMPONENT)格式如下:COMPONENT元件名
PORT元件端口说明(与该元件源程序实体中的PORT部分相同)ENDCOMPONENT;2.元件例化语句(PORTMAP)格式如下:例化名:元件名PORTMAP(元件端口对应关系列表);信号之间有位置映射和名称映射两种映射(关联)方式:(1)位置映射。就是被调用元件端口说明中信号的书写顺序及位置和PORTMAP语句中实际信号的书写顺序及位置一一对应。例如某元件的端口说明为:PORT(a,b:INBIT;c:OUTBIT);调用该元件时可使用:com1:u1PORTMAP(n1,n2,m);显然n1对应a,n2对应b,m对应c,com1是例化名,u1是元件名。(2)名称映射。就是将库中已有的模块的端口名称赋予设计中的信号名。上例可改为:com1:u1PORTMAP(a=>n1,b=>n2,c=>m);用元件例化语句
实现4位移位寄存器的设计根据题目要求,调用D触发器模块dff,并使用元件例化语句设计的程序如下:LIBRARYIEEE;USEIEEE.STD_LOGIC_1164.ALL;ENTITYshiftISPORT(DIN:INSTD_LOGIC;CP:INSTD_LOGIC;DOUT:OUTSTD_LOGIC_VECTOR(3DOWNTO0));ENDshift;ARCHITECTUREstrOFshiftISCOMPONENTdff--元件声明语句PORT(D:INSTD_LOGIC;CLK:INSTD_LOGIC;Q:OUTSTD_LOGIC);ENDCOMPONENT;SIGNALq:STD_LOGIC_VECTOR(4DOWNTO0);BEGINq(0)<=DIN;dff1:dffPORTMAP(q(0),CP,q(1));--位置映射dff2:dffPORTMAP(q(1),CP,q(2));dff3:dffPORTMAP(D=>q(2),CLK=>CP,Q=>q(3));--名称映射dff4:dffPORTMAP(D=>q(3),CLK=>CP,Q=>q(4));DOUT<=q(4DOWNTO1);ENDstr;4位移位寄存器仿真波形
从仿真波形中可以看出,在0~50ns区间,DIN=1,在CP(时钟)上升沿,DOUT=0001(移入数据“1”);在50~100ns区间,DIN=1,在CP上升沿,DOUT=0011(再次移入数据“1”)。其他区间的波形情况符合4位移位寄存器。5.3.4生成语句1.FOR工作模式的生成语句FOR工作模式常常用来进行
重复结构的描述,格式如下:[生成标号:]FOR循环变量IN取值范围GENERATE并行语句;ENDGENERATE[生成标号];2.IF工作模式的生成语句IF工作模式的生成语句常用来
描述带有条件选择的结构。格式如下:[生成标号:]IF条件GENERATE并行语句;ENDGENERATE[生成标号];LIBRARYIEEE;USEIEEE.STD_LOGIC_1164.ALL;ENTITYshiftforISPORT(DIN:INSTD_LOGIC;CP:INSTD_LOGIC;DOUT:OUTSTD_LOGIC_VECTOR(5DOWNTO0));ENDshiftfor;用FOR工作模式生成语句描述6位移位寄存器ARCHITECTUREstrOFshiftforISCOMPONENTdff--元件声明语句PORT(D:INSTD_LOGIC;CLK:INSTD_LOGIC;Q:OUTSTD_LOGIC);ENDCOMPONENT;SIGNALq:STD_LOGIC_VECTOR(6DOWNTO0);BEGINq(0)<=DIN;reg1:FORiIN0TO5GENERATE--FOR工作模式
生成语句dffx:dffPORTMAP(q(i),cp,q(i+1));--元件例化语句ENDGENERATEreg1;DOUT<=q(6DOWNTO1);ENDstr;LIBRARYIEEE;USEIEEE.STD_LOGIC_1164.ALL;ENTITYshift1ISPORT(d1:INSTD_LOGIC;cp:INSTD_LOGIC;d0:OUTSTD_LOGIC);ENDshift1;ARCHITECTUREstrOFshift1IS
COMPONENTdffPORT(d:INSTD_LOGIC;
clk:INSTD_LOGIC;q:OUTSTD_LOGIC);ENDCOMPONENT;用FOR和IF工作模式的生成语句描述8位移位寄存器SIGNALq:STD_LOGIC_VECTOR(7DOWNTO1);BEGINreg:FORiIN0TO7GENERATE--FOR工作模式生成语句g1:IFi=0GENERATE--IF工作模式生成语句dffx:dffPORTMAP(d1,cp,q(i+1));ENDGENERATE;g2:IFi=7GENERATEdffx:dffPORTMAP(q(i),cp,d0);ENDGENERATE;g3:IF((i/=0)AND(i/=7))GENERATE--IF语句
描述规则部分dffx:dffPORTMAP(q(i),cp,q(i+1));ENDGENERATE;ENDGENERATEreg;ENDstr;5.4.1LED点阵8行8列的LED点阵具有64个像素点,可以显示数字和一些比较简单的汉字。内部结构上由64个发光二极管组成,每个发光二极管是放置在行线和列线的交叉点上。5.4点阵显示的设计使用1088AS(共阴极)点阵的某一行,设计并实现一个能够异步复位的8路彩灯控制器,要求彩灯按照4种自动循环变化的花型闪烁。1.实体的确定分析设计题目,应该有1个时钟脉冲输入端、1个异步清零端和8个信号输出端。设时钟脉冲输入端为CLK、异步复位端为CLR;输出端口为LED。实体名为ledctrl。参考程序如下:ENTITYledctrlISPORT(CLKIN:INSTD_LOGIC;CLR:INSTD_LOGIC;LED:OUTSTD_LOGIC_VECTOR(7DOWNTO0));ENDENTITYledctrl;5.4.2彩灯控制器2.结构体的确定在结构体中定义4个常量(F1、F2、F3、F4),代表4种花型;自定义只有5种取值的枚举数组类型(STATE),用于记录当前的4种花型和1个高阻状态(复位状态),使用状态驱动,即用CASE语句判断“当前状态”并运行相应语句(某个花型),然后再将下一个状态赋值给“当前状态”;运行下一个状态对应的语句(另一个花型),再改变“当前状态”,利用状态的变化驱动程序不断运行。参考程序如下:ARCHITECTUREARTOFledctrlISTYPESTATEIS(S0,S1,S2,S3,S4);--自定义枚举数组类型STATESIGNALCURRSTATE:STATE;--定义STATE类型信号CURRSTATESIGNALFLOWER:STD_LOGIC_VECTOR(7DOWNTO0);BEGINPROCESS(CLR,CLKIN)ISCONSTANTF1:STD_LOGIC_VECTOR(7DOWNTO0):="01010101";--定义花型1CONSTANTF2:STD_LOGIC_VECTOR(7DOWNTO0):="00100100";--定义花型2CONSTANTF3:STD_LOGIC_VECTOR(7DOWNTO0):="11001100";--定义花型3CONSTANTF4:STD_LOGIC_VECTOR(7DOWNTO0):="11100010";--定义花型4BEGINIFCLR='1'THENCURRSTATE<=S0;--状态S0ELSIFRISING_EDGE(CLKIN)THENCASECURRSTATEISWHENS0=>--CURRSTATE=S0时,执行的语句FLOWER<="000000000000";CURRSTATE<=S1;--将CURRSTATE改为S1WHENS1=>FLOWER<=F1;--CURRSTATE=S1时,执行的语句CURRSTATE<=S2;--将CURRSTATE改为S2WHENS2=>FLOWER<=F2;CURRSTATE<=S3;WHENS3=>FLOWER<=F3;CURRSTATE<=S4;WHENS4=>FLOWER<=F4;CURRSTATE<=S1;--将CURRSTATE改为S1,实现循环运行ENDCASE;ENDIF;ENDPROCESS;LED<=FLOWER;ENDARCHITECTUREART;从仿真波形中可以看出,在0~50ns区间,CLR=1(异步复位有效),LED=00000000;在50~200ns区间,LED=00000000(状态S0);在250~350ns区间,LED=01010101(状态S1);在350~450ns区间,LED=001001001(状态S2)。其他区间的波形情况符合题意。想一想、做一做:改成按列显示,如何修改程序?彩灯控制器的仿真波形LED点阵可以显示汉字或字符,只是此时的汉字或字符应以点阵来表示,取点越多,汉字或字符越逼真,通常8行8列的点阵可以用来显示一些简单的汉字。把要显示的汉字用8位的二进制代码(对应点阵的行或列)来表示,这一过程称为取字模。
例如汉字“电”的十六进制字模为:10、7C、54、7C、54、7C、12、1E,其中“1”表示该点发光,“0”表示该点不发光。将字模赋值给点阵的每一列,在程序中采用逐行扫描的方法扫描点阵的每一行,使之轮流为低电平,于是每列字模的相应点被点亮。虽然汉字是逐行显示的,但由于人眼的视觉暂留,且只要扫描速度足够快,看到的还将是一个完整的汉字。
使用1088AS(共阴极)点阵设计并实现一个显示汉字“电”的电路,要求显示稳定、笔画完整。5.4.3汉字的显示
分析设计题目,点阵汉字的显示是多行、多列的显示,相当于数码管的动态显示。应该有1个时钟脉冲输入端、1个异步清零端、8个行信号输出端和8个列信号输出端。设时钟脉冲输入端为CLKIN、异步复位端为CLR;行信号输出端口为ROLED、列信号输出端口为COLED。文件名为ledword。参考程序如下:ENTITYledwordISPORT(CLKIN:INSTD_LOGIC;CLR:INSTD_LOGIC;ROLED,LEDCO:OUTSTD_LOGIC_VECTOR(7DOWNTO0));ENDENTITYledword;1.实体的确定
在结构体中定义8个常量(F0~F7),代表汉字字模;自定义只有9种取值的枚举数组类型(STATE),用于记录当前的汉字字模和1个高阻状态(复位状态)。字模赋值给行信号,列信号(低电平)决定显示字模某列。同样使用状态驱动。参考程序如下:ARCHITECTUREARTOFledwordISTYPESTATEIS(S0,S1,S2,S3,S4,S5,S6,S7,S8);SIGNALCURRSTATE:STATE;SIGNALtmproled,tmpledco:STD_LOGIC_VECTOR(7DOWNTO0);BEGINPROCESS(CLR,CLKIN)IS2.结构体的确定CONSTANTF0:STD_LOGIC_VECTOR(7DOWNTO0):="00010000";CONSTANTF1:STD_LOGIC_VECTOR(7DOWNTO0):="01111100";CONSTANTF2:STD_LOGIC_VECTOR(7DOWNTO0):="01010100";CONSTANTF3:STD_LOGIC_VECTOR(7DOWNTO0):="01111100";CONSTANTF4:STD_LOGIC_VECTOR(7DOWNTO0):="01010100";CONSTANTF5:STD_LOGIC_VECTOR(7DOWNTO0):="01111100";CONSTANTF6:STD_LOGIC_VECTOR(7DOWNTO0):="00010010";CONSTANTF7:STD_LOGIC_VECTOR(7DOWNTO0):="00011110";
BEGINIFCLR='1'THENCURRSTATE<=S0;tmpledco<="11111111";ELSIFRISING_EDGE(CLKIN)THENCASECURRSTATEISWHENS0=>tmproled<="00000000";CURRSTATE<=S1;WHENS1=>tmpledco<=F0;tmproled<="01111111";CURRSTATE<=S2;WHENS2=>tmpledco<=F1;tmproled<="10111111";CURRSTATE<=S3;WHENS3=>tmpledco<=F2;tmproled<="11011111";CURRSTATE<=S4;WHENS4=>tmpledco<=F3;tmproled<="11101111";CURRSTATE<=S5;WHENS5=>tmpledco<=F4;tmproled<="11110111";CURRSTATE<=S6;WHENS6=>tmpledco<=F5;tmproled<="11111011";CURRSTATE<=S7;WHENS7=>tmpledco<=F6;tmproled<="11111101";CURRSTATE<=S8;WHENS8=>tmpledco<=F7;tmproled<="11111110";CURRSTATE<=S1;ENDCASE;ENDIF;ENDPROCESS;ROLED<=tmproled;LEDCO<=tmpledco;ENDARCHITECTUREART;
由于实体中定义的STD_LOGIC信号类型不是VHDL默认类型,需要调用IEEE库中的STD_LOGIC_1164程序包,因此需要在实体的前面调用IEEE库,并使用该程序包。参考程序如下:LIBRARYIEEE;USEIEEE.STD_LOGIC_1164.ALL;3.库和程序包的确定从仿真波形中可以看出,在0~50ns区间,CLR=1(异步复位有效),LEDCO=FF、ROLED=00000000(状态S0);在150ns处,CLKIN上升沿右侧,LEDCO=10、ROLED=01111111(状态S1)。其他区间的波形情况符合题意。汉字显示控制的仿真波形
使用1088AS(共阴极)点阵设计并实现汉字“电”的滚动显示。要求:能够异步复位、汉字从下到上循环滚动显示。
把所有需显示的汉字或字符的字模从上往下依次排好,一方面用足够快的速度(即满足视觉暂留的频率)从上往下扫描整个点阵,显示该时刻所扫描的汉字或字符,即显示一个完整“画面”;另外,用一个较慢的速度每次从下往上移动一行,即将“画面”的首行移出,补充到“画面”的末行,这时将显示上方缺少首行、下方多个首行的“画面”。不断重复,视觉看上去就是滚动的效果了。5.4.4汉字的滚动显示
分析设计题目,与汉字显示相同,应该有1个时钟脉冲输入端、1个异步清零端、8个行信号输出端和8个列信号输出端。设时钟脉冲输入端为CLK、异步复位端为CLR;行信号输出端口为ROLED、列信号输出端口为COLED。文件名为rollword。参考程序如下:ENTITYrollwordISPORT(CLK:INSTD_LOGIC;CLR:INSTD_LOGIC;ROLED,LEDCO:OUTSTD_LOGIC_VECTOR(7DOWNTO0));ENDENTITYrollword;1.实体的确定结构体中定义4个进程:复位和慢速信号产生进程、稳定“画面”显示进程、行扫描进程、行递增计数进程,其中行递增计数进程由慢速信号驱动,用于滚动“画面”;其他进程由快速时钟驱动,用于显示稳定“画面”。参考程序如下:ARCHITECTUREARTOFrollwordISSIGNALtmproled,tmpledco:STD_LOGIC_VECTOR(7DOWNTO0);SIGNALrow,col,count:STD_LOGIC_VECTOR(2DOWNTO0);SIGNALCLKLOW:STD_LOGIC;BEGIN2.结构体的确定p0:PROCESS(CLR,CLK)IS--复位和慢速信号产生进程VARIABLEcnt:STD_LOGIC_VECTOR(9DOWNTO0);BEGINIFCLR='1'THENcnt:=(OTHERS=>'0'); col<="000";row<="000"; ELSIFRISING_EDGE(CLK)THEN cnt:=cnt+1;col<=col+1;row<=row+1; ENDIF; CLKLOW<=cnt(9);--慢速信号 ENDPROCESSp0;p1:PROCESS(CLK)IS--稳定“画面”显示进程CONSTANTF0:STD_LOGIC_VECTOR(7DOWNTO0):="00010000";CONSTANTF1:STD_LOGIC_VECTOR(7DOWNTO0):="01111100";CONSTANTF2:STD_LOGIC_VECTOR(7DOWNTO0):="01010100";CONSTANTF3:STD_LOGIC_VECTOR(7DOWNTO0):="01111100";CONSTANTF4:STD_LOGIC_VECTOR(7DOWNTO0):="01010100";CONSTANTF5:STD_LOGIC_VECTOR(7DOWNTO0):="01111100";CONSTANTF6:STD_LOGIC_VECTOR(7DOWNTO0):="00010010";CONSTANTF7:STD_LOGIC_VECTOR(7DOWNTO0):="00011110";VARIABLEtempcnt:STD_LOGIC_VECTOR(2DOWNTO0); BEGINIFRISING_EDGE(CLK)THEN tempcnt:=count+col;CASEtempcntISWHEN"000"=>tmpledco<=F0;WHEN"001"=>tmpledco<=F1;WHEN"010"=>tmpledco<=F2;WHEN"011"=>tmpledco<=F3;WHEN"100"=>tmpledco<=F4;WHEN"101"=>tmpledco<=F5;WHEN"110"=>tmpledco<=F6; WHEN"111"=>tmpledco<=F7;WHENOTHERS=>tmpledco<="00000000";ENDCASE; ENDIF;ENDPROCESSp1;p2:PROCESS(CLK)IS--行扫描进程BEGINIFRISING_EDGE(CLK)THENCASErowISWHEN"000"=>tmproled<="01111111";WHEN"001"=>tmproled<="10111111";WHEN"010"=>tmproled<="11011111";WHEN"011"=>tmproled<="11101111";WHEN"100"=>tmproled<="11110111";WHEN"101"=>tmproled<="11111011";WHEN"110"=>tmproled<="11111101"; WHEN"111"=>tmproled<="11111110";WHENOTHERS=>tmpledco<="11111111";ENDCASE; ENDIF;ENDPROCESSp2;P3:PROCESS(CLR,CLKLOW)IS--行递增计数进程VARIABLEcnt1:STD_LOGIC_VECTOR(2DOWNTO0);BEGINIFCLR='1'THENcnt1:=(OTHERS=>'0');ELSIFRISING_EDGE(CLKLOW)THENcnt1:=cnt1+1;ENDIF;count<=cnt1;ENDPROCESSp3;ROLED<=tmproled;LEDCO<=tmpledco;ENDARCHITECTUREART;由于实体中定义了STD_LOGIC信号类型,需要调用IEEE库中的STD_LOGIC_1164程序包;又由于结构体中使用了运算符“+”,需要调用IEEE库中的STD_LOGIC_UNSIGNED程序包。参考程序如下:LIBRARYIEEE;USEIEEE.STD_LOGIC_1164.ALL;USEIEEE.STD_LOGIC_UNSIGNED.ALL;3.库和程序包的确定1.题目说明使用1088AS(共阴极)点阵设计并实现“I⨀电子”的滚动显示,广告牌的效果。要求:能够异步复位,字符、图案和汉字从右向左循环滚动显示。5.5实训:点阵广告牌的设计与实现2.设计提示
参考“汉字滚动显示”程序,把所有需显示的字符、图案和汉字的字模从右向左依次排好,一方面用1KHz的频率(即满足视觉暂留的频率)从右向左扫描整个点阵,显示该时刻所扫描的字符,即显示一个“画面”;另外,用一个较慢的速度每次从右向左移动一列,即将“画面”的首列移出,补充到字模队列的最后列,视觉看上去就是从右向左滚动的效果。3.实训报告(1)记录并分析仿真波形。(2)分析实训结果。(3)若设置快、慢两种滚动速度,应如何修改程序?EDA项目教程
——基于VHDL与FPGA项目6信号发生器的设计与实现本章要点
子程序和LOOP语句
存储器的设计
信号发生器的设计与实现
6.1
子程序和LOOP语句
子程序是由一组顺序语句组成的,在程序包或结构体内定义,在结构体或进程中调用。子程序只有定义后才能被调用,将处理结果返回给主程序,主程序和子程序之间通过端口参数关联进行数据传送,可以被多次调用以便完成重复性的任务。每次调用时,都要先对子程序进行初始化,一次执行结束后再次调用需再次初始化,因此子程序内部定义的变量都是局部量。虽然子程序可以被多次调用完成重复性的任务,但从硬件角度看,EDA软件的综合工具对每次调用的子程序都要生成一个电路逻辑模块,因此设计者在频繁调用子程序时需要考虑硬件的承受能力。VHDL中的子程序有两种类型:过程和函数。过程和函数的区别主要是返回值和参数不同,过程调用可以通过其接口返回多个值,函数只能返回单个值;过程可以有输入参数、输出参数和双向参数,函数的所有参数都是输入参数。6.1.1子程序1.过程(PROCEDURE)过程的定义语句由两部分组成,即过程首和过程体。过程定义的格式为:PROCEDURE过程名参数列表--过程首PROCEDURE过程名参数列表IS--过程体说明部分;BEGIN顺序语句;END过程名;调用过程语句的格式为:过程名参数列表;LIBRARYIEEE;USEIEEE.STD_LOGIC_1164.ALL;USEIEEE.STD_LOGIC_UNSIGNED.ALL;ENTITYpsumISPORT(a,b,c:INSTD_LOGIC_VECTOR(3DOWNTO0);clk,clr:INSTD_LOGIC;--clr为复位端,
高电平有效SUM:OUTSTD_LOGIC_VECTOR(3DOWNTO0));ENDpsum;用一个过程语句来实现3个4位二进制数据求和的运算程序ARCHITECTUREaOFpsumISPROCEDUREadd1(data,datb,datc:INSTD_LOGIC_VECTOR;--定义过程体datout:OUTSTD_LOGIC_VECTOR)ISBEGINdatout:=data+datb+datc;--数据求和ENDadd1;--过程体定义结束。
在结构体中省略了过程首BEGIN--结构体开始PROCESS(clk)VARIABLEtmp:STD_LOGIC_VECTOR(3DOWNTO0);BEGIN--进程开始IF(clk'EVENTANDclk='1')THENIF(clr='1')THEN--高电平
同步复位tmp:="0000";ELSEadd1(a,b,c,tmp);--过程调用ENDIF;ENDIF;SUM<=tmp;ENDPROCESS;ENDa;
从仿真波形中可以看出,在0~50ns区间,CLR=1(同步复位有效),SUM=0000;在50~100ns区间,clk上升沿的左侧(观察输入信号),a=0001、b=0100、c=0010,clk上升沿的右侧(观察输出信号),SUM=0111;在350~400ns区间,clk上升沿的左侧,a=0111、b=0111、c=0011,clk上升沿的右侧,SUM=0001(数据溢出)。其他区间的波形情况符合题意。想一想、做一做:如何解决数据溢出的问题?求和运算程序的仿真波形
在VHDL中,用户可以自己定义一个程序包,将一些数据类型、子程序和元件保存在该程序包中,以便被其他设计程序所利用。程序包分为包首和包体两部分,格式如下。(1)包首:PACKAGE程序包名称IS
包首说明;END程序包名称;(2)包体:PACKAGEBODY程序包名称IS
包体说明语句组,END程序包名称;
说明:包首说明部分可定义函数、元件和子程序等。包体说明语句组部分是具体描述函数、元件和子程序的内容。在程序包结构中,如果在包首中定义了函数、元件和子程序的具体内容,这时包体可以缺省。2.程序包3.函数(FUNCTION)函数语句分为两个部分:函数首和函数体。在进程
和结构体中,函数首可以省略,而在程序包中,必须定义函数首,放在程序包的包首部分,而函
数体放在包体部分。格式如下:FUNCTION函数名(参数列表)--函数首
RETURN数据类型名;FUNCTION函数名(参数列表)--函数体
RETURN数据类型名IS
说明部分;
BEGIN
顺序语句;
RETURN返回变量;
END函数名;调用函数语句的格式为:y<=函数名(参数列表);
编写一个能输出2个4位二进制数中较大数的函数,并将这段函数放在一个程序包中,然后在进程中调用该函数两次,输出3个4位二进制数中的最大数。(1)在名称为blockA的程序包中,定义函数名称为maxA的函数,程序包文件名为blockA.vhd。由于本题需要调用程序包中定义的函数,可先建立一个文件夹,打开QuartusⅡ软件建立一个项目,项目名为smax,再编辑以下程序:LIBRARYIEEE;USEIEEE.STD_LOGIC_1164.ALL;PACKAGEblockAIS--定义程序包的包头,blockA是程序包名FUNCTIONmaxA(a:STD_LOGIC_VECTOR;--定义函数首,函数名是maxAb:STD_LOGIC_VECTOR)RETURNSTD_LOGIC_VECTOR;--定义函数返回值的类型ENDblockA;PACKAGEBODYblockAIS--定义程序包体FUNCTIONmaxA(a:STD_LOGIC_VECTOR;--定义函数体b:STD_LOGIC_VECTOR)RETURNSTD_LOGIC_VECTORISVARIABLEtmp:STD_LOGIC_VECTOR(3DOWNTO0);BEGINIF(a>b)THENtmp:=a;ELSEtmp:=b;ENDIF;RETURNtmp;--tmp是函数返回变量ENDmaxA;--函数体结束ENDblockA;注意:编辑完成后,不用编译,直接使用文件名blockA保存在当前文件夹下,以供主程序调用。LIBRARYIEEE;USEIEEE.STD_LOGIC_1164.ALL;LIBRARYWORK;--WORK是用户工作库USEWORK.blockA.ALL;--使用WORK库中的blockA程序包ENTITYsmaxISPORT(dc,da,db:INSTD_LOGIC_VECTOR(3DOWNTO0);clk,clr:INSTD_LOGIC;D:OUTSTD_LOGIC_VECTOR(3DOWNTO0));ENDsmax;(2)调用函数maxA的程序,文件名是smax.vhdARCHITECTUREaOFsmaxISBEGINPROCESS(clk)VARIABLEtmp:STD_LOGIC_VECTOR(3DOWNTO0);VARIABLEtmpmax:STD_LOGIC_VECTOR(3DOWNTO0);BEGINIF(clk'EVENTANDclk='1')THENIF(clr='1')THENtmpmax:="ZZZZ";ELSEtmp:=maxA(da,db);--调用函数,最大值放入tmp中tmpmax:=maxA(dc,tmp);ENDIF;ENDIF;D<=tmpmax;ENDPROCESS;ENDa;从仿真波形中可以看出,在0~50ns区间,CLR=1(同步复位有效),D=ZZZZ(高阻);在50~100ns区间,clk上升沿的左侧(观察输入信号),da=0001、db=0100、dc=0010,clk上升沿的右侧(观察输出信号),D=0100。其他区间的波形情况符合题意。输出最大值的仿真波形6.1.2LOOP语句1.FOR循环FOR循环是一种已知循环次数的语句,其格式如下:[循环标号]:FOR循环变量IN循环次数范围LOOP顺序语句;
ENDLOOP[循环标号];其中,循环标号是用来表示FOR循环语句的标识符,是可选项。循环次数范围表示循环变量的取值范围,且在每次循环中,循环变量的值都要发生变化。LIBRARYIEEE;USEIEEE.STD_LOGIC_1164.ALL;ENTITYpcISPORT(a:INSTD_LOGIC_VECTOR(7DOWNTO0);y:OUTSTD_LOGIC);ENDpc;用FOR循环语句描述一个8位奇校验电路,电路输入信号为a,输出信号为yARCHITECTUREoddOFpcISBEGINcbc:PROCESS(a)VARIABLEtmp:STD_LOGIC;--tmp为局部变量,只能在进程中定义BEGINtmp:='0';FORiIN0TO7LOOP--循环变量i由循环语句自动定义tmp:=tmpXORa(i);ENDLOOP;--缺省了循环标号y<=tmp;ENDPROCESScbc;ENDodd;2.WHILE循环WHILE循环是一种未知循环次数的语句,循环次数取决于条件表达式是否成立。其格式如下:[循环标号]:WHILE条件表达式LOOP顺序语句;
ENDLOOP[循环标号];循环标号是用来表示WHILE循环语句的标识符,是可选项。在循环语句中,没有给出循环次数的范围,而是给出了循环语句的条件。WHILE后边的条件表达式是一个布尔表达式,如果条件为TURE,则进行循环,如果条件为FALSE,则结束循环。用WHILE循环语句描述8位奇校验电路LIBRARYIEEE;USEIEEE.STD_LOGIC_1164.ALL;ENTITYpcISPORT(a:INSTD_LOGIC_VECTOR(7DOWNTO0);y:OUTSTD_LOGIC);ENDpc;ARCHITECTUREaOFpcISBEGINcbc:PROCESS(a)VARIABLEtmp:STD_LOGIC;--tmp为局部变量,只能在进程中定义VARIABLEi:INTEGER;--定义循环变量i,WHILE语句不用自定义BEGINtmp:='0';i:=0;--给循环变量i赋初值WHILE(i<8)LOOPtmp:=tmpXORa(i);i:=i+1;ENDLOOP;
y<=tmp;ENDPROCESScbc;ENDa;注意:并非所有的EDA综合器都支持WHILE语句。6.2存储器
存储器是数学系统的重要组成部分之一,用来存储程序和数据,表征系统的“记忆”功能。存储器属于通用大规模器件,一般不需要自行设计,但是数字系统有时需要设计一些小型的存储器件,用于临时存放数据,构成查表运算的数据表等。6.2.1ROMROM(只读存储器)是一种只能读出所存数据的存储器,其特性是一旦储存资料就无
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 河南省安阳市文峰区2024-2025学年九年级上学期1月期末化学试题(含答案)
- 2019-2025年军队文职人员招聘之军队文职政治学能力检测试卷B卷附答案
- 临床急救知识培训课件
- 酒吧员工禁止恋爱合同(2篇)
- 2025年反电信网络诈骗法测试题库及参考答案
- 自体输血知识培训课件
- 农资产品经销代理合作协议
- 共享单车租赁服务协议
- 睡前故事故事解读
- 辽宁省大连市2024-2025学年高一上学期1月期末考试生物学试题(含答案)
- 2016-2023年江苏城市职业学院高职单招(英语/数学/语文)笔试历年参考题库含答案解析
- 加强物料提升机施工现场安全管理
- 第15课《我是记忆小能手》课件
- 重症肺炎护理查房文献参考
- 小红书经典营销案例分析
- 企业战略与绩效管理
- 虚拟货币交易合同
- 操作系统课程设计报告
- 静脉输液的不良反应及处理原则考核试题及答案
- 档案袋密封条格式范本(可直接打印,可自行编辑)
- 2022年深圳市南山区教育系统招聘公办幼儿园园长考试真题
评论
0/150
提交评论