北邮数电实验三接球小游戏


前言

北邮数电实验三“接球小游戏”
数电实验验收已经结束了,实验报告也已经提交很久了,就把VHDL代码发到CSDN上分享一下,造福后来的学弟学妹,这也是我第一篇博客,以后也会分享一些单片机、PCB、FPGA之类的内容。
老师上学期没教状态机,自己也没自学这部分,所以用了多个模块然后接线,当时年级里传着一个大佬用状态机写的代码,看着很厉害,但是我感觉不好调试,就自己写了一份。

提示:代码仅供参考,请不要直接抄袭,看懂再用才是最好的,然后我的代码可能有问题,希望在评论里探讨呀

一、实验要求

接球小游戏的示意图

基本要求:
1、 设计实现一个基于 8×8 双色点阵的接球游戏,其中接球板采用红色 LED 显示,小球采用绿色 LED 显示。数码管 DISP0 显示游戏分数、DISP1、DISP2 显示游戏时间。
2、 按下游戏开始键 BTN0 后,点阵显示 5 秒倒计时动画。动画结束后进入游戏界面。
3、 游戏示意过程参考图 1 中从①→⑦的顺序所示。在点阵顶部第 7 行的位置随机出现一个小球,并按照相应的列垂直落下,下落速度为 0.5 秒/行。接球板采用 3 个红色LED 进行显示并可以通过 BTN1、BTN2 按键控制接球板左右移动(左右移动时接球板要在点阵上显示完整)。如果球落下时碰到板(即小球到达点阵第 1 行,同时正好在接球板 3 个 LED 范围内)则游戏加 1 分,否则不加分,然后在点阵顶部重新随机出现新的小球。
4、游戏时间为 30 秒倒计时提醒。当在游戏时间内计满 5 分时游戏结束,点阵显示胜利动画,蜂鸣器演奏胜利音效;如果在游戏时间内未到达 5 分,游戏显示失败画面,蜂鸣器演奏相应音效。
提高要求:
1、增加游戏音效,当小球碰到接球板时,蜂鸣器发声;
2、 增加高级模式,当游戏达到 10 秒后,接球板变短(长度变为 2 个 LED);
3、 增加难度模式,该模式下,当小球从点阵顶部降落到第 5 行时,点阵顶部随机出现第二个小球;
4、 小球降落速度多档可调;
5、 自拟其他功能。创建的。

二、设计思路

一开始打算用状态机,一个实体写完,尝试过后发现太麻烦了,多个进程间的通信比较麻烦,也容易弄混,而且不好调试,就把点阵显示模块和模式选择模块用状态机的模板来写,把其他的功能分离开,将一个复杂的游戏机划分成多个简单模块的组合。模块间通过信号通信。
所有模块如下:
–1.M序列发生器 hwk7_02_M1
–2.分频器 hwk7_02_CLK_DIVISON
–3.防抖 hwk7_02_FD
–4.点阵显示 hwk7_02_POINTDISPLAY
–5.底板移动计数器 hwk7_02_movecount
–6.小球下落计数器 hwk7_02_fallpointcount
–7.模式选择切换控制器 hwk7_02_MODEL
–8.得分判断 hwk7_02_goal
–9.数码管显示 hwk7_02_goalSegmentDisplay
–10.蜂鸣器 hwk7_02_music
–0.顶层实体 game
其中有的模块可以利用上学期已有的代码,可以大大节约开发时间,也方便仿真和调试。
模块大体分为以下几类:输入→逻辑处理→输出。
输入为按键和时钟,以此延伸出按键防抖和分频器,因为小球的下落是随机的,所以还需要M序列发生器来产生随机信号。
逻辑处理主要是几个计数器和判断模块。模式选择器是用来调节各模块之间的同步问题,用不同的模式信号告诉一些需要切换状态的模块,你当前应该处于哪个状态。底板位置用一个三位的二进制信号x1表示,每隔一段就去扫描BTN1和BTN2组成的一个二维信号,10减一,01加一,其他不变。小球的位置用两个三位的二进制信号x0和y0表示,每隔一段时间y0+1,当y0到底时读取新的x0。得分判断就是当y0=7时,判断x0是否等于x1 | x1+1 | x1-1 即可,是的话就输出一个脉冲信号goal。
输出分三大块,点阵显示,蜂鸣器,数码管。里面点阵显示是最复杂的,大体逻辑如下图所示:
点阵显示逻辑

开机处于000状态,按下以后进入倒计时,然后游戏中,最后根据游戏结果显示胜利或者失败。蜂鸣器的输出先与goal做或运算,这样只要接到球就能输出一个声音,胜利或失败以后根据finial信号输出胜利或失败音效。数码管在close信号为1时,一直处于初始状态,当close为0时,开始倒计时,同时每输入一个脉冲goal,显示得分就+1。

三、设计系统框图

系统设计框图
图中输入的speed[1]是接拨码开关,通过speed不同,控制小球下落速度不同,实现提高功能,速度可调。其它信号根据变量名都可以看出具体作用,这里就不一一解释了,详情可以看设计思路和源代码。

四、源代码

