报告数电VHDL实验报告.docx
《报告数电VHDL实验报告.docx》由会员分享,可在线阅读,更多相关《报告数电VHDL实验报告.docx(24页珍藏版)》请在冰豆网上搜索。
报告数电VHDL实验报告
【关键字】报告
2009级数字电路实验报告
实验名称:
EDA基础实验
学生姓名:
桂柯易
班级:
20
班内序号:
07
学号:
09210580
日期:
2011年4月28日
1.实验要求
【实验目的】
1.熟悉用QuartusII原理图输入法进行电路设计和仿真;
2.掌握QuartusII图形模块单元的生成与调用;
3.熟悉用VHDL语言设计组合逻辑电路和时序电路的方法;
4.熟悉用QuartusII文本输入法和图形输入法进行电路设计;
5.熟悉不同的编码及其之间的转换;
6.掌握触发器的逻辑功能及使用方法;
7.熟悉计数器、寄存器、锁存器、分频器、移位寄存器的设计方法
8.掌握VHDL语言的语法规范,掌握时序电路描述方法;
9.掌握多个数码管动态扫描显示的原理及设计方法。
【实验所用仪器及元器件】
1.计算机
2.直流稳压电源
3.数字系统与逻辑设计实验开发板
【实验内容】
1.用逻辑门设计实现一个半加器,仿真验证其功能,并生成新的半加器图形模块单元。
2.用实验内容1中生成的半加器模块和逻辑门设计实现一个全加器,仿真验证其功
能,并下载到实验板尝试,要求用拨码开关设定输入信号,发光二极管显示输出信
号。
3.用3线-8线译码器(74LS138)和逻辑门设计实现函数F,仿真验证其功能,并下
载到实验板尝试。
要求用拨码开关设定输入信号,发光二极管显示输出信号。
4.用VHDL语言设计实现一个3位二进制数值比较器,仿真验证其功能,并下载到实
验板尝试。
要求用拨码开关设定输入信号,发光二极管显示输出信号。
5.用VHDL语言设计实现一个4选1的数据选择器;一个8421码转换为格雷码的代码
转换器;一个举重比赛裁判器;一个带同步置位和同步复位功能的D触发器;一个
带异步复位的4位二进制减计数器;一个带异步复位的8421码十进制计数器;一
个带异步复位的4位自启动环形计数器;一个带控制端的8位二进制寄存器,当控
制端为‘1’时,电路正常工作,否则输出为高阻态;一个分频系数为12,分频输
出信号占空比为50%的分频器。
仿真验证其功能,并下载到实验板尝试。
要求用拨
码开关和按键开关设定输入信号,发光二极管显示输出信号。
(注:
有几个不需要
下载到实验板尝试)
2.程序分析
全加器:
LIBRARYIEEE;
USEIEEE.STD_LOGIC_1164.ALL;
ENTITYh_adderIS
PORT(a,b:
INSTD_LOGIC;
co,so:
OUTSTD_LOGIC);
ENDENTITYh_adder;
ARCHITECTUREaOFh_adderIS
BEGIN
so<=aXORb;
co<=aANDb;
END;
libraryieee;
useieee.std_logic_1164.all;
entityGKY07P3is
port(ain,bin,cin:
instd_logic;
cout,sum:
outstd_logic);
endentityGKY07P3;
architectureaofGKY07P3is
componenth_adder
port(a,b:
instd_logic;
co,so:
outstd_logic);
endcomponent;
signald,e,f:
std_logic;
begin
u1:
h_adderportmap(a=>ain,b=>bin,co=>d,so=>e);
u2:
h_adderportmap(a=>e,b=>cin,co=>f,so=>sum);
cout<=dorf;
end;
整体思路是按照实验的要求,先做出一个半加器,然后在这个半加器的基础上实现全加器的功能。
函数F:
3位二进制数值比较器:
LIBRARYIEEE;
USEIEEE.STD_LOGIC_1164.ALL;
ENTITYGKY07P4IS
PORT(A:
INSTD_LOGIC_VECTOR(2DOWNTO0);
B:
INSTD_LOGIC_VECTOR(2DOWNTO0);
YA,YB,YC:
OUTSTD_LOGIC);
ENDGKY07P4;
ARCHITECTUREbehaveOFGKY07P4IS
BEGIN
PROCESS(A,B)
BEGIN
IF(A>B)THEN
YA<='1';YB<='0';YC<='0';
ELSIF(A
YA<='0';YB<='1';YC<='0';
ELSE
YA<='0';YB<='0';YC<='1';
ENDIF;
ENDPROCESS;
ENDbehave;
将比较的过程直接交给软件本身,只需通过不同的二进制数输出比较的结果即可。
4选1数据选择器:
LIBRARYIEEE;
USEIEEE.STD_LOGIC_1164.ALL;
ENTITYGKY07P5IS
PORT(G,A1,A0:
INSTD_LOGIC;
D0,D1,D2,D3:
INSTD_LOGIC;
Y,YB:
OUTSTD_LOGIC);
ENDGKY07P5;
ARCHITECTUREbehaveOFGKY07P5IS
SIGNALcomb:
STD_LOGIC_VECTOR(1DOWNTO0);
BEGIN
comb<=A1&A0;
PROCESS(G,comb,D0,D1,D2,D3)
BEGIN
IFG='0'THEN
CASEcombIS
WHEN"00"=>Y<=D0;YB<=NOTD0;
WHEN"01"=>Y<=D1;YB<=NOTD1;
WHEN"10"=>Y<=D2;YB<=NOTD2;
WHEN"11"=>Y<=D3;YB<=NOTD3;
WHENOTHERS=>Y<='0';YB<='1';
ENDCASE;
ELSE
Y<='0';YB<='1';
ENDIF;
ENDPROCESS;
ENDbehave;
主要是WHEN语句的运用,用两位二进制数表示四种数据输出状态,再用WHEN语句具体实现。
8421码转换为格雷码:
LIBRARYIEEE;
USEIEEE.STD_LOGIC_1164.ALL;
ENTITYGKY07P6IS
PORT(A:
INSTD_LOGIC_VECTOR(3DOWNTO0);
B:
OUTSTD_LOGIC_VECTOR(3DOWNTO0));
ENDGKY07P6;
ARCHITECTUREbehaveOFGKY07P6IS
BEGIN
PROCESS(A)
BEGIN
B(3)<=A(3);
B
(2)<=A(3)XORA
(2);
B
(1)<=A
(2)XORA
(1);
B(0)<=A
(1)XORA(0);
ENDPROCESS;
ENDbehave;
本来是考察WHEN语句的运用,将所有的情况用WHEN语句列出来,但是因为8421码转换为格雷码的时候有一个相关的计算式子,采用这个式子可以使程序简化不少。
举重比赛裁判器:
LIBRARYIEEE;
USEIEEE.STD_LOGIC_1164.ALL;
ENTITYGKY07P7IS
PORT(a:
INSTD_LOGIC_VECTOR(2DOWNTO0);
b:
OUTSTD_LOGIC_VECTOR(2DOWNTO0));
ENDGKY07P7;
ARCHITECTUREbehaveOFGKY07P7IS
BEGIN
PROCESS(a)
BEGIN
CASEaIS
WHEN"000"=>b<="000";
WHEN"001"=>b<="000";
WHEN"010"=>b<="000";
WHEN"011"=>b<="100";
WHEN"100"=>b<="100";
WHEN"101"=>b<="111";
WHEN"110"=>b<="111";
WHEN"111"=>b<="111";
ENDCASE;
ENDPROCESS;
END;
与前几题不同,这个更偏向应用。
列出实际情况的状态表,发现三个裁判的不同判断各对应红黄绿灯的亮灭情况,故还是WHEN语句的应用。
D触发器:
LIBRARYIEEE;
USEIEEE.STD_LOGIC_1164.ALL;
ENTITYGKY07P8IS
PORT(d,clk,set,reset:
INSTD_LOGIC;
q,qb:
OUTSTD_LOGIC);
ENDGKY07P8;
ARCHITECTUREstrucOFGKY07P8IS
BEGIN
PROCESS(clk,set,reset)
BEGIN
IFset='0'ANDreset='1'THEN
q<='1';qb<='0';
ELSIFset='1'ANDreset='0'THEN
q<='0';qb<='1';
ELSIFclk'EVENTANDclk='1'THEN
q<=d;qb<=NOTd;
ENDIF;
ENDPROCESS;
ENDstruc;
和书上的例子基本一样,只是同步置位和同步复位都跟随时间脉冲的变化。
4位二进制减计数器:
LIBRARYIEEE;
USEIEEE.STD_LOGIC_1164.ALL;
USEIEEE.STD_LOGIC_UNSIGNED.ALL;
ENTITYGKY07P9IS
PORT(clk,reset:
INSTD_LOGIC;
q:
OUTSTD_LOGIC_VECTOR(3DOWNTO0));
ENDGKY07P9;
ARCHITECTUREstrucOFGKY07P9IS
SIGNALq_temp:
STD_LOGIC_VECTOR(3DOWNTO0);
BEGIN
PROCESS(clk)
BEGIN
IF(clk'EVENTANDclk='1')THEN
IFreset='0'THEN
q_temp<="1111";
ELSIFq_temp<="0000"THEN
q_temp<="1111";
ELSE
q_temp<=q_temp-1;
ENDIF;
ENDIF;
ENDPROCESS;
q<=q_temp;
ENDstruc;
从状态‘1111’到状态‘0000’,然后再跳回‘1111’。
异步复位不需要跟随脉冲变化,要立即复位。
8421码十进制计数器:
LIBRARYIEEE;
USEIEEE.STD_LOGIC_1164.ALL;
USEIEEE.STD_LOGIC_UNSIGNED.ALL;
ENTITYGKY07P10IS
PORT(clk,reset:
INSTD_LOGIC;
q:
OUTSTD_LOGIC_VECTOR(3DOWNTO0));
ENDGKY07P10;
ARCHITECTUREstrucOFGKY07P10IS
SIGNALq_temp:
STD_LOGIC_VECTOR(3DOWNTO0);
BEGIN
PROCESS(clk)
BEGIN
IF(clk'EVENTANDclk='1')THEN
IFreset='1'THEN
q_temp<="0000";
ELSIFq_temp="1001"THEN
q_temp<="0000";
ELSE
q_temp<=q_temp+1;
ENDIF;
ENDIF;
ENDPROCESS;
q<=q_temp;
ENDstruc;
从状态‘0000’到状态‘1001’,然后再跳回‘0000’,异步复位要立即复位。
4位环形计数器:
LIBRARYIEEE;
USEIEEE.STD_LOGIC_1164.ALL;
ENTITYGKY07P11IS
PORT(clk,reset:
INSTD_LOGIC;
countout:
OUTSTD_LOGIC_VECTOR(3DOWNTO0));
ENDGKY07P11;
ARCHITECTUREbehaveOFGKY07P11IS
SIGNALnextcount:
STD_LOGIC_VECTOR(3DOWNTO0);
BEGIN
PROCESS(clk,reset)
BEGIN
IFRESET='1'THENnextcount<="0001";
ELSIF(clk'EVENTANDclk='1')THEN
CASEnextcountIS
WHEN"0001"=>nextcount<="0010";
WHEN"0010"=>nextcount<="0100";
WHEN"0100"=>nextcount<="1000";
WHENOTHERS=>nextcount<="0001";
ENDCASE;
ENDIF;
ENDPROCESS;
countout<=nextcount;
ENDbehave;
计数状态在‘0001’,‘0010’,‘0100’,‘1000’四个之间转换,由于需要能够自启动,对别状态的处理是全部引到那四个计数状态上。
8位二进制寄存器:
LIBRARYIEEE;
USEIEEE.STD_LOGIC_1164.ALL;
ENTITYGKY07P12IS
PORT(d:
INSTD_LOGIC_VECTOR(7DOWNTO0);
oe,clk:
INSTD_LOGIC;
q:
OUTSTD_LOGIC_VECTOR(7DOWNTO0));
ENDGKY07P12;
ARCHITECTUREstrucOFGKY07P12IS
SIGNALtemp:
STD_LOGIC_VECTOR(7DOWNTO0);
BEGIN
PROCESS(clk,oe)
BEGIN
IFoe='1'THEN
IFclk'EVENTANDclk='1'THEN
temp<=d;
ENDIF;
ELSE
temp<="ZZZZZZZZ";
ENDIF;
q<=temp;
ENDPROCESS;
ENDstruc;
和书上的例子基本一样,将低电平控制改成高电平控制即可。
分频器:
LIBRARYIEEE;
USEIEEE.STD_LOGIC_1164.ALL;
USEIEEE.STD_LOGIC_UNSIGNED.ALL;
ENTITYGKY07P13IS
PORT(clk,clear:
INSTD_LOGIC;
clk_out:
OUTSTD_LOGIC);
ENDGKY07P13;
ARCHITECTUREstrucOFGKY07P13IS
SIGNALtemp:
INTEGERRANGE0TO11;
BEGIN
p1:
PROCESS(clear,clk)
BEGIN
IFclear='0'THEN
temp<=0;
ELSIFclk'EVENTANDclk='1'THEN
IFtemp=11THEN
temp<=0;
ELSE
temp<=temp+1;
ENDIF;
ENDIF;
ENDPROCESSp1;
p2:
PROCESS(temp)
BEGIN
IFtemp<6THEN
clk_out<='0';
ELSE
clk_out<='1';
ENDIF;
ENDPROCESSp2;
ENDstruc;
很重要的一个器件,但是设计难度并不很高,首先是模为12的计数,然后是占空比50%。
数码管串行扫描电路:
LIBRARYIEEE;
USEIEEE.STD_LOGIC_1164.ALL;
USEIEEE.STD_LOGIC_UNSIGNED.ALL;
ENTITYGKY07P14IS
PORT(clk,clear:
INSTD_LOGIC;
q:
OUTSTD_LOGIC_VECTOR(6DOWNTO0);
countout:
OUTSTD_LOGIC_VECTOR(5DOWNTO0));
ENDGKY07P14;
ARCHITECTUREbehaveOFGKY07P14IS
SIGNALq_temp:
STD_LOGIC_VECTOR(6DOWNTO0);
SIGNALcount:
STD_LOGIC_VECTOR(5DOWNTO0);
SIGNALcnt:
INTEGERRANGE0TO5;
BEGIN
p1:
PROCESS(clk)
BEGIN
IF(clk'EVENTANDclk='1')THEN
IF(cnt=5)THENcnt<=0;
ELSE
cnt<=cnt+1;
ENDIF;
ENDIF;
ENDPROCESS;
p2:
PROCESS(cnt)
BEGIN
IF(clear='0')THENcount<="111111";
ELSE
CASEcntIS
WHEN1=>count<="101111";q_temp<="0110000";
WHEN2=>count<="110111";q_temp<="1101101";
WHEN3=>count<="111011";q_temp<="1111001";
WHEN4=>count<="111101";q_temp<="0110011";
WHEN5=>count<="111110";q_temp<="1011011";
WHEN0=>count<="011111";q_temp<="1111110";
ENDCASE;
ENDIF;
ENDPROCESS;
countout<=count;
q<=q_temp;
ENDbehave;
先用0~5六进制计数器产生六个计数状态,这六个状态同时决定二极管点亮的数字和数码管接通的电路,在时钟信号频率很高的时候可以同时显示0~5六个数字。
只是在下载到实验板的时候与芯片的各个引脚一定要对应,不然容易达不到实验要求。
数码管滚动显示电路:
LIBRARYIEEE;
USEIEEE.STD_LOGIC_1164.ALL;
USEIEEE.STD_LOGIC_UNSIGNED.ALL;
ENTITYGKY07P14IS
PORT(clk,clear:
INSTD_LOGIC;
q:
OUTSTD_LOGIC_VECTOR(6DOWNTO0);
countout:
OUTSTD_LOGIC_VECTOR(5DOWNTO0));
ENDGKY07P14;
ARCHITECTUREbehaveOFGKY07P14IS
SIGNALq_temp:
STD_LOGIC_VECTOR(6DOWNTO0);
SIGNALcount:
STD_LOGIC_VECTOR(5DOWNTO0);
SIGNALcnt,cnt1:
INTEGERRANGE0TO5;
SIGNALtmp:
INTEGERRANGE0TO1999;
signalclk1:
STD_LOGIC;
BEGIN
p0:
PROCESS(clk,clear)
BEGIN
IFclear='0'THENtmp<=0;
ELSIFclk'EVENTANDclk='1'THEN
IFtmp=1999THEN
tmp<=0;
ELSE
tmp<=tmp+1;
ENDIF;
ENDIF;
ENDPROCESSp0;
p1:
PROCESS(tmp)
BEGIN
IFclk'EVENTANDclk='1'THEN
IFtmp<1000THEN
clk1<='0';
ELSE
clk1<='1';
ENDIF;
ENDIF;
ENDPROCESSp1;
p2:
PROCESS(clk)
BEGIN
IF(clk'EVENTANDclk='1')THEN
IF(cnt=5)THENcnt<=0;
ELSE
cnt<=cnt+1;
ENDIF;
ENDIF;
ENDPROCESSp2;
p3:
PROCESS(clk1)
BEGIN
IF(clk1'EVENTANDclk1='1')THEN
IF(cnt1=5)THENcnt1<=0;
ELSE
cnt1<=cnt1+1;
ENDIF;
ENDIF;
ENDPROCESSp3;
p4:
PROCESS(cnt,cnt1)
BEGIN
IF(clear='0')THENq_temp<="0000000";
ELSE
CASEcnt+cnt1IS
WHEN0=>q_temp<="1111110";
WHEN1=>q_temp<="0110000";
WHEN2=>q_temp<="1101101";
WHEN3=>q_temp<="1111001";
WHEN4=>q_temp<="0110011";
WHEN5=>q_temp<="1011011";
WHEN6=>q_temp<="1111110";
WHEN7=>q_temp<="0110000";
WHEN8=>q_temp<="1101101";
WHEN9=>q_temp<="1111001";
WHEN10=>q_temp<="0110011";
WHEN11=>q_temp<="1011011";
WHENOTHERS=>q_temp<="0000000";
ENDCASE;
ENDIF;
ENDPROCESSp4;
q<=q_temp;
p5:
PROCESS(cnt)
BEGIN
IF(clear='0')THENcount<="111111";
ELSE
CASEcntIS
WHEN0=>count<="011111";
WHEN1=>count<="101111";
WHEN2=>count<="110111";
WHEN3=>count<="