VHDL-贪吃蛇游戏实验报告_第1页
VHDL-贪吃蛇游戏实验报告_第2页
VHDL-贪吃蛇游戏实验报告_第3页
VHDL-贪吃蛇游戏实验报告_第4页
VHDL-贪吃蛇游戏实验报告_第5页
已阅读5页,还剩17页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

2/221/22贪吃蛇游戏摘要:本实验以设计贪吃蛇游戏为课题。最终结果是以8*8点阵作为本游戏的显示界面,通过按键BTN1,BTN2,BTN3,BTN4分别控制蛇的运动方向,分别为“上下左右”。蛇的长度为六个点阵,另外以一点表示老鼠,当蛇头吃到老鼠时,老鼠则在点阵上改变位置,也就是说通过一个伪随机函数在点阵上产生老鼠的位置,每当蛇头吃到老鼠时,就自动加一分,并在数码管显示。每隔五分钟,在蛇没有吃到老鼠的前提下,老鼠就自动在点阵上改变位置,这样就增加了游戏的趣味性和难度性。关键字:8*8点阵,贪吃蛇,数码管,EPM7128SLC8—15数电实验开发板课题设计任务及要求:简要说明:用一个8×8点阵作为基本显示屏,六个连续移动的的发光点表示一条蛇,用任意出现的一个亮点表示老鼠,用4个排成一条线的发光点表示“墙”,用四个按键控制蛇的运动方向,完成贪食蛇游戏,蛇撞“墙”、边或者游戏时间到,则游戏结束。1.老鼠出现的地方是随机的,在某个地点出现的时间是5秒钟,如果5秒钟之内没有被吃掉,它就会在其它地方出现;2.用数码管显示得分情况和游戏的剩余时间,每吃掉一只老鼠就加一分;3.游戏时间和速度可以手动设置。4.选做:增加游戏难度或自拟其它功能。设计思路:当开启电源时,初始化EPM7128SLC8—15数电实验开发板。8*8点阵也初始化,每来一个时钟脉冲就对8*8点阵进行一次扫描,并依次点亮六个蛇身和一个老鼠所对应的点,由于扫描频率是1MHz(远远超出人眼所能分辨的范围),故人眼看来蛇身是连续的。用BTN1,BTN2,BTN3,BTN4键分别控制蛇的运动方向“上下左右”,每次按键时通过和蛇原来的运动方向进行比较来控制蛇接下来的运动方向。在七段数码管上显示得分情况,每当蛇吃到一个老鼠时则自动加一分,并在数码管上显示出当前得分。设置一个控件SW1来对得分进行复位,即每当SW1有效时,则得分清零。总体框架图:初始化8*8点阵初始化8*8点阵1MHZ晶振,产生时钟信号CLK1MHZ晶振,产生时钟信号CLK10e610e6分频蛇在8*8点阵上显示,并按照初始化时的方向向前移动蛇在8*8点阵上显示,并按照初始化时的方向向前移动通过控件BTN1,BTN2,BTN3,BNT4输入蛇的运动方向比较1S时钟信号CLK1比较1S时钟信号CLK11MHz时钟CLK在七段数码管显示得分5S内蛇还没吃到老鼠,则老鼠自动改变位置没有吃到老鼠,蛇继续向前运动5分频,CLK2,周期为5S通过比较决定蛇的运动方向老鼠在8*8点阵上显示吃到老鼠,在数码管显示上加一分,蛇继续保持向前运动否判断蛇是否吃到老鼠是1MHz时钟CLK在七段数码管显示得分5S内蛇还没吃到老鼠,则老鼠自动改变位置没有吃到老鼠,蛇继续向前运动5分频,CLK2,周期为5S通过比较决定蛇的运动方向老鼠在8*8点阵上显示吃到老鼠,在数码管显示上加一分,蛇继续保持向前运动否判断蛇是否吃到老鼠是控制器部分的状态转移图(MDS图):蛇的运动方向snake_m设置为两位二进制的变量:假设“00”表示“上”,“01”表示“下”,“10”表示“左”,“11”表示“右”;控制方向dir也设置为两位二进制变量:假设“00”表示“上”,“01”表示“下”,“10”表示“左”,“11”表示“右”。则蛇运动方向的状态转移图如下:DDir=”00”ordir=”01”SSnake_m=”00”DDir=”11”Dir=”00”DDir=”00”Dir=”10”Dir=”11”Dir=”01”Dir=”01”Dir=”11”Dir=”01”Dir=”01”Dir=”01”ordir=”00”Dir=”11”ordir=”10”Dir=”10”ordir=”11”Snake_m=”10”Snake_m=“01”Snake_m=”11”Dir=”00”DDir=”10”流程图:按照系统的设计思路其流程图如下:NoNoYesYes撞到墙或边?游戏结束时间到?加1分,蛇继续移动老鼠出现在其它地方Yes5秒内吃到老鼠?No蛇开始移动启动NoNoYesYes撞到墙或边?游戏结束时间到?加1分,蛇继续移动老鼠出现在其它地方Yes5秒内吃到老鼠?No蛇开始移动启动分块电路和总体电路的设计:总体电路的设计:在本课题中最主要的是如何让蛇在8*8点阵上显示并且让蛇身在点阵上移动。为此我设置snake_x和snake_y这两个变量,这两个变量定义为word型,word数据类型是我自己定义的(typewordisarray(1to7)ofstd_logic_vector(2downto0))。意思是说,snake_x和snake_y是一个数组(从1到7),其值是3位的二进制变量(从“000”到“111”),分别为点阵的横坐标和纵坐标。这样当蛇移动时只要把前一个点的值赋给后一个点的值,对于第一个点则需判断其当前方向来决定其下一步的移动方向,例如:当蛇的移动方向为上,即snake_m=“00”,则当控制方向为左,即dir=“10”,则代码如下:if(snake_m="00")then if(dir="10")then snake_m<="10"; if(snake_m="10")and(snake_x(1)="000")then--左, snake_x(6)<=snake_x(5); snake_x(5)<=snake_x(4); snake_x(4)<=snake_x(3); snake_x(3)<=snake_x(2); snake_x(2)<=snake_x(1); snake_y(6)<=snake_y(5); snake_y(5)<=snake_y(4); snake_y(4)<=snake_y(3); snake_y(3)<=snake_y(2); snake_y(2)<=snake_y(1); snake_x(1)<="111"; elsif(snake_m="10")then snake_x(6)<=snake_x(5); snake_x(5)<=snake_x(4); snake_x(4)<=snake_x(3); snake_x(3)<=snake_x(2); snake_x(2)<=snake_x(1); snake_y(6)<=snake_y(5); snake_y(5)<=snake_y(4); snake_y(4)<=snake_y(3); snake_y(3)<=snake_y(2); snake_y(2)<=snake_y(1); snake_x(1)<=snake_x(1)-1;这就解决了蛇的移动问题,另外对于显示模块和控制模块比较简单,在分块电路设计中将分别介绍。分块电路设计:控制方向模块:通过按键BTN1,BTN2,BTN3,BTN4来控制蛇的移动方向,其源代码如下: process(clk) begin if(clk'event)and(clk='0')then--shang,xiazou,you if(key="1000")then--shang dir<="00"; elsif(key="0100")then--xia dir<="01"; elsif(key="0010")then--zou dir<="10"; elsif(key="0001")then--you dir<="11"; endif; endif; endprocess;时钟分频模块:由于系统所用的晶振为1MHZ,而要求是蛇1S移动一次,这就要1MHZ晶振进行分频,采用10e6分频,是分频得到的时钟CLK2周期为1S,其设计源代码如下:P0:process(clk)beginif(clk'eventandclk='1')then ifcount=1000000then count<=0; clk1<=notclk1; else count<=count+1; endif;endif;扫描显示模块:扫描显示时每来一个时钟就对整个8*8点阵全部扫描一次,由于点阵上的点亮的条件是行为高电平‘1’,列为低电平‘0’时,则对应的点就被点亮,其源代码如下:process(clk)--显示部分begin if(clk'eventandclk='1')then ifcount1=8then count1<=1; elsecount1<=count1+1; endif; casesnake_x(count1)is when"000"=>rown<="10000000"; when"001"=>rown<="01000000"; when"010"=>rown<="00100000"; when"011"=>rown<="00010000"; when"100"=>rown<="00001000"; when"101"=>rown<="00000100"; when"110"=>rown<="00000010"; when"111"=>rown<="00000001"; whenothers =>rown<="00000000"; endcase; casesnake_y(count1)is when"000"=>coln<="01111111"; when"001"=>coln<="10111111"; when"010"=>coln<="11011111"; when"011"=>coln<="11101111"; when"100"=>coln<="11110111"; when"101"=>coln<="11111011"; when"110"=>coln<="11111101"; when"111"=>coln<="11111110"; whenothers =>coln<="11111111"; endcase; endif;col<=coln;row<=rown;endprocess;蛇身移动模块:蛇身移动时首先判断蛇的移动方向snake_m,然后和控制方向dir进行比较,按照上述状态转移图进行程序的编写,其源代码如下:process(clk1)--蛇的运动 begin if(clk1'eventandclk1='1')then if(snake_m="10")and(snake_x(1)="000")then--左, snake_x(6)<=snake_x(5); snake_x(5)<=snake_x(4); snake_x(4)<=snake_x(3); snake_x(3)<=snake_x(2); snake_x(2)<=snake_x(1); snake_y(6)<=snake_y(5); snake_y(5)<=snake_y(4); snake_y(4)<=snake_y(3); snake_y(3)<=snake_y(2); snake_y(2)<=snake_y(1); snake_x(1)<="111"; elsif(snake_m="10")then snake_x(6)<=snake_x(5); snake_x(5)<=snake_x(4); snake_x(4)<=snake_x(3); snake_x(3)<=snake_x(2); snake_x(2)<=snake_x(1); snake_y(6)<=snake_y(5); snake_y(5)<=snake_y(4); snake_y(4)<=snake_y(3); snake_y(3)<=snake_y(2); snake_y(2)<=snake_y(1); snake_x(1)<=snake_x(1)-1; elsif(snake_m="00")and(snake_y(1)="111")then--上 snake_x(6)<=snake_x(5); snake_x(5)<=snake_x(4); snake_x(4)<=snake_x(3); snake_x(3)<=snake_x(2); snake_x(2)<=snake_x(1); snake_y(6)<=snake_y(5); snake_y(5)<=snake_y(4); snake_y(4)<=snake_y(3); snake_y(3)<=snake_y(2); snake_y(2)<=snake_y(1); snake_y(1)<="000"; elsif(snake_m="00")then snake_x(6)<=snake_x(5); snake_x(5)<=snake_x(4); snake_x(4)<=snake_x(3); snake_x(3)<=snake_x(2); snake_x(2)<=snake_x(1); snake_y(6)<=snake_y(5); snake_y(5)<=snake_y(4); snake_y(4)<=snake_y(3); snake_y(3)<=snake_y(2); snake_y(2)<=snake_y(1); snake_y(1)<=snake_y(1)+1; elsif(snake_m="11")and(snake_x(1)="111")then--右 snake_x(6)<=snake_x(5); snake_x(5)<=snake_x(4); snake_x(4)<=snake_x(3); snake_x(3)<=snake_x(2); snake_x(2)<=snake_x(1); snake_y(6)<=snake_y(5); snake_y(5)<=snake_y(4); snake_y(4)<=snake_y(3); snake_y(3)<=snake_y(2); snake_y(2)<=snake_y(1); snake_x(1)<="000"; elsif(snake_m="11")then snake_x(6)<=snake_x(5); snake_x(5)<=snake_x(4); snake_x(4)<=snake_x(3); snake_x(3)<=snake_x(2); snake_x(2)<=snake_x(1); snake_y(6)<=snake_y(5); snake_y(5)<=snake_y(4); snake_y(4)<=snake_y(3); snake_y(3)<=snake_y(2); snake_y(2)<=snake_y(1); snake_x(1)<=snake_x(1)+1; elsif(snake_m="01")and(snake_y(1)="000")then--下 snake_x(6)<=snake_x(5); snake_x(5)<=snake_x(4); snake_x(4)<=snake_x(3); snake_x(3)<=snake_x(2); snake_x(2)<=snake_x(1); snake_y(6)<=snake_y(5); snake_y(5)<=snake_y(4); snake_y(4)<=snake_y(3); snake_y(3)<=snake_y(2); snake_y(2)<=snake_y(1); snake_y(1)<="111"; elsif(snake_m="01")then snake_x(6)<=snake_x(5); snake_x(5)<=snake_x(4); snake_x(4)<=snake_x(3); snake_x(3)<=snake_x(2); snake_x(2)<=snake_x(1); snake_y(6)<=snake_y(5); snake_y(5)<=snake_y(4); snake_y(4)<=snake_y(3); snake_y(3)<=snake_y(2); snake_y(2)<=snake_y(1); snake_y(1)<=snake_y(1)-1; endif; endif; endprocess;老鼠随机显示模块及计分模块:在老鼠显示模块中,有三项功能:第一项,当SW1有效时,这时对计分进行清零;第二项,当5s到来,而蛇没有吃到老鼠,则改变老鼠的位置,当蛇吃到老鼠,改变蛇的位置;第三项,在七段数码管上显示得分情况,其中还设置six这个输入变量对数码进行片选。其相关源代码如下:process(clk) begin if(clk'eventandclk='1')then ifsw1='1'then seven<="1111110"; elseifcount2=5000000thencount<=1;snake_x(7)<=snake_y(3)+1; snake_y(7)<=snake_x(4)-1; elsecount2<=count2+1;endif; elseifsnake_x(1)=snake_x(7)andsnake_y(1)=snake_y(7)then score<=score+1; snake_x(7)<=snake_y(3)+1; snake_y(7)<=snake_x(4)-1; endif; endif; casescoreis when"0000"=>seven<="1111110"; when"0001"=>seven<="0110000"; when"0010"=>seven<="1101101"; when"0011"=>seven<="1111001"; when"0100"=>seven<="0110011"; when"0101"=>seven<="1011011"; when"0110"=>seven<="1011111"; when"0111"=>seven<="1110000"; when"1000"=>seven<="1111111"; when"1001"=>seven<="1111011"; when"1010"=>seven<="1110111"; when"1011"=>seven<="1111111"; when"1100"=>seven<="1001110"; when"1101"=>seven<="0011101"; when"1110"=>seven<="1001111"; when"1111"=>seven<="1000111"; whenothers=>seven<="0000000"; endcase; six<="011111"; endif; endprocess;所实现功能说明:蛇可以在点阵上自动移动;可以通过控件控制蛇的移动方向;可以在七段数码管上显示当前游戏者的得分;可以通过复位键来对当前得分清零;可以在蛇没有吃到老鼠而且时间已过5S时对蛇的位置进行自动改变。故障及问题分析:本实验中开始时遇到的最大问题时如何让蛇在在8*8点阵上显示并且移动,开始参考了一些资料,由于在开始时对点阵显示的原理不是很明白,所以在实验开始的一段时间内几乎没有任何进展。后来在和同学讨论和请教同寝一做点阵显示的同学前提下,明白了点阵的显示原理,于是设计了蛇的移动和显示。就这样过了两周时间,真正的程序设计才开始,接下来编程过程中遇到的问题都比较简单,在程序调试的过程中都得以解决,其中遇到一个比较多的问题是if语句的配套问题,但这个问题在编程的过程中都很快得以解决。最后程序在下载时遇到一个普遍性的问题就是逻辑宏单元不够,后面发现这主要时由于过多的使用if,case等一系列语句造成的,故在程序设计时当硬件不是很好的情况下,一定要简化语句,在使用最少的硬件设施下完成所要求的任务。总结和结论:在本次试验中,所有的步骤,从实验设计到最后将所有的代码写进计算机都是自己完成,虽然在其中遇到很多问题,但每当问题得以解决时是快乐,特别是的当蛇在点阵上跑动时,心里只能用happy来形容。但这不代表所有要做的事都解决了,还有许多模块要添加进取,其中首先想到的是计分模块,这个模块很快就解决,接下来我又添加了一个计分复位模块,这时最不想遇到的问题来了,我编的程序占有逻辑宏单元为99%,系统一共有128个逻辑宏单元,而我已经使用了127个。后来,我发现通过简化某些程序段,特别是简化if语句的使用可以腾出一些逻辑宏单元出来,接着我又将在每隔5S游戏者仍然没有吃到老鼠的前提下老鼠自动跳变这个模块加了进去。就这样验收程序的时间到了,虽然算不上perfect,但毕竟在发现问题和解决问题的过程中,编出来的不仅是贪吃蛇这个游戏,更重要的是种能力,一种思路的设计,发现问题,解决问题的能力。所用元器件及测试仪表清单:硬件:EPM7128SLC8—15数字电路实验开发板计算机软件:ALTER公司开发的quartusII7.1版本AdobeReaderOfficeword源代码:libraryieee;useieee.std_logic_1164.all;useieee.std_logic_unsigned.all;entitysnakeis--shiti port ( clk:instd_logic;--shizhongduankou sw1:instd_logic;--fuweiduankou key:instd_logic_vector(3downto0);--kongzhifangxiangduankou col:outstd_logic_vector(7downto0);--liezuobiao row:outstd_logic_vector(7downto0);--hangzuobiao six:outstd_logic_vector(5downto0);--qiduanshumaguandepianxuan seven:outstd_logic_vector(6downto0)--qiduanshumaguan );endentitysnake;architecturebehavofsnakeis--jiegouti signaldir:std_logic_vector(1downto0);--kongzhisheyidongdefangxiang signalrown:std_logic_vector(7downto0);--hangxinhao signalcoln:std_logic_vector(7downto0);--liexinhao typewordisarray(1to7)ofstd_logic_vector(2downto0);--dingyiwordshujuleixing signalsnake_y:word;--dingyizongzuobiao signalsnake_x:word;--dingyihengzuibiao signalcount:integerrange0to1000000;--10e6fenpinxinhao signalclk1:std_logic;--1miaoshizhong signalclk2:std_logic;--5miaoshizhong signalcount1:integerrange1to7;--sheshenhelaoshu signalcount2:integerrange1to5000000;--5*10e6fenpin signalsnake_m:std_logic_vector(1downto0);--sheyidongdefangxiang signalscore:std_logic_vector(3downto0);--jisuandefenbeginP0:process(clk)--10e6fenpinbeginif(clk'eventandclk='1')then ifcount=1000000then count<=0; clk1<=notclk1; else count<=count+1; endif;endif;endprocess;p1: process(clk)--kongzhifangxiangdeshixian begin if(clk'event)and(clk='0')then--shang,xiazou,you if(key="1000")then--shang dir<="00"; elsif(key="0100")then--xia dir<="01"; elsif(key="0010")then--zou dir<="10"; elsif(key="0001")then--you dir<="11"; endif; endif; endprocess;p2: process(clk)--shexiayibudeyidongfangxiang begin if(clk'event)and(clk='0')then if(snake_m="00")then if(dir="00")then snake_m<="00"; elsif(dir="01")then snake_m<="00"; elsif(dir="10")then snake_m<="10"; elsif(dir="11")then snake_m<="11"; endif; elsif(snake_m="01")then if(dir="00")then snake_m<="01"; elsif(dir="01")then snake_m<="01"; elsif(dir="10")then snake_m<="10"; elsif(dir="11")then snake_m<="01"; endif; elsif(snake_m="10")then if(dir="00")then snake_m<="00"; elsif(dir="01")then snake_m<="01"; elsif(dir="10")then snake_m<="10"; elsif(dir="11")then snake_m<="11"; endif; elsif(snake_m="11")then if(dir="00")then snake_m<="00"; elsif(dir="01")then snake_m<="01"; elsif(dir="10")then snake_m<="11"; elsif(dir="11")then snake_m<="11"; endif; endif; endif; endprocess;p3: process(clk)--zaidianzhenshangxianshisheshenbegin if(clk'eventandclk='1')then ifcount1=8then count1<=1; elsecount1<=count1+1; endif; casesnake_x(count1)is when"000"=>rown<="10000000"; when"001"=>rown<="01000000"; when"010"=>rown<="00100000"; when"011"=>rown<="00010000"; when"100"=>rown<="00001000"; when"101"=>rown<="00000100"; when"110"=>rown<="00000010"; when"111"=>rown<="00000001"; whenothers =>rown<="00000000"; endcase; casesnake_y(count1)is when"000"=>coln<="01111111"; when"001"=>coln<="10111111"; when"010"=>coln<="11011111"; when"011"=>coln<="11101111"; when"100"=>coln<="11110111"; when"101"=>coln<="11111011"; when"110"=>coln<="11111101"; when"111"=>coln<="11111110"; whenothers =>coln<="11111111"; endcase; endif;col<=coln;row<=rown;endprocess;p4:process(clk)--changshengsuijilaoshuhejufenmokuai begin if(clk'eventandclk='1')then ifsw1='1'then seven<="1111110"; elseifcount2=5000000thencount<=1;snake_x(7)<=snake_y(3)+1; snake_y(7)<=snake_x(4)-1; elsecount2<=count2+1;endif; elseifsnake_x(1)=snake_x(7)andsnake_y(1)=snake_y(7)then score<=score+1; snake_x(7)<=snake_y(3)+1; snake_y(7)<=snake_x(4)-1; endif; endif; casescoreis when"0000"=>seven<="1111110"; when"0001"=>seven<="0110000"; when"0010"=>seven<="1101101"; when"0011"=>seven<="1111001"; when"0100"=>seven<="0110011"; when"0101"=>seven<="1011011"; when"0110"=>seven<="1011111"; when"0111"=>seven<="1110000"; when"1000"=>seven<="1111111"; when"1001"=>seven<="1111011"; when"1010"=>seven<="1110111"; when"1011"=>seven<="1111111"; when"1100"=>seven<="1001110"; when"1101"=>seven<="0011101"; when"1110"=>seven<="1001111"; when"1111"=>seven<="1000111"; whenothers=>seven<="0000000"; endcase; six<="011111"; endif; endprocess; p5:process(clk1)--sheshenyudongmokuai begin if(clk1'eventandclk1='1')then if(snake_m="10")and(snake_x(1)="000")then--zuo snake_x(6)<=snake_x(5); snake_x(5)<=snake_x(4); snake_x(4)<=snake_x(3); snake_x(3)<=snake_x(2); snake_x(2)<=snake_x(1); snake_y(6)<=snake_y(5); snake_y(5)<=snake_y(4); snake_y(4)<=snake_y(3); snake_y(3)<=snake_y(2); snake_y(2)<=snake_y(1); snake_x(1)<="111"; elsif(snake_m="10")then snake_x(6)<=snake_x(5); snake_x(5)<=snake_x(4); snake_x(4)<=snake_x(3); snake_x(3)<=snake_x(2); snake_x(2)<=snake_x(1); snake_y(6)<=snake_y(5); snake_y(5)<=snake_y(4); snake_y(4)<=snake_y(3); snake_y(3)<=snake_y(2); snake_y(2)<=snake_y(1); snake_x(1)<=snake_x(1)-1; elsif(snake_m="00")and(snake_y(1)="111")then--shang snake_x(6)<=snake_x(5); snake_x(5)<=snake_x(4); snake_x(4)<=snake_x(3); snake_x(3)<=snake_x(2); snake_x(2)<=snake_x(1); snake_y(6)<=snake_y(5); snake_y(5)<=snake_y(4); snake_y(4)<=snake_y(3); snake_y(3)<=snake_y(2); snake_

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论