数字电路与逻辑设计实验报告打地鼠游戏的设计与实现学院:信息与通信工程学院班级:2013211117姓名:李昊然学号:2013210486序号:02课题:打地鼠一.课题的任务要求基本要求:1、设计一个挑战反应速度的“打地鼠”游戏,采用用8×8双色点阵显示游戏界面,其中游戏边界采用绿色LED显示,随机出现的地鼠采用红色LED显示,游戏有16个洞穴,如图1所示。图1打地鼠游戏示意图2、游戏洞穴每次随机出现一个地鼠,每个地鼠的最长保持时间为2秒,2秒后随机出现下一个地鼠。以4×4键盘的按键代表锤子,16个洞穴与16个按键一一对应,一旦锤子在2秒内击中地鼠,地鼠消失,数码管计分器分数加1分;若锤子一直没有击中地鼠,2秒后该地鼠消失。用两个数码管显示游戏成绩,当游戏成绩达到10分时游戏结束,点阵显示字符“V”。3、用两个数码管对整个游戏进行倒计时,当游戏时间超过59秒而成绩未达到10分时,游戏失败,点阵显示字符“X”。4、按复位键重新开始游戏,并开始倒计时。提高要求:1、增加游戏难关,在边界内每次随机出现两个地鼠,两个地鼠的最长保持时间均为2秒,2秒后随机出现下两个地鼠,锤子击中一个地鼠加1分,当游戏成绩达到20分而且游戏时间未超过59秒时,游戏结束,显示字符“V”,否则显示字符“X”。2、自拟其他功能。二.系统设计(一)设计思路程序采用自顶向下设计的思路,先将主程序启动,然后依次进行多级分频,并逐个执行子程序,主程序为点阵中显示边框背景及随机出现地鼠,子程序包括数码管计分和计时部分、时钟部分、键盘部分以及逻辑判断部分等。(二)总体框图开始生成边框生成随机位置地鼠打地鼠2s内击中地鼠60s是否到时加1分积分是否达到10分赢输结束是是否否(三)分块设计1.输入部分:外部时钟信号CLK频率为25MHz,为程序提供初始的有效时钟边沿。复位信号输入CLEAR为高电平有效,当CLEAR为1时,数码管、点阵、计数器等都返回到初始状态。键盘输入值由两个四位二进制数分别表示行和列的状态。2.逻辑判断模块:通过检测键盘返回值是否与点阵上出现地鼠的位置相对应,判断“打”是否有效。通过60s倒计时的计数器是否为0判断游戏是否到时。通过一个模为10的计数器判断得分是否达到游戏要求。3.输出部分:由译码电路,根据SEG_SELECT信号的扫描、对SEG_SHOW赋予不同的值,实现在四个数码管上分别显示两位60s倒计时和两位计分。点阵根据LED_ROW的扫描、和LED_COL_G、LED_COL_R的值显示游戏的边框、地鼠出现的位置以及结束画面,利用人眼的视觉延缓效应,当行扫描时钟信号clk的频率50Hz,可以达到六行点阵同时显示的效果。4.键盘输入部分:以1kHz的频率进行列扫描,将键盘检测到的行和列的二进制数KEY_COL和KEY_ROW组合起来,赋值给一个四位二进制数CODE,记录按键的位置,方便与地鼠在点阵上的位置相比较。三.仿真波形及波形分析1.分频由波形可知,对输入时钟信号clk进行了4倍分频2.绿色灯示边框在行数为1和6时,每列都亮,在行数为2、3、4、5时,亮第1和第6列,从而形成一个6*6的边框。3.随机出现地鼠地鼠可能出现在随机的行和列当lose信号为1时,点阵显示×4.数码管会在第一个到第四个之间来回扫描5.给键盘行值赋予一个随机值,程序进行列扫描,当键盘输入值与点阵值相对应时,积分信号score会+1,由于是随机赋值,所以恰好碰上的概率较小,加分的时间较长四.源程序LIBRARYIEEE;USEIEEE.STD_LOGIC_1164.ALL;USEIEEE.STD_LOGIC_UNSIGNED.ALL;ENTITYddsISPORT(CLK:INSTD_LOGIC;--输入时钟LED_ROW:OUTSTD_LOGIC_VECTOR(7DOWNTO0);--点阵行LED_COL_G:OUTSTD_LOGIC_VECTOR(7DOWNTO0);--点阵列绿色LED_COL_R:OUTSTD_LOGIC_VECTOR(7DOWNTO0);--点阵列红色SEG_SELECT:OUTSTD_LOGIC_VECTOR(5DOWNTO0);--数码管位置扫描SEG_SHOW:OUTSTD_LOGIC_VECTOR(6DOWNTO0);--数码管显示KEY_COL:OUTSTD_LOGIC_VECTOR(3DOWNTO0);--键盘列KEY_ROW:INSTD_LOGIC_VECTOR(3DOWNTO0);--键盘行CLEAR:INSTD_LOGIC;--复位信号LIGHT:OUTSTD_LOGIC_VECTOR(7DOWNTO0)--输出灯);ENDdds;ARCHITECTUREaOFddsISSIGNALTEMP_LED_ROW:STD_LOGIC_VECTOR(7DOWNTO0);--DIANZHENSIGNALTEMP_LED_COLG:STD_LOGIC_VECTOR(7DOWNTO0);SIGNALTEMP_LED_COLR:STD_LOGIC_VECTOR(7DOWNTO0);SIGNALTEMP_SEG_SELECT:STD_LOGIC_VECTOR(5DOWNTO0):=011111;--SHUMAGUANSIGNALTEMP_SEG1:STD_LOGIC_VECTOR(6DOWNTO0);SIGNALTEMP_SEG2:STD_LOGIC_VECTOR(6DOWNTO0);SIGNALTEMP_SEG3:STD_LOGIC_VECTOR(6DOWNTO0);SIGNALTEMP_SEG4:STD_LOGIC_VECTOR(6DOWNTO0);SIGNALRANDOM:STD_LOGIC_VECTOR(3DOWNTO0);--SUIJISHUSIGNALTEMP_RANDOM:STD_LOGIC_VECTOR(3DOWNTO0);SIGNALDIV_1K:INTEGERRANGE0TO12499;--FENPIN0.001SSIGNALDIV_1S:INTEGERRANGE0TO499;--FENPIN1SSIGNALDIV_2S:INTEGERRANGE0TO999;--FENPIN2SSIGNALDIV_R:INTEGERRANGE0TO998;--FENPINSUIJISIGNALTEMP_10:INTEGERRANGE0TO9;--DAOJISHISHIWEISIGNALCLK_1K:STD_LOGIC;--SHIZHONGSIGNALCLK_1S:STD_LOGIC;SIGNALCLK_2S:STD_LOGIC;SIGNALCLK_R:STD_LOGIC;--SIGNALCLKTEMP:STD_LOGIC;SIGNALTEMP_KEY_COL:STD_LOGIC_VECTOR(3DOWNTO0);--JIANPANSIGNALTEMP_KEY_ROW:STD_LOGIC_VECTOR(3DOWNTO0);SIGNALCODE:STD_LOGIC_VECTOR(3DOWNTO0);SIGNALTEMP_LIGHT:STD_LOGIC_VECTOR(7DOWNTO0);SIGNALPOKE:INTEGERRANGE0TO1;--DADISHUSIGNALPOKE_FLAG:INTEGERRANGE0TO1:=0;--DABIAOZHIWEISIGNALSCORE:INTEGERRANGE0TO10;--DEFENSIGNALSCORE_FLAG:INTEGERRANGE0TO1;--DEFENBIAOZHIWEISIGNALCOUNTDOWN_60:INTEGERRANGE0TO60;--60SDAOJISHISIGNALWIN:INTEGERRANGE0TO1;--YINGSIGNALLOSE:INTEGERRANGE0TO1;--SHUSIGNALCLEAR_TEMP:STD_LOGIC;--FUWEIBEGINP1:PROCESS(CLK)--DIV0.001SBEGINIFCLK'EVENTANDCLK='1'THENIFDIV_1K=12499THEN--计数12500次DIV_1K=0;CLK_1K=NOTCLK_1K;--clk_1k翻转两次ELSEDIV_1K=DIV_1K+1;ENDIF;ENDIF;ENDPROCESSP1;P2:PROCESS(CLK_1K)--DIV1sBEGINIFCLK_1K'EVENTANDCLK_1K='1'THENIFDIV_1S=499THENDIV_1S=0;CLK_1S=NOTCLK_1S;ELSEDIV_1S=DIV_1S+1;ENDIF;ENDIF;ENDPROCESSP2;P3:PROCESS(CLK_1K)--DIV2SBEGINIFCLK_1K'EVENTANDCLK_1K='1'THENIFDIV_2S=999THENDIV_2S=0;CLK_2S=NOTCLK_2S;ELSEDIV_2S=DIV_2S+1;ENDIF;--比较键盘输入值和地鼠位置是否相同,判断有没有打到IF((CODE=0000ANDTEMP_RANDOM=1100)OR(CODE=0001ANDTEMP_RANDOM=0000)OR(CODE=0010ANDTEMP_RANDOM=0100)OR(CODE=0011ANDTEMP_RANDOM=1000)OR(CODE=0100ANDTEMP_RANDOM=1101)OR(CODE=0101ANDTEMP_RANDOM=0001)OR(CODE=0110ANDTEMP_RANDOM=0101)OR(CODE=0111ANDTEMP_RANDOM=1001)OR(CODE=1000ANDTEMP_RANDOM=1110)OR(CODE=1001ANDTEMP_RANDOM=0010)OR(CODE=1010ANDTEMP_RANDOM=0110)OR(CODE=1011ANDTEMP_RANDOM=1010)OR(CODE=1100ANDTEMP_RANDOM=1111)OR(CODE=1101ANDTEMP_RANDOM=0011)OR(CODE=1110ANDTEMP_RANDOM=0111)OR(CODE=1111ANDTEMP_RANDOM=1011))THENPOKE=1;ELSEPOKE=0;SCORE_FLAG=0;--标志位,防止按一次计分多次ENDIF;IF(POKE=1ANDSCORE_FLAG=0ANDPOKE_FLAG=1)THEN—若打到则计一分CLK_2S=NOTCLK_2S;--DIV_2S=0;SCORE_FLAG=1;--计分后标志位变1SCORE=SCORE+1;ENDIF;IFCLEAR_TEMP='1'THEN--若复位信号为高电平,恢复初始值SCORE=0;ENDIF;ENDIF;ENDPROCESSP3;P4:PROCESS(CLK)--randomtime--通过与2s时钟不同频率的时钟产生随机数BEGINIFCLK'EVENTANDCLK='1'THENIFDIV_R=233THENDIV_R=0;CLK_R=NOTCLK_R;ELSEDIV_R=DIV_R+1;ENDIF;ENDIF;ENDPROCESSP4;P5:PROCESS(CLK_R)--randomnumber--产生代表地鼠位置的随机数BEGINIF(CLK_R'EVENTANDCLK_R='1')THENCASERANDOMISWHEN0000=RANDOM=0001;WHEN0001=RANDOM=0010;WHEN0010=RANDOM=0011;WHEN0011=RANDOM=0100;WHEN0100=RANDOM=0101;WHEN0101=RANDOM=0110;WHEN0110=RANDOM=0111;WHEN0111=RANDOM