北邮数电实验猜数字.docx
- 文档编号:12876804
- 上传时间:2023-04-22
- 格式:DOCX
- 页数:40
- 大小:946.08KB
北邮数电实验猜数字.docx
《北邮数电实验猜数字.docx》由会员分享,可在线阅读,更多相关《北邮数电实验猜数字.docx(40页珍藏版)》请在冰豆网上搜索。
北邮数电实验猜数字
题目:
简易猜数字游戏机的设计与实现
姓名
学院电子工程学院
专业电子信息科学与技术
班级
学号
班内序号
一、设计课题的任务要求
●基本要求:
1、游戏规则:
通常由两个人玩,一方出数字,另一方猜。
出数字的人要想好一个没有重复数字的4位数,不能让猜的人知道。
2、数字设置:
通过4*4键盘进行4位数字输入,在数码管(DISP0~DISP3)上显示当前所输入的数字。
通过设置确定键(BTN1键)进行锁定,此时数码管上的数值消失,同时用点阵开始倒计时,即:
初始状态点阵全亮,然后从右下角开始,由右到左、由下到上逐点逐排依次熄灭,间隔时间为1s,共计64s。
3、猜数字:
可以通过4*4键盘进行4位数字输入进行猜数字,且每输入一位数字在数码管(DISP0~DISP3)上显示当前所输入的数字,按确定键(BTN2键)进行确认,此时要根据输入的这组数字给出几A几B,其中:
A前面的数字表示位置正确的数的个数,用DISP5显示;B前的数字表示数字正确而位置不对的数的个数,用DISP4显示;如正确答案为2134,而猜的人猜5314,则是1A2B,其中有一个4的位置对了,记为1A,而1和3这三个数字对了,而位置没对,因此记为2B,合起来就是1A2B;接着猜的人再根据出题者的几A几B继续猜,直到猜中(即4A0B)为止。
4、若数字正确则显示猜数字成功,点阵显示“☺”笑脸;若输入数字错误系统仍然处于猜数字状态,点阵显示“X”,并用蜂鸣器或led闪烁报警。
5、若到点阵全灭时(64s结束)仍未猜出正确数字,游戏失败,点阵显示“囧”。
6、设置游戏机开关。
●提高要求:
1、若数字正确则显示猜数字成功,用蜂鸣器播放一段乐曲。
2、随机产生数字,并不在数码管上显示,进行猜数字游戏,用点阵进行128s计时,即点阵轮询熄灭两次,其他要求同基本功能3、4和5。
3、自拟其他功能。
二、系统设计
●设计思路:
1、模块设计:
根据任务要求,分开文件进行编写,方便编译与debug。
将设计分为以下几个模块:
guess(顶层文件)、dianzhen(点阵显示模块)、shumaguan(数码管显示模块)、keyboard(键盘扫描模块)、calculate(计算A/B个数模块)。
2、状态设计:
根据任务要求,由于确定键的按下时机不同,将设计细分为以下11个状态:
SS:
初始状态;
S0:
被猜数字输入一位;
S1:
被猜数字输入两位;
S2:
被猜数字输入三位;
S3:
被猜数字输入四位;
S4:
ans键按下,计时开始,但未输入所猜数字;
S5:
猜数字状态,输入一位;
S6:
猜数字状态,输入一位;
S7:
猜数字状态,输入一位;
S8:
猜数字状态,输入一位;
S9:
输入数字正确;
S10:
输入数字错误;
S11:
时间到,显示(囧);
●总体框图:
●分块设计:
1、点阵显示模块(dianzhen)
将“☺”笑脸、“囧”字、“×”符号单独编写状态显示,如下:
笑脸:
“囧”字:
“×”符号:
其余64种情况,将计数变量tmp1除以64取余,形成0—63依次出现,使用case语句,一个数字代表一个点发亮,将小于当前倒计时数的点逐点扫描。
部分截取如下:
2、数码管显示模块(shumaguan)
区分段选与位选,将不同数字的段选编入代码,扫频显示。
如下:
3、键盘扫描模块(keyboard)
将四行赋予为两位二进制数,逐行扫描,按下为0,不按为1。
部分截取如下:
防抖写在顶层文件中,截取如下:
说明:
flag是有数字输入的标志,&为按位与,如果出现抖动,则会出现重复输入情况,不允许出现,设计中将其排除。
4、计算A/B个数模块(calculate)
如果输入与设定数字相同且位置相同,则A+1,如果输入与设定数字相同但位置不同,则B+1。
因为是0—9,十个数字,所以用四位二进制表示。
部分截取如下:
三、仿真波形及波形分析
四、源程序(见附件)
代码已附在最后
五、功能说明及资源利用情况
●功能说明
开始时按BTN3,reset,LED0亮表示等待输入被猜数字;
依次输入四位被猜数字,每输入一位,LED1—LED4依次亮起,表示输入成功;
按下BTN0,确认被猜数字,此时LED1—LED4熄灭;
依次输入四位试探数字,每输入一位,LED5—LED0依次亮起,表示输入成功;
按下BTN1,确认试探数字;
如果猜错,点阵显示“×”符号,蜂鸣器报警,左边两个数码管显示A、B的数量,一秒后自动复原;
直到完全猜对,点阵显示“☺”笑脸,LED全亮,表示游戏成功;
如果在64秒内没有猜对,64秒时点阵显示“囧”字,表示游戏失败。
●资源利用情况
如图:
六、故障及问题分析
●起始设计7种状态,没有将输入每一位数字单独设立出来,但是面临确认键不能统一问题。
所以将输入每一位数字单独设立,虽然此方法重复性高,但是很简便的解决了确认键问题。
●点阵亮度低问题。
笑脸、“囧”字和“×”符号亮度均正常,但是倒计时时亮度偏低。
根据以往发生过的情况,将行扫描调整为列扫描,但是问题没有解决。
后来经过思考,因为本设计倒计时中点阵扫描是逐点扫描,同样扫描频率下,倒计时比其他扫描频率低1/64,加之本身扫描频率设计为5kHz,过高,所以发生上述情况。
七、总结和结论
本次数电综合实验中,从第一节课的框图初次设计,到后来的设计调整尤其是状态图调整,经历了一定曲折,是发现问题并且解决问题的过程。
本次实验中,我巩固了VHDL的基本语法;将一个较大的设计拆分成为不同的模块,并将他们组合起来;通过查询资料和小组讨论将设计思路整理清楚,并通过代码实现。
其间出现过符号中英文转换等小问题,也出现过点阵显示亮度不高等问题,最终实现了要求功能。
现将部分现场照片展示如下:
附程序:
Guess
libraryieee;
useieee.std_logic_1164.all;
useieee.std_logic_unsigned.all;
entityguessis--biubiubiu!
port(
res,clk:
instd_logic;
gus:
instd_logic;
ans:
instd_logic;
beep:
outstd_logic;
led_out:
outstd_logic_vector(7downto0);
kbrow:
outstd_logic_vector(3downto0);
kbcol:
instd_logic_vector(3downto0);
col:
outstd_logic_vector(7downto0);
row:
outstd_logic_vector(7downto0);
seg_out:
outstd_logic_vector(6downto0);
cat:
outstd_logic_vector(5downto0)
);
endguess;
architecturetopofguessis
componentkeyboardis
port(clk:
instd_logic;
kbrow:
outstd_logic_vector(3downto0);
kbcol:
instd_logic_vector(3downto0);
num_out:
outstd_logic_vector(9downto0)
);
endcomponentkeyboard;
componentdianzhenis
port(
switch_d:
instd_logic;
start:
instd_logic;
smile:
instd_logic;
error:
instd_logic;
clk:
instd_logic;
col:
outstd_logic_vector(7downto0);
row:
outstd_logic_vector(7downto0);
beep:
outstd_logic;
endtime:
outstd_logic
);
endcomponentdianzhen;
componentshumaguanis
port(
clk:
instd_logic;
switch_s:
instd_logic;
num_in:
instd_logic_vector(23downto0);
seg_out:
outstd_logic_vector(6downto0);
cat:
outstd_logic_vector(5downto0)
);
endcomponentshumaguan;
componentcalculateis
port(
clk:
instd_logic;
num_gus,num_ans:
instd_logic_vector(15downto0);
An,Bn:
outstd_logic_vector(3downto0)
);
endcomponentcalculate;
Typestateis(ss,s0,s1,s2,s3,s4,s5,s6,s7,s8,s9,s10,s11);
signals_state:
state;
signalnum_in1:
std_logic_vector(9downto0);
signalnum_in2:
std_logic_vector(3downto0);
signalnum_out1:
std_logic_vector(23downto0);
signalnum_gus:
std_logic_vector(15downto0);
signalnum_ans:
std_logic_vector(15downto0);
signalswitch_d,switch_s,start,smile,error,endtime:
std_logic;
signalflag:
std_logic;
signalAn,Bn:
std_logic_vector(3downto0);
signalcount_x:
integerrange1to25000000;
begin
u0:
keyboardportmap(clk=>clk,kbrow=>kbrow,kbcol=>kbcol,num_out=>num_in1);
u1:
dianzhenportmap(switch_d=>switch_d,start=>start,smile=>smile,error=>error,clk=>clk,col=>col,row=>row,beep=>beep,endtime=>endtime);
u2:
shumaguanportmap(clk=>clk,switch_s=>switch_s,num_in=>num_out1,seg_out=>seg_out,cat=>cat);
u3:
calculateportmap(clk=>clk,num_gus=>num_gus,num_ans=>num_ans,An=>An,Bn=>Bn);
process(clk,num_in2,res)
begin
flag<=not(num_in2(3)andnum_in2
(2)andnum_in2
(1)andnum_in2(0));
ifres='1'then
s_state<=ss;
elsifclk'eventandclk='1'then
cases_stateis
whenss=>--初始状态
switch_d<='0';
switch_s<='1';
start<='0';
smile<='0';
error<='0';
num_out1<="111111111111111111111111";
led_out<="10000000";
num_ans<="1111111111111111";
num_gus<="1111111111111111";
if(flag='1')then
num_ans<=num_in2&"111111111111";
num_out1<=num_ans&"11111111";
s_state<=s0;
else
s_state<=ss;
endif;
whens0=>--被猜数字输入一位状态
num_out1<=num_ans&"11111111";
switch_d<='0';
start<='0';
smile<='0';
error<='0';
led_out<="01000000";
if(flag='1')then
if(num_in2=(num_ans(15)&num_ans(14)&num_ans(13)&num_ans(12)))then
s_state<=s0;
else
num_ans<=num_ansand("1111"&num_in2&"11111111");
num_out1<=num_ans&"11111111";
s_state<=s1;
endif;
else
s_state<=s0;
endif;
whens1=>--被猜数字输入两位状态
num_out1<=num_ans&"11111111";
switch_d<='1';
start<='0';
smile<='0';
error<='0';
led_out<="01100000";
if(flag='1')then
if(num_in2=(num_ans(11)&num_ans(10)&num_ans(9)&num_ans(8)))then
s_state<=s1;
else
num_ans<=num_ansand("11111111"&num_in2&"1111");
num_out1<=num_ans&"11111111";
s_state<=s2;
endif;
else
s_state<=s1;
endif;
whens2=>--被猜数字输入三位状态
num_out1<=num_ans&"11111111";
switch_d<='1';
start<='0';
smile<='0';
error<='0';
led_out<="01110000";
if(flag='1')then
if(num_in2=(num_ans(7)&num_ans(6)&num_ans(5)&num_ans(4)))then
s_state<=s2;
else
num_ans<=num_ansand("111111111111"&num_in2);
num_out1<=num_ans&"11111111";
s_state<=s3;
endif;
else
s_state<=s2;
endif;
whens3=>--被猜数字输入四位状态
num_out1<=num_ans&"11111111";
switch_d<='1';
start<='1';
smile<='0';
error<='0';
led_out<="01111000";
if(ans='1')then
s_state<=s4;
else
s_state<=s3;
endif;
whens4=>--ans键按下,计时开始,但未输入所猜数字状态
num_out1<="111111111111111111111111";
start<='0';
switch_d<='1';
smile<='0';
error<='0';
led_out<="01111000";
if(endtime='1')then
s_state<=s11;
elsif(flag='1')then
num_gus<=num_in2&"111111111111";
num_out1<=num_gus&"11111111";
s_state<=s5;
else
s_state<=s4;
endif;
whens5=>--猜数字状态:
输入一位
num_out1<=num_gus&"11111111";
start<='0';
switch_d<='1';
smile<='0';
error<='0';
led_out<="01111100";
if(endtime='1')then
s_state<=s11;
elsif(flag='1')then
if(num_in2=(num_gus(15)&num_gus(14)&num_gus(13)&num_gus(12)))then
s_state<=s5;
else
num_gus<=num_gusand("1111"&num_in2&"11111111");
num_out1<=num_gus&"11111111";
s_state<=s6;
endif;
else
s_state<=s5;
endif;
whens6=>--猜数字状态:
输入两位
num_out1<=num_gus&"11111111";
start<='0';
switch_d<='1';
smile<='0';
error<='0';
led_out<="01111110";
if(endtime='1')then
s_state<=s11;
elsif(flag='1')then
if(num_in2=(num_gus(11)&num_gus(10)&num_gus(9)&num_gus(8)))then
s_state<=s6;
else
num_gus<=num_gusand("11111111"&num_in2&"1111");
num_out1<=num_gus&"11111111";
s_state<=s7;
endif;
else
s_state<=s6;
endif;
whens7=>--猜数字状态:
输入三位
num_out1<=num_gus&"11111111";
start<='0';
switch_d<='1';
smile<='0';
error<='0';
led_out<="01111111";
if(endtime='1')then
s_state<=s11;
elsif(flag='1')then
if(num_in2=(num_gus(7)&num_gus(6)&num_gus(5)&num_gus(4)))then
s_state<=s7;
else
num_gus<=num_gusand("111111111111"&num_in2);
num_out1<=num_gus&"11111111";
s_state<=s8;
endif;
else
s_state<=s7;
endif;
whens8=>--猜数字状态:
输入四位
num_out1<=num_gus&"11111111";
start<='0';
switch_d<='1';
smile<='0';
error<='0';
count_x<=1;
led_out<="11111111";
if(endtime='1')then
s_state<=s11;
elsif(gus='1')then
if(An="0100"andBn="0000")then
num_out1<=num_gus&An&Bn;
s_state<=s9;
else
count_x<=1;
s_state<=s10;
endif;
else
s_state<=s8;
endif;
whens9=>--right
start<='0';
switch_d<='1';
smile<='1';
error<='0';
led_out<="00000001";
whens10=>--wrong
num_out1<=num_gus&An&Bn;
start<='0';
switch_d<='1';
smile<='0';
error<='1';
led_out<="00001010";
if(endtime='1')then
s_state<=s11;
elsif(count_x=25000000)then
s_state<=s4;
else
count_x<=count_x+1;
s_state<=s10;
endif;
whens11=>--timeup!
jiong!
num_out1<="111111111111111111111111";
start<='0';
switch_d<='1';
smile<='0';
error<='0';
led_out<="00001011";
endcase;
endif;
endprocess;
INPUT:
PROCESS(clk)
BEGIN
ifclk'eventandclk='0'then
CASEnum_in1IS
WHEN"1000000000"=>num_in2<="0000";--0
WHEN"0100000000"=>num_in2<="0001";--1
WHEN"0010000000"=>num_in2<="0010";--2
WHEN"0001000000"=>num_in2<="0011";--3
WHEN"0000100000"=>num_in2<="0100";--4
WHEN"0000010000"=>num_in2<="0101";--5
WHEN"0000001000"=>num_in2<="0110";--6
WHEN"0000000100"=>num_in2<="0111";--7
WHEN"0000000010"=>num_in2<="1000";--8
WHEN"0000000001"=>num_in2<="1001";--9
WHENOTHERS=>num_in2<="1111";
ENDCASE;
endif;
endprocessinput;
endtop;
Dianzhen
lib
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 北邮数电 实验 数字