代码的注释挺多的,但有的地方为了加功能改了内容,没有改注释(因为懒:(,看的时候多看代码):

----------------------------------------------------------------------------------------
--题目 3 接球小游戏的设计与实现     by hwk
--基本要求:   基本功能全部完成
--1、 设计实现一个基于 8×8 双色点阵的接球游戏,其中接球板采用红色 LED 显示,小球采用绿色 LED 显示。
--    数码管 DISP0 显示游戏分数、DISP1、DISP2 显示游戏时间。
--2、 按下游戏开始键 BTN0 后,点阵显示 5 秒倒计时动画。动画结束后进入游戏界面。
--3、 游戏示意过程参考图 1 中从①→⑦的顺序所示。在点阵顶部第 7 行的位置随机出现一个小球,并按照相应的列垂直落下,下落速度为 0.5/--    接球板采用 3 个红色LED 进行显示,并可以通过 BTN1、BTN2 按键控制接球板左右移动(左右移动时接球板要在点阵上显示完整)
--    如果球落下时碰到板(即小球到达点阵第 1 行,同时正好在接球板 3--LED 范围内)则游戏加 1--    否则不加分,然后在点阵顶部重新随机出现新的小球。
--4、 游戏时间为 30 秒倒计时提醒。当在游戏时间内计满 5 分时游戏结束,点阵显示胜利动画,蜂鸣器演奏胜利音效
--    如果在游戏时间内未到达 5 分,游戏显示失败画面,蜂鸣--器演奏相应音效。       
--提高要求:
--1、增加游戏音效,当小球碰到接球板时,蜂鸣器发声;                                             √ 
--2、增加高级模式,当游戏达到 10 秒后,接球板变短(长度变为 2 个 LED);                        X
--3、增加难度模式,该模式下,当小球从点阵顶部降落到第 5 行时,点阵顶部随机出现第二个小球;      X
--4、小球降落速度多档可调;                                                                     √    SW(100——11速度依次升高, 10为变速下降
--5、自拟其他功能。                                                                             X
--编译者邮箱:HeWenKang@bupt.edu.cn
----------------------------------------------------------------------------------------------------------------

-------------------------------------------------------------------------------------------------------------
--1.M序列发生器                   hwk7_02_M1 
--2.分频器                        hwk7_02_CLK_DIVISON 
--3.防抖                          hwk7_02_FD 
--4.点阵显示                      hwk7_02_POINTDISPLAY
--5.底板移动计数器                hwk7_02_movecount
--6.小球下落计数器                hwk7_02_fallpointcount
--7.模式选择切换控制器            hwk7_02_MODEL
--8.得分判断                      hwk7_02_goal 
--9.数码管显示                    hwk7_02_goalSegmentDisplay
--10.蜂鸣器                       hwk7_02_music
--0.顶层实体                      game
--编译者邮箱:HeWenKang@bupt.edu.cn
-------------------------------------------------------------------------------------------------------------

----------------------------------------------
--名称:M序列发生器  hwk7_02_M1                                                                      1
--功能: 产生随机序列
--输入:时钟信号clkin和复位信号clear                                                                 
--输出:4位随机序列 m
--编译者邮箱:HeWenKang@bupt.edu.cn
----------------------------------------------
LIBRARY IEEE;               
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;
ENTITY hwk7_02_M1 IS             
	PORT(clkin:IN STD_LOGIC;
		 clear:IN STD_LOGIC;
		 m:OUT STD_LOGIC_VECTOR(2 downto 0));
END ;

ARCHITECTURE a OF hwk7_02_M1 IS
	SIGNAL temp1:STD_LOGIC_VECTOR(3 downto 0);
	SIGNAL temp2:STD_LOGIC_VECTOR(2 downto 0);
BEGIN
	PROCESS(clear,clkin)
	BEGIN
        IF clear='1'  THEN 
          temp2<="000";
		ELSIF(clkin'EVENT AND clkin='1')THEN
			IF temp1="0000" THEN        
               temp1<="0001" ;
			ELSE
				temp1(0)<=temp1(0) xor temp1(3);
				temp1(1)<=temp1(0);
				temp1(2)<=temp1(1);
				temp1(3)<=temp1(2);
			END	IF;
			case temp1 is
				when "0000"=> temp2<="000";--  0
				when "0001"=> temp2<="001";--  1
				when "0010"=> temp2<="010";--  2
				when "0011"=> temp2<="011";--  3
				when "0100"=> temp2<="100";--  4
				when "0101"=> temp2<="101";--  5
				when "0110"=> temp2<="110";--  6				
				when "0111"=> temp2<="111";--  7				
				when "1000"=> temp2<="000";--  0
				when "1001"=> temp2<="001";--  1
				when "1010"=> temp2<="010";--  2
				when "1011"=> temp2<="011";--  3
				when "1100"=> temp2<="100";--  4
				when "1101"=> temp2<="101";--  5
				when "1110"=> temp2<="110";--  6				
				when "1111"=> temp2<="111";--  7											
				when others=> temp2<="111";
	        end case;
		END IF;
	END PROCESS ;
	m<=temp2;
END a;

----------------------------------------------
--名称:分频器                                                                                 2
--功能: 产生其它频率的时钟信号
--输入clkin   1MHz
--输出:clk_out_10Hz, clk_out_1Hz, clk_out_2Hz
--编译者邮箱:HeWenKang@bupt.edu.cn
----------------------------------------------
LIBRARY IEEE;                   
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;
ENTITY hwk7_02_CLK_DIVISON IS             
	PORT(clkin:IN STD_LOGIC;
		 clk_out_10Hz, clk_out_1Hz, clk_out_2Hz :OUT STD_LOGIC	
		 );
END ;

ARCHITECTURE a OF hwk7_02_CLK_DIVISON IS
signal count_10Hz :integer range 0 to 2000000;
signal count_1Hz :integer range 0 to 1000000;
signal count_2Hz :integer range 0 to 500000;
BEGIN
p1:process(clkin)
   BEGIN
       if rising_edge(clkin) then
          if count_10Hz =100000 then
            count_10Hz<=0;
          elsif count_1Hz = 1000000 then
            count_1Hz<=0;
          elsif count_2Hz = 250000 then
            count_2Hz<=0;
          else
            count_10Hz<=count_10Hz + 1;
            count_1Hz<=count_1Hz + 1;                                
            count_2Hz<=count_2Hz + 1;
         end if;
      end if;
 end process p1;
p2:process(count_10Hz,clkin)
   begin
   if rising_edge(clkin) then
      if count_10Hz<50000 then 
            clk_out_10Hz <= '0';
      else  clk_out_10Hz <= '1';
      end if;
     end if;
end process p2;
p3:process(count_1Hz,clkin)
   begin
   if rising_edge(clkin) then
      if count_1Hz<500000 then 
            clk_out_1Hz <= '0';
      else  clk_out_1Hz <= '1';
      end if;
   end if;
end process p3;
p4:process(count_2Hz,clkin)
   begin
   if rising_edge(clkin) then
      if count_2Hz<125000 then 
            clk_out_2Hz <= '0';
      else  clk_out_2Hz <= '1';
      end if;
      end if;
end process p4;
END a;

----------------------------------------------
--名称:按键防抖                                                                              3
--功能:计数实现按键防抖,按下高电平
--输入:BTN0,BTN1,BTN2,clkin,goal       其中clkin为1Mhz,BTN接外部键盘,goal是内部模块间信号
--输出:FDBTN0,FDBTN1,FDBTN2,fdgoal
--编译者邮箱:HeWenKang@bupt.edu.cn
----------------------------------------------
LIBRARY IEEE;                   
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;
ENTITY hwk7_02_FD IS             
	PORT(clkin , BTN0 , BTN1 ,BTN2, goal:IN STD_LOGIC;
		 FDBTN0 , FDBTN1 ,FDBTN2,fdgoal:OUT STD_LOGIC	
		 );
END ;

ARCHITECTURE a OF hwk7_02_FD IS
signal count_0 :integer range 0 to 10000;
signal count_1 :integer range 0 to 10000;
signal count_2 :integer range 0 to 10000;
signal count_3 :integer range 0 to 10000;
BEGIN
p1:process(clkin, BTN0)
   BEGIN
       if BTN0 = '1' then
         if rising_edge(clkin) then
            if count_0 =10000 then
               count_0<=count_0;
             else count_0<=count_0+1;
            end if;
            if count_0<10000 then FDBTN0 <= '0';
             else FDBTN0 <= '1';
            end if;
         end if;
       else
         count_0<=0;
         FDBTN0 <= '0';
       end if;
 end process p1;
p2:process(clkin, BTN1)
   BEGIN
       if BTN1 = '1' then
         if rising_edge(clkin) then
            if count_1 =10000 then
               count_1<=count_1;
             else count_1<=count_1+1;
            end if;
            if count_1<10000 then FDBTN1 <= '0';
             else FDBTN1 <= '1';
            end if;
         end if;
       else
         count_1<=0;
         FDBTN1 <= '0';
       end if;
 end process p2;
 p3:process(clkin, BTN2)
   BEGIN
       if BTN2 = '1' then
         if rising_edge(clkin) then
            if count_2 =10000 then
               count_2<=count_2;
             else count_2<=count_2+1;
            end if;
            if count_2<10000 then FDBTN2 <= '0';
             else FDBTN2 <= '1';
            end if;
         end if;
       else
         count_2<=0;
         FDBTN2 <= '0';
       end if;
 end process p3;
  p4:process(clkin, goal)
   BEGIN
       if goal = '1' then
         if rising_edge(clkin) then
            if count_3 =10000 then
               count_3<=count_3;
             else count_3<=count_3+1;
            end if;
            if count_3<10000 then fdgoal <= '0';
             else fdgoal <= '1';
            end if;
         end if;
       else
         count_3<=0;
         fdgoal <= '0';
       end if;
 end process p4;
END a;



----------------------------------------------
--名称:点阵显示                                                                                4                                                                            4
--功能:模式选择000,实现倒计时动画001,胜利动画010,失败动画011,游戏动画100
--      model输入进某个状态,就先让model_out输出该状态以保持
--      该状态结束以后再用model_out输出下一状态
--输入:x0[2],y0[2],x1[2],model[2],clkin_1Hz,clkin(1M Hz)
--输出:col_red[7],col_green[7],row[7],model_out
--编译者邮箱:HeWenKang@bupt.edu.cn
----------------------------------------------
LIBRARY IEEE;                   
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;
ENTITY hwk7_02_POINTDISPLAY IS             
	PORT(X0:IN STD_LOGIC_VECTOR(2 DOWNTO 0);
		 Y0:IN STD_LOGIC_VECTOR(2 DOWNTO 0);
		 X1:IN STD_LOGIC_VECTOR(2 DOWNTO 0);
		 MODEL :IN STD_LOGIC_VECTOR(2 DOWNTO 0);
		 MODEL_out :out STD_LOGIC_VECTOR(2 DOWNTO 0);
		 clkin: IN STD_LOGIC;
		 clkin_1Hz: IN STD_LOGIC;
		 col_red:OUT STD_LOGIC_VECTOR(7 DOWNTO 0);
		 col_green:OUT STD_LOGIC_VECTOR(7 DOWNTO 0);
		 row:OUT STD_LOGIC_VECTOR(7 DOWNTO 0)
		 );
END ;
ARCHITECTURE a OF hwk7_02_POINTDISPLAY IS
		
signal count_row :integer range 0 to 8;
signal time_count :integer range -1 to 5;
 begin

p1:process(model,clkin_1Hz)               --5秒倒计时进程   
   begin
   if model ="001" then
     if rising_edge(clkin_1Hz) then
       time_count<=time_count-1;
       end if;
   else
       time_count<=5;
      end if;
   end process;
   
p2:process(model,clkin)                   --点阵扫描进程        
  begin	
	 		  if rising_edge(clkin) then
			  count_row<=count_row+1;
			  if count_row = 8 then
				   count_row<=0;
			  end if;
		  end if;
   end process;	
	
		
p3:process(MODEL,clkin,clkin_1Hz,x0,y0,x1)  
  begin
   if MODEL ="000"   then                     -- 模式选择待完成,应在1处显示绿灯
        col_red<="00000000";
        col_green<="00000001";
        row<="11111110";
   end if;

      if MODEL ="001" then                     --开场5秒倒计时 状态001  结束后跳到状态100
   MODEL_out <="001";
case time_count is	
when 0 =>  		 MODEL_out <="100";  	  
when 1 =>		 case count_row is
   when 0 =>   col_green<="00000000"; row<="01111111";
   when 1 =>   col_green<="00001000"; row<="10111111";
   when 2 =>   col_green<="00001000"; row<="11011111";
   when 3 =>   col_green<="00001000"; row<="11101111";
   when 4 =>   col_green<="00001000"; row<="11110111";
   when 5 =>   col_green<="00001000"; row<="11111011";
   when 6 =>   col_green<="00001000"; row<="11111101";
   when 7 =>   col_green<="00000000"; row<="11111110";	  
   when others =>   col_green<="00000000"; row<="11111111";		  
	end case;	  
when 2 =>		 case count_row is
   when 0 =>   col_green<="00000000"; row<="01111111";
   when 1 =>   col_green<="00111100"; row<="10111111";
   when 2 =>   col_green<="00100000"; row<="11011111";
   when 3 =>   col_green<="00111100"; row<="11101111";
   when 4 =>   col_green<="00000100"; row<="11110111";
   when 5 =>   col_green<="00111100"; row<="11111011";
   when 6 =>   col_green<="00000000"; row<="11111101";
   when 7 =>   col_green<="00000000"; row<="11111110";	  
   when others =>   col_green<="00000000"; row<="11111111";		  
	end case;	
when 3 =>		 case count_row is
   when 0 =>   col_green<="00000000"; row<="01111111";
   when 1 =>   col_green<="00111100"; row<="10111111";
   when 2 =>   col_green<="00100000"; row<="11011111";
   when 3 =>   col_green<="00111100"; row<="11101111";
   when 4 =>   col_green<="00100000"; row<="11110111";
   when 5 =>   col_green<="00111100"; row<="11111011";
   when 6 =>   col_green<="00000000"; row<="11111101";
   when 7 =>   col_green<="00000000"; row<="11111110";	  
   when others =>   col_green<="00000000"; row<="11111111";		  
	end case;	
when 4 =>		 case count_row is
   when 0 =>   col_green<="00000000"; row<="01111111";
   when 1 =>   col_green<="00001001"; row<="10111111";
   when 2 =>   col_green<="00001001"; row<="11011111";
   when 3 =>   col_green<="00111111"; row<="11101111";
   when 4 =>   col_green<="00001000"; row<="11110111";
   when 5 =>   col_green<="00001000"; row<="11111011";
   when 6 =>   col_green<="00001000"; row<="11111101";
   when 7 =>   col_green<="00000000"; row<="11111110";	  
   when others =>   col_green<="00000000"; row<="11111111";		  
	end case;	
when 5 =>			
	 case count_row is
   when 0 =>   col_green<="00000000"; row<="01111111";
   when 1 =>   col_green<="00111100"; row<="10111111";
   when 2 =>   col_green<="00000100"; row<="11011111";
   when 3 =>   col_green<="00111100"; row<="11101111";
   when 4 =>   col_green<="00100000"; row<="11110111";
   when 5 =>   col_green<="00111100"; row<="11111011";
   when 6 =>   col_green<="00000000"; row<="11111101";
   when 7 =>   col_green<="00000000"; row<="11111110";	  
   when others =>   col_green<="00000000"; row<="11111111";		  
	end case;
when others =>   col_green<="00000000"; row<="11111111";				  
end case;		  
   end if;  
     
       if MODEL ="010" then                     --胜利动画,绿色笑脸 状态010   
    MODEL_out <="010"; col_red<="00000000";
case count_row is
   when 0 =>   col_green<="00000000"; row<="01111111";
   when 1 =>   col_green<="01000010"; row<="10111111";
   when 2 =>   col_green<="00000000"; row<="11011111";
   when 3 =>   col_green<="01000010"; row<="11101111";
   when 4 =>   col_green<="00100100"; row<="11110111";
   when 5 =>   col_green<="00011000"; row<="11111011";
   when 6 =>   col_green<="00000000"; row<="11111101";
   when 7 =>   col_green<="00000000"; row<="11111110";	  
   when others =>   col_green<="00000000"; row<="11111111";		  
	end case;	  
   end if;      

       if MODEL ="011" then                     --失败动画,红色哭脸   状态011   
    MODEL_out <="011"; col_green<="00000000";
case count_row is
   when 0 =>   col_red<="00000000"; row<="01111111";
   when 1 =>   col_red<="01000010"; row<="10111111";
   when 2 =>   col_red<="00000000"; row<="11011111";
   when 3 =>   col_red<="00011000"; row<="11101111";
   when 4 =>   col_red<="00100100"; row<="11110111";
   when 5 =>   col_red<="01000010"; row<="11111011";
   when 6 =>   col_red<="00000000"; row<="11111101";
   when 7 =>   col_red<="00000000"; row<="11111110";	  
   when others =>   col_green<="00000000"; row<="11111111";		  
	end case;
   end if;           
    
       if MODEL ="100" then                     --游戏中 状态100   结束以后跳到状态010或者011
       MODEL_out <="100"; 
				 CASE count_row IS
				 when 0  =>   if y0 ="000" then 
								 CASE x0 IS 
										  when "000"=>  col_green<="10000000";
										  when "001"=>  col_green<="01000000";    
										  when "010"=>  col_green<="00100000";     
										  when "011"=>  col_green<="00010000";     
										  when "100"=>  col_green<="00001000";
										  when "101"=>  col_green<="00000100";
										  when "110"=>  col_green<="00000010";
										  when "111"=>  col_green<="00000001";
										  WHEN OTHERS =>col_green<="00000000";
								 end case;
								 row<="01111111";
							   else row<="11111111";
							   end if;
				  when 1  =>   if y0 ="001" then 
								 CASE x0 IS 
										  when "000"=>  col_green<="10000000";
										  when "001"=>  col_green<="01000000";    
										  when "010"=>  col_green<="00100000";     
										  when "011"=>  col_green<="00010000";     
										  when "100"=>  col_green<="00001000";
										  when "101"=>  col_green<="00000100";
										  when "110"=>  col_green<="00000010";
										  when "111"=>  col_green<="00000001";
										  WHEN OTHERS =>col_green<="00000000";
								 end case;
								 row<="10111111";
							   else row<="11111111";
							   end if;
				 when 2  =>   if y0 ="010" then 
								 CASE x0 IS 
										  when "000"=>  col_green<="10000000";
										  when "001"=>  col_green<="01000000";    
										  when "010"=>  col_green<="00100000";     
										  when "011"=>  col_green<="00010000";     
										  when "100"=>  col_green<="00001000";
										  when "101"=>  col_green<="00000100";
										  when "110"=>  col_green<="00000010";
										  when "111"=>  col_green<="00000001";
										  WHEN OTHERS =>col_green<="00000000";
								 end case;
								 row<="11011111";
							   else row<="11111111";
							   end if;                                     
							   
				  when 3  =>   if y0 ="011" then 
								 CASE x0 IS 
										  when "000"=>  col_green<="10000000";
										  when "001"=>  col_green<="01000000";    
										  when "010"=>  col_green<="00100000";     
										  when "011"=>  col_green<="00010000";     
										  when "100"=>  col_green<="00001000";
										  when "101"=>  col_green<="00000100";
										  when "110"=>  col_green<="00000010";
										  when "111"=>  col_green<="00000001";
										  WHEN OTHERS =>col_green<="00000000";
								 end case;
								 row<="11101111";
							   else row<="11111111";
							   end if;                  
				 when 4  =>   if y0 ="100" then 
								 CASE x0 IS 
										  when "000"=>  col_green<="10000000";
										  when "001"=>  col_green<="01000000";    
										  when "010"=>  col_green<="00100000";     
										  when "011"=>  col_green<="00010000";     
										  when "100"=>  col_green<="00001000";
										  when "101"=>  col_green<="00000100";
										  when "110"=>  col_green<="00000010";
										  when "111"=>  col_green<="00000001";
										  WHEN OTHERS =>col_green<="00000000";
								 end case;
								 row<="11110111";
							   else row<="11111111";
							   end if;                             
				 when 5  =>   if y0 ="101" then 
								 CASE x0 IS 
										  when "000"=>  col_green<="10000000";
										  when "001"=>  col_green<="01000000";    
										  when "010"=>  col_green<="00100000";     
										  when "011"=>  col_green<="00010000";     
										  when "100"=>  col_green<="00001000";
										  when "101"=>  col_green<="00000100";
										  when "110"=>  col_green<="00000010";
										  when "111"=>  col_green<="00000001";
										  WHEN OTHERS =>col_green<="00000000";
								 end case;
								 row<="11111011";
							   else row<="11111111";
							   end if;
				 when 6  =>   if y0 ="110" then 
								 CASE x0 IS 
										  when "000"=>  col_green<="10000000";
										  when "001"=>  col_green<="01000000";    
										  when "010"=>  col_green<="00100000";     
										  when "011"=>  col_green<="00010000";     
										  when "100"=>  col_green<="00001000";
										  when "101"=>  col_green<="00000100";
										  when "110"=>  col_green<="00000010";
										  when "111"=>  col_green<="00000001";
										  WHEN OTHERS =>col_green<="00000000";
								 end case;
								 row<="11111101";
							   else row<="11111111";
							   end if;
				 when 7  =>   col_green<="00000000"; row<="11111110";
								 CASE x1 IS 
										  when "000"=>  col_red<="11100000";
										  when "001"=>  col_red<="11100000";
										  when "010"=>  col_red<="01110000";
										  when "011"=>  col_red<="00111000";
										  when "100"=>  col_red<="00011100";
										  when "101"=>  col_red<="00001110";
										  when "110"=>  col_red<="00000111";
										  when "111"=>  col_red<="00000111";
										  WHEN OTHERS =>col_red<="00000000";
								 end case;
								
                when others => col_green<="00000000";col_red<="00000000"; row<="11111111";
				end case;
      end if;
 end process ;            
END a;

----------------------------------------------
--名称:底板移动计数器                                                                         5
--功能:实现底板移动
--输入:BTN1,BTN2
--输出:x[2]
--编译者邮箱:HeWenKang@bupt.edu.cn
----------------------------------------------
LIBRARY IEEE;               
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;
ENTITY hwk7_02_movecount IS             
	PORT(	 
		    clkin:IN STD_LOGIC;
		    btn:IN STD_LOGIC_VECTOR(1 downto 0);
		    x1:OUT STD_LOGIC_VECTOR(2 downto 0));
END ;
ARCHITECTURE a OF hwk7_02_movecount IS

signal temp: integer range 0 to 5;

BEGIN

p1:	PROCESS(clkin)
	BEGIN
if rising_edge(clkin) then	
 if  (btn="01") then
  if temp =0 then
	 temp<=0;
	else temp<=temp-1; 
  end if;
 elsif  (btn="10") then
  if temp =5 then
	 temp<=5;
	else temp<=temp+1; 
  end if; 
 end if;
 end if;
 end process;
 

p2: process(temp)
	begin
case temp is
	when 0 => x1<= "001";
	when 1 => x1<= "010";
	when 2 => x1<= "011";
	when 3 => x1<= "100";
	when 4 => x1<= "101";
	when 5 => x1<= "110";
end case;		
	END PROCESS ;
END a;
----------------------------------------------
--名称:小球下落计数器                                                                       6
--功能:实现小球下落
--输入:M[2],clk_2hz
--输出:x[2]
--编译者邮箱:HeWenKang@bupt.edu.cn
----------------------------------------------
LIBRARY IEEE;               
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;
ENTITY hwk7_02_fallpointcount IS             
	PORT(
		    clkin,clear: IN STD_LOGIC;
		    clkin_2Hz: IN STD_LOGIC;
		    speed:IN STD_LOGIC_VECTOR(1 downto 0);
		    M:IN STD_LOGIC_VECTOR(2 downto 0);
		    x0:OUT STD_LOGIC_VECTOR(2 downto 0);
		    y0:OUT STD_LOGIC_VECTOR(2 downto 0));
END ;
ARCHITECTURE a OF hwk7_02_fallpointcount IS
	SIGNAL temp1:  STD_LOGIC_VECTOR(2 downto 0);
	SIGNAL temp2:  integer range 0 to 30;	
BEGIN
	PROCESS(clkin_2Hz,clear)
	BEGIN
	

	     if (clear='1') then 
	      temp2<=0;   
      elsif rising_edge(clkin_2Hz) then
      case speed is
     when "00" =>
	          if temp2>=27 then
	          temp1<=M;temp2<=0;
	          else temp2<=temp2+1;
	         end if; 
	 when "01" =>
	          if temp2>=27 then
	          temp1<=M;temp2<=0;
	          else temp2<=temp2+2;
	         end if;          
	 when "10" =>
	          if temp2>=27 then
	          temp1<=M;temp2<=0;
	          else temp2<=temp2+3;
	         end if;	         
	 when "11" =>
	          if temp2>=27 then
	          temp1<=M;temp2<=0;
	          else temp2<=temp2+4;
	         end if;	         
	 when others =>
	          if temp2>=27 then
	          temp1<=M;temp2<=0;
	          else temp2<=temp2+2;
	         end if;	         
	 end case;       	         
        x0<=temp1;
     case temp2 is
	       when  0|1|2|3  => y0<="000";
	       when  4|5|6|7  => y0<="001";
	       when  8|9|10|11  => y0<="010";
	       when  12|13|14|15  => y0<="011";
	       when  16|17|18|19  => y0<="100";
	       when  20|21|22|23  => y0<="101";
           when  24|25|26|27  => y0<="110";
          when others => y0<="111";
    end case;
     end if; 
   
	END PROCESS ;
END a;

----------------------------------------------
--名称:   模式选择器                                                                             7
--功能:实现模式选择  模式选择000,实现倒计时动画001,胜利动画010,失败动画011,游戏动画100--输入:BTN0,BTN1,BTN2
--输出:MODEL[2]
--编译者邮箱:HeWenKang@bupt.edu.cn       MODEL_out <="100"; 
----------------------------------------------
LIBRARY IEEE;                   
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;
ENTITY hwk7_02_MODEL IS             
	PORT( BTN0 , BTN1 ,BTN2:IN STD_LOGIC;
		 MODEL_in:in STD_LOGIC_VECTOR(2 DOWNTO 0);
		 MODEL:OUT STD_LOGIC_VECTOR(2 DOWNTO 0);
		 finish:in STD_LOGIC_VECTOR(1 DOWNTO 0);
		 close:	out STD_LOGIC
		 );
END ;

ARCHITECTURE a OF hwk7_02_MODEL IS
 begin
 p1: process(btn0,model_in,finish)
 begin
  
  if btn0 ='1' then
 MODEL<="001";
   elsif model_in ="100" and finish = "10"   then
  MODEL<="010"; 
    elsif model_in ="100" and finish = "01"   then
   MODEL<="011";
  else 
 model<=model_in;
 end if;
 end process; 
 
  p2: process(btn0,model_in,finish)
 begin 
  if model_in ="100" then
  close<='0';
  else
 close<='1';
 end if;
 end process;
 
 
 
 
 END a;
 

----------------------------------------------
--名称:  得分判断模块                                                                           8
--功能:实现得分判断,如果得分,则输出一个高电平
--输入:x0[2],y0[2],x1[2]
--输出:goal
--编译者邮箱:HeWenKang@bupt.edu.cn
----------------------------------------------
LIBRARY IEEE;               
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;
ENTITY hwk7_02_goal IS             
	PORT(	MODEL :IN STD_LOGIC_VECTOR(2 DOWNTO 0);
		    clkin: IN STD_LOGIC;
            goal:out STD_LOGIC;
		    x0:in STD_LOGIC_VECTOR(2 downto 0);
		    y0:in STD_LOGIC_VECTOR(2 downto 0);
		    x1:in STD_LOGIC_VECTOR(2 downto 0));
END ;

ARCHITECTURE a OF hwk7_02_goal IS
begin

p1: process(clkin)
  begin
 if rising_edge(clkin) then
  case model is
when  "100"  =>
    if (y0="110")  then
   if x0=x1-1 or x0=x1 or x0=x1+1  then
       goal <='1';
   end if;
 else 
    goal <='0';
 end if;   
 
 when others =>
    goal <='0';
 end case;
end if;
end process;
end a;

----------------------------------------------
--名称:  数码管计分模块                                                                            9
--功能:实现得分计数,当收到一个高电平,数码管显示数字+1
--输入:goal, clk, clear, clk_1hz
--输出:seg[7],cat[7],finish[1]
--编译者邮箱:HeWenKang@bupt.edu.cn
----------------------------------------------
LIBRARY IEEE;               
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;
Library ieee;
Use ieee.std_logic_1164.all;

ENTITY hwk7_02_goalSegmentDisplay IS
PORT(clk,clk_1Hz, close: in std_logic;
     goal:in std_logic;
     finish: out std_logic_vector(1 downto 0);
     number: OUT STD_LOGIC_VECTOR(6 downto 0);
     cat:    OUT STD_LOGIC_VECTOR(7 DOWNTO 0)
     );
END hwk7_02_goalSegmentDisplay; 

ARCHITECTURE a OF hwk7_02_goalSegmentDisplay IS
signal i ,time_high,time_low: STD_LOGIC_VECTOR(3 DOWNTO 0);
signal finish_signal,finish_signal1: std_logic_vector(1 downto 0);
signal point_count: integer range 0 to 3;
BEGIN

p1:PROCESS(goal,close,clk,clk_1Hz,time_high,time_low)    
     begin
          if close ='1' then
         i<="0000";finish_signal<="00";
     elsif rising_edge(goal) then
       if i="0100" then
           finish_signal<="10";
      else  i<=i+1;
       end if;
      end if;
    end process;


 p2:    PROCESS(point_count,goal,close,clk,clk_1Hz,time_high,time_low)    
     begin
     if close ='1' then
        time_high<="0011";time_low<="0000";finish_signal1<="00";
     elsif rising_edge(clk_1Hz) then     
          if(time_low="0000" and time_high="0000") then
                finish_signal1<="01";
          elsif(time_low="0000" ) then 
               time_low<="1001";time_high<=time_high-1;
          else time_low<=time_low-1;
          end if;
      end if;
   case point_count is   
  when 0 =>
       case i is
    WHEN "0000" =>number<="1111110";cat<="11111110";--0
    WHEN "0001" =>number<="0110000";cat<="11111110";--1
    WHEN "0010" =>number<="1101101";cat<="11111110";--2
    WHEN "0011" =>number<="1111001";cat<="11111110";--3
    WHEN "0100" =>number<="0110011";cat<="11111110";--4
    WHEN "0101" =>number<="1011011";cat<="11111110";--5
    WHEN "0110" =>number<="1011111";cat<="11111110";--6
    WHEN "0111" =>number<="1110000";cat<="11111110";--7
    WHEN "1000" =>number<="1111111";cat<="11111110";--8
    WHEN "1001" =>number<="1111011";cat<="11111110";--9
    WHEN OTHERS =>number<="0000000";cat<="11111111";--other
    end case;
  when 1 =>  
         case time_high is
    WHEN "0000" =>number<="1111110";cat<="11011111";--0
    WHEN "0001" =>number<="0110000";cat<="11011111";--1
    WHEN "0010" =>number<="1101101";cat<="11011111";--2
    WHEN "0011" =>number<="1111001";cat<="11011111";--3
    WHEN "0100" =>number<="0110011";cat<="11011111";--4
    WHEN "0101" =>number<="1011011";cat<="11011111";--5
    WHEN "0110" =>number<="1011111";cat<="11011111";--6
    WHEN "0111" =>number<="1110000";cat<="11011111";--7
    WHEN "1000" =>number<="1111111";cat<="11011111";--8
    WHEN "1001" =>number<="1111011";cat<="11011111";--9
    WHEN OTHERS =>number<="0000000";cat<="11111111";--other
    end case;
 when 2 =>   
         case time_low is
    WHEN "0000" =>number<="1111110";cat<="11101111";--0
    WHEN "0001" =>number<="0110000";cat<="11101111";--1
    WHEN "0010" =>number<="1101101";cat<="11101111";--2
    WHEN "0011" =>number<="1111001";cat<="11101111";--3
    WHEN "0100" =>number<="0110011";cat<="11101111";--4
    WHEN "0101" =>number<="1011011";cat<="11101111";--5
    WHEN "0110" =>number<="1011111";cat<="11101111";--6
    WHEN "0111" =>number<="1110000";cat<="11101111";--7
    WHEN "1000" =>number<="1111111";cat<="11101111";--8
    WHEN "1001" =>number<="1111011";cat<="11101111";--9
    WHEN OTHERS =>number<="0000000";cat<="11111111";--other
    end case;
WHEN OTHERS =>number<="0000000";cat<="11111111";--other
end case;
    end process;
    
 p3: process (clk)
begin 
if rising_edge(clk) then
  point_count <= point_count + 1;
     if point_count=3 then
        point_count<=0;
      end if;
 end if;
 end process;

      finish<=finish_signal or finish_signal1;


   

    
END a;
----------------------------------------------
--名称:   蜂鸣器模块                                                                          10
--功能:接球响一下,胜利音调上升,失败音调下降
--输入:goal,finish, clk_in 
--输出:music
--编译者邮箱:HeWenKang@bupt.edu.cn
----------------------------------------------
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;

ENTITY hwk7_02_music IS
	PORT(
		clk_in:IN STD_LOGIC;
		goal:IN STD_LOGIC;
		model:IN STD_LOGIC_vector(2 downto 0);
		music:OUT STD_LOGIC);
END hwk7_02_music;

ARCHITECTURE a OF hwk7_02_music IS
	SIGNAL tmp:INTEGER RANGE 0 TO 2000;
	SIGNAL clktmp:STD_LOGIC;
	SIGNAL tmp2:INTEGER RANGE 0 TO 300000;
	SIGNAL clktmp2:STD_LOGIC;
	SIGNAL fp:INTEGER RANGE 0 TO 20000;
	SIGNAL q_temp: INTEGER RANGE 0 TO 144;
	signal music_win,music_lose: STD_LOGIC;
	
BEGIN

PROCESS(fp,clk_in) --Changeable div
	BEGIN
		IF clk_in'event AND clk_in='1' THEN
			IF tmp >= fp/2 THEN
				tmp<=0; clktmp<=NOT clktmp;
				ELSE
				tmp<=tmp+1;
			END IF;
		END IF;
END PROCESS;

	
PROCESS(clk_in) --0.5S div
	BEGIN
		IF clk_in'event AND clk_in='1' THEN
			IF tmp2=83333 THEN
				tmp2<=0; clktmp2<=NOT clktmp2;
				ELSE
				tmp2<=tmp2+1;
			END IF;
		END IF;
END PROCESS;
	
PROCESS(clktmp2,model)
	BEGIN
	IF model="100" THEN
		q_temp<=0 ;
	ELSIF(clktmp2'event AND clktmp2='1' and model="010")THEN
		IF q_temp =7 THEN  --wait for finish
			q_temp<=7 ;
		ELSE
			q_temp<=q_temp+1;
		END IF;
	ELSIF(clktmp2'event AND clktmp2='1' and model="011")THEN
		IF q_temp =64 THEN  --wait for finish
			q_temp<=64 ;
		ELSE
			q_temp<=q_temp+8;
		END IF;
	END IF;
END PROCESS;

PROCESS(q_temp,clk_in)
	BEGIN
	if rising_edge(clk_in) then
	case q_temp is 
		when 0|56 => fp<=5000;
		when 1|48 => fp<=1911;
		when 2|40 => fp<=1703;
		when 3|32 => fp<=1517;
		when 4|24 => fp<=1412;
		when 5|16 => fp<=1276;
		when 6|8  => fp<=1136;
		when others => fp<=5000;
	end case;
	end if;
END PROCESS;

p1:process(clk_in)
begin
if rising_edge(clk_in) then
if(goal='1') then
 music<='1';
 elsif (model="010") then
 music<=clktmp;
 elsif (model="011")  then
 music<=clktmp;
else
music<='0';
end if;
end if;
end process;






END a;

----------------------------------------------
--名称:接球小游戏顶层设计                                                                    0
--功能:根据按键完成点阵接球小游戏
--输入:1MHz,BTN0,BTN1,BTN2
--输出:点阵显示, 数码管 ,蜂鸣器
--编译者邮箱:HeWenKang@bupt.edu.cn
----------------------------------------------
LIBRARY IEEE;                       
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;
ENTITY game IS             
	PORT
		(btn0:IN STD_LOGIC;
		 btn1:IN STD_LOGIC;
		 btn2:IN STD_LOGIC;
		 clk_1M:IN STD_LOGIC;
		 speed:IN STD_LOGIC_VECTOR(1 downto 0);
		 col_red:OUT STD_LOGIC_VECTOR(7 DOWNTO 0);
		 col_green:OUT STD_LOGIC_VECTOR(7 DOWNTO 0);
		 row:OUT STD_LOGIC_VECTOR(7 DOWNTO 0);
		 music:OUT STD_LOGIC;
		 segnumber:OUT STD_LOGIC_VECTOR(6 DOWNTO 0);
		 cat:OUT STD_LOGIC_VECTOR(7 DOWNTO 0)
		);
END game;

ARCHITECTURE a OF game IS

COMPONENT hwk7_02_M1 IS             
	PORT(clkin:IN STD_LOGIC;
		 clear:IN STD_LOGIC;
		 m:OUT STD_LOGIC_VECTOR(2 downto 0));
  END COMPONENT;
  
COMPONENT hwk7_02_CLK_DIVISON IS             
	PORT(clkin:IN STD_LOGIC;
		 clk_out_10Hz, clk_out_1Hz, clk_out_2Hz :OUT STD_LOGIC	
		 );
  END COMPONENT;
  
COMPONENT hwk7_02_FD IS             
	PORT(clkin , BTN0 , BTN1 ,BTN2,goal:IN STD_LOGIC;
		 FDBTN0 , FDBTN1 ,FDBTN2,fdgoal:OUT STD_LOGIC	
		 );
  END COMPONENT;
  
COMPONENT hwk7_02_POINTDISPLAY IS             
	PORT(X0:IN STD_LOGIC_VECTOR(2 DOWNTO 0);
		 Y0:IN STD_LOGIC_VECTOR(2 DOWNTO 0);
		 X1:IN STD_LOGIC_VECTOR(2 DOWNTO 0);
		 MODEL :IN STD_LOGIC_VECTOR(2 DOWNTO 0);
		 MODEL_out :out STD_LOGIC_VECTOR(2 DOWNTO 0);
		 clkin: IN STD_LOGIC;
		 clkin_1Hz: IN STD_LOGIC;
		 col_red:OUT STD_LOGIC_VECTOR(7 DOWNTO 0);
		 col_green:OUT STD_LOGIC_VECTOR(7 DOWNTO 0);
		 row:OUT STD_LOGIC_VECTOR(7 DOWNTO 0)
		 );
  END COMPONENT;
  
 COMPONENT hwk7_02_movecount IS             
	PORT(	clkin:IN STD_LOGIC;
		    btn:IN STD_LOGIC_VECTOR(1 downto 0);		    
		    x1:OUT STD_LOGIC_VECTOR(2 downto 0));
  END COMPONENT;
 
  COMPONENT hwk7_02_MODEL IS             
	PORT( BTN0 , BTN1 ,BTN2:IN STD_LOGIC;
		 MODEL_in:in STD_LOGIC_VECTOR(2 DOWNTO 0);
		 MODEL:OUT STD_LOGIC_VECTOR(2 DOWNTO 0);
		 finish:in STD_LOGIC_VECTOR(1 DOWNTO 0);
		 close:	out STD_LOGIC
		 );
  END COMPONENT;
  
  COMPONENT  hwk7_02_fallpointcount IS             
	PORT(	clear,clkin: IN STD_LOGIC;
		    clkin_2Hz: IN STD_LOGIC;
		    speed:IN STD_LOGIC_VECTOR(1 downto 0);
		    M:IN STD_LOGIC_VECTOR(2 downto 0);
		    x0:OUT STD_LOGIC_VECTOR(2 downto 0);
		    y0:OUT STD_LOGIC_VECTOR(2 downto 0));
  END COMPONENT;
  
   COMPONENT  hwk7_02_goal IS             
PORT(	clkin: IN STD_LOGIC;
            goal:out STD_LOGIC;
            MODEL :IN STD_LOGIC_VECTOR(2 DOWNTO 0);
		    x0:in STD_LOGIC_VECTOR(2 downto 0);
		    y0:in STD_LOGIC_VECTOR(2 downto 0);
		    x1:in STD_LOGIC_VECTOR(2 downto 0));
  END COMPONENT;
  
COMPONENT hwk7_02_goalSegmentDisplay IS
PORT(clk,clk_1Hz, close: in std_logic;
     goal:in std_logic;
     finish: out std_logic_vector(1 downto 0);
     number: OUT STD_LOGIC_VECTOR(6 DOWNTO 0);
     cat:    OUT STD_LOGIC_VECTOR(7 DOWNTO 0)
     );
END COMPONENT;  
  
COMPONENT hwk7_02_music IS
	PORT(
		clk_in:IN STD_LOGIC;
		goal:IN STD_LOGIC;
		model:IN STD_LOGIC_vector(2 downto 0);
		music:OUT STD_LOGIC);
END COMPONENT;

 
SIGNAL m_signal: STD_LOGIC_VECTOR(2 DOWNTO 0);
SIGNAL clk_10Hz_signal,clk_1Hz_signal,clk_2Hz_signal: STD_LOGIC;
SIGNAL FDBTN0_signal , FDBTN1_signal ,FDBTN2_signal,fdgoal_signal:STD_LOGIC;
SIGNAL x0_signal,y0_signal,x1_signal,MODEL_signal,MODEL_out_signal: STD_LOGIC_VECTOR(2 DOWNTO 0);
SIGNAL goal_signal,close_signal: STD_LOGIC;
SIGNAL finish_signal: STD_LOGIC_vector(1 downto 0);

BEGIN
G1:hwk7_02_M1 PORT MAP(clkin=>clk_1M,clear=>FDBTN0_signal,m=>m_signal);
G2:hwk7_02_CLK_DIVISON PORT MAP(clkin=>clk_1M,clk_out_10Hz=>clk_10Hz_signal, clk_out_1Hz=>clk_1Hz_signal, clk_out_2Hz=>clk_2Hz_signal);
G3:hwk7_02_FD PORT MAP(goal=>goal_signal,fdgoal=>fdgoal_signal,clkin=>clk_1M , BTN0=>btn0 , BTN1=>btn1 , BTN2=>btn2, FDBTN0=>FDBTN0_signal , FDBTN1=>FDBTN1_signal ,FDBTN2=>FDBTN2_signal);
G4:hwk7_02_POINTDISPLAY PORT MAP(x0=>x0_signal,y0=>y0_signal,x1=>x1_signal,MODEL=>MODEL_signal,MODEL_out=>MODEL_out_signal,clkin=>clk_1M,clkin_1Hz=>clk_1Hz_signal,col_red=>col_red,col_green=>col_green,row=>row);
G5:hwk7_02_movecount PORT MAP(clkin=>clk_10Hz_signal,btn(0)=>FDBTN1_signal,btn(1)=>FDBTN2_signal,x1=>x1_signal);
G6:hwk7_02_fallpointcount PORT MAP(speed=>speed,clear=>FDBTN0_signal,clkin=>clk_1M,clkin_2Hz=>clk_2Hz_signal,M=>m_signal,x0=>x0_signal,y0=>y0_signal);
G7:hwk7_02_MODEL PORT MAP(finish=>finish_signal ,model_in=>model_out_signal,btn0=>FDBTN0_signal,btn1=>FDBTN1_signal,btn2=>FDBTN2_signal,MODEL=>MODEL_signal,close=>close_signal);
G8:hwk7_02_goal PORT MAP(model=>model_signal,clkin=>clk_1M,x0=>x0_signal,y0=>y0_signal,x1=>x1_signal,goal=>goal_signal);
G9:hwk7_02_goalSegmentDisplay PORT MAP(clk=>clk_1M,clk_1hz=>clk_1hz_signal,close=>close_signal,goal=>goal_signal,finish=>finish_signal,number=>segnumber,cat=>cat);
G10:hwk7_02_music PORT MAP(goal=>fdgoal_signal,clk_in=>clk_1M,model=>model_out_signal,music=>music);
END;

五、遇到的问题和解决办法

问题:小球跳格下落,每次下落两行
解决办法: 在分频器的代码外嵌套了一个上升沿的判断语句,如下面红色部分所示。
p4:process(count_2Hz,clkin)
begin
if rising_edge(clkin) then
if count_2Hz<125000 then
clk_out_2Hz <= ‘0’;
else clk_out_2Hz <= ‘1’;
end if;
end if;
end process p4;

问题:验收时老师指出,小球下落未到最后一行,到了倒数第二行就重新到第0行了。
解决办法: 在小球位矢计数器和点阵显示模块中加入最后一行的代码,代码格式和前几行格式一样,只要复制就行。

问题:底板位矢计数器中,两个进程中无法对同一个信号进行赋值。
解决办法:加一个扫描信号,以它为敏感信号建立一个进程。将输入的按键信号合并为一组二进制信号,当扫描到btn为01或者10时,对底板的位矢进行+1或者-1。

六、总结

这次实验时间跨度很大,大二下的实验,因为疫情原因只能在家用做仿真,回学校才拿到器件开始做实物实验,不过因祸得福,我的Quartus使用的熟练度有了很大提升。
回学校用了实物以后才知道实物电路和仿真的差距有多大,很多问题都是用仿真软件时难以发现的。也在实验中通过烧录发现问题,解决问题,也是需要不断的实验来积累自己的经验的。
这个实验做起来到最后还是有一些遗憾的吧,没有把所有的提高功能做完,一个是因为每周六要上课,学校压缩课时没有太多课余时间,二个是因为数电实验验收前一阵子恰好赶上期中考试,但是在写代码的时候预留了部分接口,给之后提高留了空间,等学期结束,可以把提高的部分自己给写完。
原本挺讨厌实验课的,觉得实验中遇到的问题很“玄学”,很多问题是需要经验积累的,不去踩这个坑就很难知道这个问题,就很难意识到问题。数字电路的问题没有C代码那样容易被发现。但是一旦有了经验,知道问题在哪,调起来还是很快的。做了这次接球小游戏实验,我对数电实验没有原来那么厌恶或者说畏惧了,掌握了很多调试的方法,比如说将其分块分别测试,看仿真的波形,这些方法都是需要经验去积累和自行领会的。感谢这次实验机会吧,也感谢老师的答疑和帮助,谢谢!

Python接球小游戏是一款简单的游戏,玩家需要控制一个接球器来接住从上方掉落的球,每接到一个球得一分,如果接到炸弹则扣一分。以下是一个简单的Python代码示例: ```python import pygame import random # 初始化游戏 pygame.init() # 设置游戏窗口大小 screen_width = 800 screen_height = 600 screen = pygame.display.set_mode((screen_width, screen_height)) pygame.display.set_caption("接球小游戏") # 定义颜色 BLACK = (0, 0, 0) WHITE = (255, 255, 255) # 加载图片 ball_image = pygame.image.load("ball.png") bomb_image = pygame.image.load("bomb.png") player_image = pygame.image.load("player.png") # 获取图片大小 ball_width = ball_image.get_width() ball_height = ball_image.get_height() bomb_width = bomb_image.get_width() bomb_height = bomb_image.get_height() player_width = player_image.get_width() player_height = player_image.get_height() # 设置玩家初始位置 player_x = (screen_width - player_width) // 2 player_y = screen_height - player_height # 设置球和炸弹的初始位置和速度 ball_x = random.randint(0, screen_width - ball_width) ball_y = 0 ball_speed = 5 bomb_x = random.randint(0, screen_width - bomb_width) bomb_y = 0 bomb_speed = 5 # 设置分数 score = 0 # 游戏主循环 running = True clock = pygame.time.Clock() while running: for event in pygame.event.get(): if event.type == pygame.QUIT: running = False # 移动玩家 keys = pygame.key.get_pressed() if keys[pygame.K_LEFT]: player_x -= 5 if keys[pygame.K_RIGHT]: player_x += 5 # 更新球和炸弹的位置 ball_y += ball_speed bomb_y += bomb_speed # 判断球是否接到玩家 if ball_y + ball_height >= player_y and ball_x + ball_width >= player_x and ball_x <= player_x + player_width: score += 1 ball_x = random.randint(0, screen_width - ball_width) ball_y = 0 # 判断炸弹是否接到玩家 if bomb_y + bomb_height >= player_y and bomb_x + bomb_width >= player_x and bomb_x <= player_x + player_width: score -= 1 bomb_x = random.randint(0, screen_width - bomb_width) bomb_y = 0 # 绘制游戏界面 screen.fill(BLACK) screen.blit(ball_image, (ball_x, ball_y)) screen.blit(bomb_image, (bomb_x, bomb_y)) screen.blit(player_image, (player_x, player_y)) pygame.display.flip() # 控制游戏帧率 clock.tick(60) # 游戏结束后退出 pygame.quit() ``` 请注意,上述代码中的图片文件需要提前准备好,并与代码文件放在同一目录下。你可以根据自己的需求自定义图片和调整游戏的逻辑。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值