数电实验报告题目:打地鼠的游戏设计与实现姓名:学号:班级:学院: 电子工程学院2015年 11 月 8日一、 任务要求基本要求1、设计一个挑战反应速度的“打地鼠”游戏,采用用 8×8双色点阵显示游戏界面,其中游戏边界采用绿色 LED 显示,随机出现的地鼠采用红色 LED 显示,游戏有 16个洞穴,如图 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、自拟其他功能。
二、系统设计设计思路:1、将该程序进行分模块设计。
可以将程序分为:分频模块、随机数产生模块、比较模块、键盘电路、显示模块、计时模块、游戏结束模块。
2、分模块进行相应模块的编写。
3、对编好的模块进行测试。
4、编写主程序并进行调试。
总体框图:分块设计:1、分频模块将50MHz的信号源分别分频为各难度所需频率的时钟信号。
2、随机数产生模块本实验采用伪随机数产生方法,即在ROM中存入随机表中的数据,游戏开始后采用一个计数器不断从其中读取数据。
3、比较模块判断选手得分或失分主要是由一个比较器完成的,将系统传给LED灯的信号与选手输入的信号作比较,相同则加分,否则扣分,这两个信号分别传给计分模块,从而完成系统判定得分的工作。
4、键盘电路主要通过产生行扫描,来识别用户的按键,电路中已经对按键进行了消抖。
其提供给控制器按键的编码。
5、显示模块显示模块分为两部分,一为60s的倒计时,另一个为从0到10的记分模块,游戏开始时计时模块和比较模块分别将信号传递给显示模块,用来将BCD码转化为可以在七段数码管中显示的。
6、计时模块在此模块中集合开始键,复位键。
当复位键等于0,开始键等于1时,游戏开始。
倒计时模块预置值为60,开始信号给出后,开始60s倒计时。
7、记分模块计分模块接受来自比较模块的信号控制分数的加减,同时将当前的分数BCD码以电信号传递给显示模块显示分数,每一次加分时,判断当前分数是否超过10分,同时当前时间是否小于0。
8、游戏结束模块接收来自计分模块的信号,判断是否结束,保存当前分数,时间通过显示模块显示。
三、仿真波形及波形分析:一、随机数仿真波形在等级为1的情况下产生0---16随机数,产生时间不定,根据当前数字,对应与点阵中的16个LED灯,同时点亮该点。
二、键盘输入(“锤子”仿真波形)通过消抖,提高了键盘反应,当点阵数列和键盘相同时,判断为1,表示为加分信号三、计时器出始时刻设为60S, 通过频率为1Hz的时钟,每一次在时钟上升沿到来时,时间减一。
四、最高分保存模块最高分保存模块和计分模块倒计时模块相连,当倒计时显示为0,分数小于10时保存,或者当分数等于10,倒计时小于60保存,其余情况下均输出0,该模块不工作。
五、比较计分模块波形当计分信号显示为1时,分数u1加一,时钟频率为0.5Hz,在每一个时钟周期内为1,加一否则保持不变。
六、等级判断模块四、源程序:一、分频器LIBRARY IEEE;USE IEEE.STD_LOGIC_1164.ALL;USE IEEE.STD_LOGIC_UNSIGNED.ALL;ENTITY fenpinqi ISPORT(clk_f,clear_f: IN STD_LOGIC;clk_f_out10k, clk_f_out100, clk_f_out1, clk_f_out1d2: OUT STD_LOGIC);END fenpinqi;ARCHITECTURE a OF fenpinqi ISSIGNAL tmp1: INTEGER RANGE 0 TO 24999; --50000分频SIGNAL tmp2: INTEGER RANGE 0 TO 4;SIGNAL tmp3: INTEGER RANGE 0 TO 49; --100分频SIGNAL tmp4: INTEGER RANGE 0 TO 99; --200分频SIGNAL clktmp1: STD_LOGIC;SIGNAL clktmp2: STD_LOGIC;SIGNAL clktmp3: STD_LOGIC;SIGNAL clktmp4: STD_LOGIC;BEGINP1: PROCESS(clear_f, clk_f)BEGINIF clear_f = '1' THENtmp1<=0;ELSIF clk_f'event AND clk_f='1' THENIF tmp1=24999 THENtmp1<=0;clktmp1<=not clktmp1; -- 50000fenpinELSEtmp1<=tmp1+1;END IF;END IF;END PROCESS P1;P2: PROCESS(clear_f, clktmp1)BEGINIF clear_f = '1' THENtmp2<=0;ELSIF clktmp1'event AND clktmp1='1' THENIF tmp2=4 THENtmp2<=0;clktmp2<=not clktmp2; -- 10fenpinELSEtmp2<=tmp2+1;END IF;END IF;END PROCESS P2;P3: PROCESS(clear_f, clktmp2)BEGINIF clear_f = '1' THENtmp3<=0;ELSIF clktmp2'event AND clktmp2='1' THENIF tmp3=49 THENtmp3<=0;clktmp3<=not clktmp3; -- 100fenpin ELSEtmp3<=tmp3+1;END IF;END IF;END PROCESS P3;P4: PROCESS(clear_f, clktmp2)BEGINIF clear_f = '1' THENtmp4<=0;ELSIF clktmp2'event AND clktmp2='1' THENIF tmp4=99 THENtmp4<=0;clktmp4<=not clktmp4; -- 200fenpin ELSEtmp4<=tmp4+1;END IF;END IF;END PROCESS P4;clk_f_out10k<=clktmp1;clk_f_out100<=clktmp2;clk_f_out1<=clktmp3;clk_f_out1d2<=clktmp4;END a;二、译码器libraryieee;use ieee.std_logic_1164.all;entityyimaqi isport(clk_y, clear_y: in std_logic;time1, time2, score1, score2: IN std_logic_vector(3 downto 0);yimaqi_out: out std_logic_vector(6 downto 0);cat: out std_logic_vector(5 downto 0));endyimaqi;architecture yimaqi_1 of yimaqi issignal time1_tmp, time2_tmp, score1_tmp, score2_tmp: std_logic_vector(6 downto 0);signalcat_tmp: std_logic_vector(5 downto 0);function convert (input: std_logic_vector) return std_logic_vector isbegincase input ISwhen "0000" => return "1111110"; --根据BCD码,生成不同的显when "0001" => return "0110000"; 序列,点亮不同位置,显示when "0010" => return "1101101"; 数字1--10when "0011" => return "1111001";when "0100" => return "0110011";when "0101" => return "1011011";when "0110" => return "1011111";when "0111" => return "1110000";when "1000" => return "1111111";when "1001" => return "1111011";when others => return "0000000";end case;end convert;beginp1: process(clk_y, clear_y)beginifclear_y= '1' then cat_tmp<= "111111";elsifclk_y'event and clk_y= '1' thencasecat_tmp iswhen "111110" =>cat_tmp<= "011111";yimaqi_out<= time2_tmp;when "011111" =>cat_tmp<= "101111";yimaqi_out<= time1_tmp;when "101111" =>cat_tmp<= "111101";yimaqi_out<= score2_tmp;when "111101" =>cat_tmp<= "111110";yimaqi_out<= score1_tmp;when others =>cat_tmp<= "111110";end case;end if;end process p1;p2: process(time1, time2, score1, score2, time1_tmp, time2_tmp, score1_tmp, score2_tmp)begintime1_tmp<= convert(time1);time2_tmp<= convert(time2);score1_tmp<= convert(score1);score2_tmp<= convert(score2);end process p2;cat<= cat_tmp;end yimaqi_1;三、计数器LIBRARY IEEE;USE IEEE.STD_LOGIC_1164.ALL;USE IEEE.STD_LOGIC_UNSIGNED.ALL;entityjishuqi isPORT(add, clk_j60, clear_j: IN STD_LOGIC;q1_j60, q2_j60, q1_j10, q2_j10: OUT STD_LOGIC_VECTOR(3 DOWNTO 0);time_up, reach10: OUT STD_LOGIC);endjishuqi;architecture a of jishuqi issignal q1_j60tmp, q2_j60tmp, q1_j10tmp,q2_j10tmp: std_logic_vector(3 DOWNTO 0);signalendsignal: std_logic_vector(1 downto 0);beginp1: process(clk_j60, clear_j)begin --倒计时部分,预置为60,根据时钟信号每一秒减一ifclear_j= '1' thenq1_j60tmp<= "0000";q2_j60tmp<= "0000";time_up<= '0';endsignal(1)<= '0';elsifendsignal(0)= '0' thenif clk_j60'event and clk_j60 = '1' thenif q1_j60tmp= "1001" thenif q2_j60tmp= "0101" then time_up<= '1';endsignal(1)<= '1';else q1_j60tmp<= "0000";q2_j60tmp<= q2_j60tmp+1;time_up<= '0';endsignal(1)<= '0';end if;else q1_j60tmp<= q1_j60tmp+1;time_up<= '0';endsignal(1)<= '0';end if;end if;end if;end process p1;q1_j60<= q1_j60tmp;q2_j60<= q2_j60tmp;p2: process(add)begin --分数表示部分,接收加分信号,并输出给判断模块ifclear_j= '1' thenq1_j10tmp<= "0000";q2_j10tmp<= "0000";reach10<= '0';endsignal(0)<= '0';elsifendsignal(1)= '0' thenifadd'event and add= '1' thenif q1_j10tmp= "1001" thenif q2_j10tmp= "0000" then q1_j10tmp<= "0000";q2_j10tmp<= q2_j10tmp+1;reach10<= '1';endsignal(0)<= '1';else q1_j10tmp<= "0000";q2_j10tmp<= q2_j10tmp+1;reach10<= '0';endsignal(0)<= '0';end if;else q1_j10tmp<= q1_j10tmp+1;reach10<= '0';endsignal(0)<= '0';end if;end if;end if;end process p2;q1_j10<= q1_j10tmp;q2_j10<= q2_j10tmp;end a;四、点阵模块libraryieee;use ieee.std_logic_1164.all;entitydianzhen isport(x, y: in std_logic_vector(1 downto 0); --根据产生的伪随机数,确定行clear_d, clk_d, hit, win, lose: in std_logic; 列坐标,点亮相应点阵序列cat1_out, cat2_out, cat3_out: out std_logic_vector(5 downto 0));enddianzhen;architecture a of dianzhen issignal cat1, cat2, cat3, x_tmp: std_logic_vector(5 downto 0);beginp1: process(y, clear_d, clk_d, hit)beginifclear_d = '1' then cat3<="111111";elsifclk_d'event and clk_d='1' thenif win= '1' then --当获胜信号为1时,控制点阵显示Vcase cat3 iswhen "011111" => cat3<="101111";cat1<="100001";cat2<= "010010";when "101111" => cat3<="110111";cat1<="100001";cat2<= "010010";when "110111" => cat3<="111011";cat1<="100001";cat2<= "001100";when "111011" => cat3<="111101";cat1<="100001";cat2<= "001100";when "111101" => cat3<="111110";cat1<="111111";cat2<= "000000";when "111110" => cat3<="011111";cat1<="111111";cat2<= "000000";when others => cat3<="011111";end case; --失败信号为1时,显示Xelsif lose= '1' thencase cat3 iswhen "011111" => cat3<="101111";cat1<="100001";cat2<= "010010";when "101111" => cat3<="110111";cat1<="100001";cat2<= "001100";when "110111" => cat3<="111011";cat1<="100001";cat2<= "001100";when "111011" => cat3<="111101";cat1<="100001";cat2<= "010010";when "111101" => cat3<="111110";cat1<="111111";cat2<= "000000";when "111110" => cat3<="011111";cat1<="111111";cat2<= "000000";when others => cat3<="011111";end case;else --游戏进行中win、lose均不为1,游戏继续case cat3 iswhen "011111" => cat3<="101111";cat1<="100001";if y="00" then cat2<=x_tmp;else cat2<="000000"; end if;when "101111" => cat3<="110111";cat1<="100001";if y="01" then cat2<=x_tmp;else cat2<="000000"; end if;when "110111" => cat3<="111011";cat1<="100001";if y="10" then cat2<=x_tmp;else cat2<="000000"; end if;when "111011" => cat3<="111101";cat1<="100001";if y="11" then cat2<=x_tmp;else cat2<="000000"; end if;when "111101" => cat3<="111110";cat1<="111111";cat2<="000000";when "111110" => cat3<="011111";cat1<="111111";cat2<="000000";when others => cat3<="011111";end case;end if;end if;end process p1;p2: process(x, x_tmp, hit)beginif hit='1' then x_tmp<="000000";elsif hit= '0' thencase x iswhen "00" =>x_tmp<="000010";when "1" =>x_tmp<="000100";when "10" =>x_tmp<="001000";when "11" =>x_tmp<="010000";when others =>x_tmp<="000000";end case;end if;end process p2;cat1_out<=cat1;cat2_out<=cat2;cat3_out<=cat3;end a;五、控制器libraryieee;use ieee.std_logic_1164.all;useieee.std_logic_arith.all;useieee.std_logic_unsigned.all;entitykongzhiqi isport(x_in, y_in: in std_logic_vector(1 downto 0);--键盘输入xkey_out: out std_logic_vector(3 downto 0); --列项ykey_in: in std_logic_vector(3 downto 0); --行项reach10_in, time_up_in: in std_logic;--分数时间信号clk_k, clk_k2, clear_k: in std_logic;add_out, win_out, lose_out, disappear_out:outstd_logic);endkongzhiqi;architecture a of kongzhiqi issignalscan_key: std_logic_vector(3 downto 0); signaldiv_cnt: std_logic_vector(24 downto 0);signalx_tmp, y_tmp, x, y: std_logic_vector(2 downto 0); signal flag: std_logic;signalx_old, y_old: std_logic_vector(1 downto 0); beginp1: process(clk_k,clear_k)beginifclear_k = '1' thendiv_cnt<= "0000000000000000000000000";elsif(clk_k'event and clk_k = '1')thendiv_cnt<= div_cnt + 1;end if;end process p1;p2: process(div_cnt(1 downto 0))begincasediv_cnt(1 downto 0) ISwhen "00"=>scan_key<="1110";when "01"=>scan_key<="1101";when "10"=>scan_key<="1011";when "11"=>scan_key<="0111";end case;end process p2;p3: process(clk_k,clear_k)beginifclear_k='1' thenx_tmp<= "111";y_tmp<= "111";elsif(clk_k'event and clk_k='1')thenif not(x_in= x_old) or not(y_in= y_old) thenx_tmp<= "111";y_tmp<= "111";x_old<= x_in;y_old<= y_in;end if;casescan_key is --jiancewhen "1110" =>caseykey_in iswhen "0111" =>y_tmp<= "000";x_tmp <= "000";when "1011" =>y_tmp<= "001";x_tmp <= "000";when "1101" =>y_tmp<= "010";x_tmp <= "000";when "1110" =>y_tmp<= "011";x_tmp <= "000";when others => null;end case;when "1101" =>caseykey_in iswhen "0111" =>y_tmp<= "000";x_tmp <= "001";when "1011" =>y_tmp<= "001";x_tmp <= "001";when "1101" =>y_tmp<= "010";x_tmp <= "001";when "1110" =>y_tmp<= "011";x_tmp <= "001";when others => null;end case;when "1011" =>caseykey_in iswhen "0111" =>y_tmp<= "000";x_tmp <= "010";"1011" =>y_tmp<= "001";x_tmp <= "010";when "1101" =>y_tmp<= "010";x_tmp <= "010";when "1110" =>y_tmp<= "011";x_tmp <= "010";when others => null;end case;when "0111" =>caseykey_in iswhen "0111" =>y_tmp<= "000";x_tmp <= "011";when "1011" =>y_tmp<= "001";x_tmp <= "011";when "1101" =>y_tmp<= "010";x_tmp <= "011";when "1110" =>mp<= "011";x_tmp <= "011";when others => null;end case;when others => null;end case;end if;end process p3;p4: process(x_in, y_in, flag, x, y, x_tmp, y_tmp, clk_k2) beginif x= x_tmp and y= y_tmp thenadd_out<= '1';disappear_out<= '1';elsif clk_k2'event and clk_k2= '0' thenadd_out<= '0';disappear_out<= '0';end if;end process p4;p5: process(reach10_in, time_up_in)beginif reach10_in= '1' thenwin_out<= '1';elsiftime_up_in= '1' thenlose_out<= '1';elsewin_out<= '0';lose_out<= '0';end if;end process p5;xkey_out<= scan_key;x(1 downto 0)<= x_in;y(1 downto 0)<= y_in;x(2)<= '0';y(2)<= '0';end a;五、功能说明及资源利用率情况:通过不同模块协同和作,实现打地鼠游戏。