北邮数字电路与逻辑设计实验实验报告下.docx
《北邮数字电路与逻辑设计实验实验报告下.docx》由会员分享,可在线阅读,更多相关《北邮数字电路与逻辑设计实验实验报告下.docx(35页珍藏版)》请在冰豆网上搜索。
北邮数字电路与逻辑设计实验实验报告下
北京邮电大学电路实验中心
<数字电路与逻辑设计实验(下)>
实
验
报
告
班 级:
xxx
学 院:
xxx
实验室:
xxx
审阅教师:
姓名(班内序号):
xxx
学 号:
xxx
实验时间:
xxx
评定成绩:
目录
一、任务要求2
1.基本要求2
2.提高要求2
二、系统设计2
1.设计思路2
2.总体框图4
3.分块设计5
(1)分频器模块5
(2)4×4键盘输入模块5
(3)数码管显示模块6
(4)8×8LED点阵显示模块6
(5)LCD液晶屏显示模块6
(6)中心模块6
三、仿真波形及波形分析6
1.分频器模块6
2.4×4键盘输入模块7
3.数码管显示模块7
4.8×8LED点阵显示模块8
5.LCD液晶屏显示模块8
6.中心模块8
四、源程序9
1.分频器模块9
2.4×4键盘输入模块9
3.数码管显示模块11
4.8×8LED点阵显示模块12
5.LCD液晶屏显示模块19
6.中心模块23
五、功能说明及资源利用情况26
六、故障及问题分析27
七、总结和结论27
一、任务要求
本电路可供甲乙二人进行猜拳游戏。
通过不同的按键控制,选择多种出拳方式,显示猜拳的结果,实现猜拳游戏,防止了作弊的可能。
1.基本要求
1、甲乙双方各用4×4键盘中的三个按键模拟“石头”、“剪刀”、“布”,一个按键为“确认”。
4×4键盘第一行为甲,第二行为乙;
2、裁判用4×4键盘第三行的一个按键模拟“开”,一个按键为“准备”,一个按键为“复位”;
3、裁判宣布“准备”后,甲乙双方分别选择出拳方式并确认;
4、裁判“开”以后,用点阵的左右三列同时显示甲乙双方的猜拳选择(如下图所示),并用两个数码管显示甲乙的猜拳比分;
图1甲“布”,乙“剪刀”;甲“剪刀”,乙“石头”
5、猜拳游戏为五局三胜制。
若甲乙双方出拳一致,则比分保持不变,双方重新出拳;
6、比赛结束后,用8×8点阵显示甲乙获胜方;
7、复位后游戏重新开始。
2.提高要求
1、点阵显示增加游戏开机动画、结束动画;
2、为游戏增加音效;
3、在LCD1602液晶屏上显示甲乙双方的猜拳比分;
4、自拟其他功能。
二、系统设计
1.设计思路
本电路分为6个模块,分别是中心模块(包含状态机)、8×8LED点阵显示模块、数码管显示模块、LCD液晶屏显示模块、4×4键盘输入模块、分频器模块,各模块使用VHDL语言设计,顶层连接使用QuartusII原理图设计。
分频器模块负责将50MHz时钟分成低频信号,供其他模块使用。
中心模块负责读取4×4键盘输入模块的输入,并控制状态机和其他模块的输出显示。
8×8LED点阵显示模块负责接收中心模块的信号,显示相应的图案。
数码管显示模块和LCD液晶屏显示模块负责接收中心模块的信号,显示比分。
4×4键盘输入模块负责读取键盘输入,并将其输出到中心模块。
2.总体框图
图2系统流程图
图3逻辑框图
图4BDF原理图
3.分块设计
(1)分频器模块
输入clkin为50MHz时钟,输出clkout为1KHz时钟,作为中心模块、8×8LED点阵显示模块、数码管显示模块、4×4键盘输入模块的时钟信号。
(2)4×4键盘输入模块
4×4键盘输入模块负责读取键盘输入,并将其输出到中心模块。
输出KBcol为4位二进制信号,是键盘的遍历扫描信号。
输入KBrow为4位二进制信号,是键盘的检测信号。
输出resultout为5位二进制信号,是4×4键盘输入模块所检测出的所按的按键,其中第一位代表键盘按下,后四位用二进制数表示所按的按键。
(3)数码管显示模块
数码管显示模块负责接收中心模块的信号,显示比分。
输入A、B分别为2位二进制信号,代表甲、乙的得分。
输出cat为8位二进制信号,控制8个数码管的使能端。
输出disp为7位二进制信号,控制数码管所显示的图案。
(4)8×8LED点阵显示模块
8×8LED点阵显示模块负责接收中心模块的信号,显示相应的图案。
输入A、B分别为2位二进制信号,代表甲、乙的出拳结果,其中“11”表示甲或乙获胜,显示结束动画。
输入en为点阵的使能端,start为开机动画控制信号。
输出row为8位二进制信号,是点阵的扫描信号。
输出colr为8位二进制信号,是红色点阵的数据信号。
输出colg为8位二进制信号,是绿色点阵的数据信号。
(5)LCD液晶屏显示模块
LCD液晶屏显示模块负责接收中心模块的信号,显示比分。
时钟clk直接使用50MHz信号。
输入rst为LCD液晶屏模块的复位信号,输入A、B分别为2位二进制信号,代表甲、乙的得分。
输出rs、en、rw、data_out为LCD液晶屏的控制和数据信号。
(6)中心模块
中心模块负责读取4×4键盘输入模块的输入,并控制状态机和其他模块的输出显示。
输入KB为5位二进制信号,是4×4键盘输入模块所检测出的所按的按键。
输出LEDen控制LED点阵模块的使能端,LEDstart为LED点阵模块的开机动画控制信号。
输出LEDA、LEDB分别为2位二进制信号,代表甲、乙的出拳结果,其中“11”表示甲或乙获胜,显示结束动画。
输出DISPA、DISPB分别为2位二进制信号,代表甲、乙的得分。
三、仿真波形及波形分析
1.分频器模块
分频比太大,不易仿真。
2.4×4键盘输入模块
图54×4键盘输入模块仿真
模块为时钟下降沿有效,resultout[4]为有按键按下的信号,resultout[0..3]为按下的按键。
仿真中遍历了所有按键的情况,在resultout中对应有16~31的所有情况(没有按顺序)。
在中心模块编写时,考虑了防抖的问题,检测到按下多次按键与按下一次按键的效果相同,所以在此模块中没有必要加入防抖。
3.数码管显示模块
图6数码管显示模块仿真
时钟clk为‘0’时,DISP7点亮,显示甲的得分,时钟clk为‘1’时,DISP6点亮,显示乙的得分。
输入A、B遍历了甲、乙得分的所有结果,对应disp为数码管的显示,‘~’状态表示0分,‘0’状态表示1分,‘m’状态表示2分,‘y’状态表示3分。
4.8×8LED点阵显示模块
图78×8LED点阵显示模块仿真
此模块状态太多,只仿真了部分状态。
输入A、B的‘0’-‘2’状态分别代表石头、剪刀、布,‘3’状态代表甲或乙获胜。
输出colr为甲的出拳结果,colg为乙的出拳结果。
5.LCD液晶屏显示模块
此模块使用50MHz信号,不易仿真。
实现功能与数码管显示模块类似。
6.中心模块
图8中心模块仿真
此模块状态太多,只仿真了部分状态。
仿真中模拟按下了3个按键,第一个是裁判的“准备”键,按键抬起后结束开机动画,进入选手输入状态,LEDen和LEDstart都变为‘0’。
第二个是乙按下“剪刀”(甲默认出“布”),按键抬起后LEDB的信号发生变化。
第一个是裁判的“开”键,按键抬起后结算双方出拳结果,给乙+1分(DISPB),同时显示双方出拳结果,LEDen变为‘1’。
四、源程序
1.分频器模块
libraryieee;
useieee.std_logic_1164.all;
entityfenpinqi12is
port(clkin:
instd_logic;--时钟信号输入
clkout:
outstd_logic);--时钟信号输出
endfenpinqi12;
architecturearoneMHZoffenpinqi12is
signaldata:
integerrange0to24999;
signalQ:
std_logic;
begin
process(clkin)
begin
ifrising_edge(clkin)then--检测输入时钟上升沿
if(data=24999)then--此句为你想要的分频比,data=0,1,2,3,4.......9的分频比为1,2,3,,,10
data<=0;
Q<=notQ;
else
data<=data+1;
endif;
endif;
clkout<=Q;
endprocess;
endaroneMHZ;
2.4×4键盘输入模块
LIBRARYIEEE;
USEIEEE.STD_LOGIC_1164.ALL;
USEIEEE.STD_LOGIC_UNSIGNED.ALL;
ENTITYKBcontrollerIS
PORT(
clk:
INSTD_LOGIC;--时钟
KBcol:
OUTSTD_LOGIC_VECTOR(0TO3);--扫描信号
KBrow:
INSTD_LOGIC_VECTOR(0TO3);--检测信号
resultout:
OUTSTD_LOGIC_VECTOR(4DOWNTO0)--检测结果
);
ENDKBcontroller;
ARCHITECTUREbehavioralOFKBcontrollerIS
signaltemp:
INTEGERRANGE0TO3;
signalresult:
STD_LOGIC_VECTOR(4DOWNTO0);
BEGIN
P1:
PROCESS(temp)
BEGIN
IF(clk'eventandclk='0')THEN
CASEtempIS--检测键盘输入结果
WHEN0=>
CASEKBrowIS
WHEN"0111"=>result<="11111";
WHEN"1011"=>result<="11110";
WHEN"1101"=>result<="11101";
WHEN"1110"=>result<="11100";
WHENOTHERS=>result<="00000";
ENDCASE;
WHEN1=>
CASEKBrowIS
WHEN"0111"=>result<="11011";
WHEN"1011"=>result<="11010";
WHEN"1101"=>result<="11001";
WHEN"1110"=>result<="11000";
WHENOTHERS=>result<="00000";
ENDCASE;
WHEN2=>
CASEKBrowIS
WHEN"0111"=>result<="10111";
WHEN"1011"=>result<="10110";
WHEN"1101"=>result<="10101";
WHEN"1110"=>result<="10100";
WHENOTHERS=>result<="00000";
ENDCASE;
WHEN3=>
CASEKBrowIS
WHEN"0111"=>result<="10011";
WHEN"1011"=>result<="10010";
WHEN"1101"=>result<="10001";
WHEN"1110"=>result<="10000";
WHENOTHERS=>result<="00000";
ENDCASE;
WHENOTHERS=>NULL;
ENDCASE;
ENDIF;
resultout<=result;
ENDPROCESSP1;
P2:
process(clk)
begin
IF(clk'eventandclk='1')THEN--模4计数器,对应键盘的4列
IFtemp=3THEN
temp<=0;
ELSE
temp<=temp+1;
ENDIF;
ENDIF;
ENDPROCESSP2;
P3:
process(temp)
begin
CASEtempIS--键盘扫描输出
WHEN0=>KBcol<="1110";
WHEN1=>KBcol<="1101";
WHEN2=>KBcol<="1011";
WHEN3=>KBcol<="0111";
WHENOTHERS=>KBcol<="1111";
ENDCASE;
ENDPROCESSP3;
ENDbehavioral;
3.数码管显示模块
LIBRARYIEEE;
USEIEEE.STD_LOGIC_1164.ALL;
USEIEEE.STD_LOGIC_UNSIGNED.ALL;
ENTITYDISPshowIS
PORT(
clk:
INSTD_LOGIC;--时钟
A:
INSTD_LOGIC_VECTOR(1DOWNTO0);--甲的得分
B:
INSTD_LOGIC_VECTOR(1DOWNTO0);--乙的得分
disp:
OUTSTD_LOGIC_VECTOR(0To6);--显示内容
cat:
OUTSTD_LOGIC_VECTOR(7DOWNTO0));--数码管使能
ENDDISPshow;
ARCHITECTUREbehavioralOFDISPshowIS
BEGIN
P3:
process(clk,A,B)
variabledispA:
STD_LOGIC_VECTOR(0To6);
variabledispB:
STD_LOGIC_VECTOR(0To6);
begin
CASEAIS--将甲得分变为数码管显示信号
WHEN"00"=>dispA:
="1111110";--0
WHEN"01"=>dispA:
="0110000";--1
WHEN"10"=>dispA:
="1101101";--2
WHEN"11"=>dispA:
="1111001";--3
WHENOTHERS=>dispA:
="0000000";
ENDCASE;
CASEBIS--将乙得分变为数码管显示信号
WHEN"00"=>dispB:
="1111110";--0
WHEN"01"=>dispB:
="0110000";--1
WHEN"10"=>dispB:
="1101101";--2
WHEN"11"=>dispB:
="1111001";--3
WHENOTHERS=>dispB:
="0000000";
ENDCASE;
CASEclkIS--时钟为‘0’时显示甲,时钟为‘1’时显示乙,相当于扫描
WHEN'0'=>disp<=dispA;cat<="01111111";
WHEN'1'=>disp<=dispB;cat<="10111111";
WHENOTHERS=>disp<="0000000";cat<="11111111";
ENDCASE;
ENDPROCESSP3;
ENDbehavioral;
4.8×8LED点阵显示模块
LIBRARYIEEE;
USEIEEE.STD_LOGIC_1164.ALL;
USEIEEE.STD_LOGIC_UNSIGNED.ALL;
ENTITYLEDshowIS
PORT(
clk:
INSTD_LOGIC;--时钟
en:
INSTD_LOGIC;--使能端
A:
INSTD_LOGIC_VECTOR(1DOWNTO0);--甲的出拳
B:
INSTD_LOGIC_VECTOR(1DOWNTO0);--乙的出拳
start:
INSTD_LOGIC;--开始动画控制
colr:
OUTSTD_LOGIC_VECTOR(7DOWNTO0);--红色数据信号
colg:
OUTSTD_LOGIC_VECTOR(7DOWNTO0);--绿色数据信号
row:
OUTSTD_LOGIC_VECTOR(7DOWNTO0));--扫描信号
ENDLEDshow;
ARCHITECTUREbehavioralOFLEDshowIS
signaltemp:
INTEGERRANGE0TO8;
signaltemp1:
INTEGERRANGE0TO5;
signaldata:
integerrange0to249;
signalclk_2Hz,Q:
STD_LOGIC;
signalA0:
STD_LOGIC_VECTOR(0to7);
signalA1:
STD_LOGIC_VECTOR(0to7);
signalA2:
STD_LOGIC_VECTOR(0to7);
signalA3:
STD_LOGIC_VECTOR(0to7);
signalA4:
STD_LOGIC_VECTOR(0to7);
signalA5:
STD_LOGIC_VECTOR(0to7);
signalA6:
STD_LOGIC_VECTOR(0to7);
signalA7:
STD_LOGIC_VECTOR(0to7);
signalB0:
STD_LOGIC_VECTOR(7DOWNTO0);
signalB1:
STD_LOGIC_VECTOR(7DOWNTO0);
signalB2:
STD_LOGIC_VECTOR(7DOWNTO0);
signalB3:
STD_LOGIC_VECTOR(7DOWNTO0);
signalB4:
STD_LOGIC_VECTOR(7DOWNTO0);
signalB5:
STD_LOGIC_VECTOR(7DOWNTO0);
signalB6:
STD_LOGIC_VECTOR(7DOWNTO0);
signalB7:
STD_LOGIC_VECTOR(7DOWNTO0);
BEGIN
P1:
PROCESS(clk_2Hz)
BEGIN
ifstart='0'then
ifA="00"then--甲出布
A0<="00000000";A1<="00000000";A2<="11100000";A3<="11100000";
A4<="11100000";A5<="11100000";A6<="00000000";A7<="00000000";
elsifA="01"then--甲出剪刀
A0<="00000000";A1<="00000000";A2<="00100000";A3<="11000000";
A4<="11000000";A5<="00100000";A6<="00000000";A7<="00000000";
elsifA="10"then--甲出石头
A0<="00000000";A1<="00000000";A2<="01000000";A3<="11100000";
A4<="11100000";A5<="01000000";A6<="00000000";A7<="00000000";
else
casetemp1is--甲获胜,显示动画
when0=>--显示“甲”
A0<="11111110";
A1<="10010010";
A2<="11111110";
A3<="10010010";
A4<="11111110";
A5<="00010000";
A6<="00010000";
A7<="00010000";
when1=>--显示“获”
A0<="00101000";
A1<="11111110";
A2<="10101000";
A3<="01001010";
A4<="10111110";
A5<="01101000";
A6<="10101100";
A7<="01110010";
when2=>--显示“胜”
A0<="11100100";
A1<="10110100";
A2<="11111111";
A3<="10100100";
A4<="11111111";
A5<="10100100";
A6<="10100100";
A7<="10111111";
when3=>--显示笑脸
A0<="00111100";
A1<="01000010";
A2<="10000001";
A3<="10100101";
A4<="10000001";
A5<="10100101";
A6<="01011010";
A7<="00111100";
when4=>--显示笑脸
A0<="00111100";
A1<="01000010";
A2<="10000001";
A3<="10100101";
A4<="10000001";
A5<="10100101";
A6<="01011010";
A7<="00111100";
when5=>--显示空白
A0<="00000000";A1<="00000000";A2<="00000000";A3<="00000000";
A4<="00000000";A5<="00000000";A6<="00000000";A7<="00000000";
whenothers=>NULL;
endcase;
endif;
ifB="00"then--乙出布
B0<="00000000";B1<="00000000";B2<="00000111";B3<="00000111";
B4<="00000111";B5<="00000111";B6<="00000000";B7<="0000