基于FPGA的VGA小霸王游戏机(附源码)


前言:
本文主要介绍了基于FPGA的VGA小霸王游戏机原理及操作过程。使用的软件是Quartus Ⅱ,该实验使用fpga芯片为cyclone IV EP4CE115F29C7。
需要注意,使用的FPGA板子为DE2-115,该实验板中数码管显示模块使用的是直接控制,即每个引脚控制一个数码管的一根线,使用了74系列芯片的板子需要自己更改数码管显示模块或者直接丢弃该模块也行。
同时vga显示使用的是RGB 888模式经过ADV7123芯片转换为VGA信号,使用代码时需要注意。如下两图所示。
有疑问的地方欢迎大家积极提问,有空都会回复。

在这里插入图片描述

在这里插入图片描述

1. 项目目标

1.设计并实现基于FPGA的硬件平台,兼容小霸王游戏机的经典游戏。
2.支持VGA接口,能够将游戏画面输出到现代显示器上。
3.开发用户友好的界面,包括游戏选择菜单、设置选项等。
4.实现至少3款经典小霸王游戏的移植与兼容。
5.确保游戏运行稳定,操作响应灵敏。

2. 技术功能

1.硬件设计: 选择使用DE2-115系列FPGA套版作为基础硬件。
2.软件开发: 使用quartus2编写Verilog代码实现游戏逻辑处理,图像渲染,以及用户界面等。
3.游戏适配: 对选定的经典小霸王游戏进行逆向工程,确保游戏能在新平台上稳定运行。
4.界面设计: 设计直观易用的图形用户界面,包括游戏启动、选择、设置等功能。
5.测试与优化: 进行系统测试,确保硬件稳定性和游戏兼容性,优化用户体验。

3. 项目模块设计

3.1 项目总体框架

项目总体由五个大模块与一个选择模块,再加上按键滤波模块与pll锁相环模块构成。
其中五个大模块分别为:
1.游戏菜单模块game_machine_menu
2.贪吃蛇模块snakeeat
3.俄罗斯方块模块tetris
4.五子棋模块gomoku
5.游戏机设置模块setting

选择模块根据游戏菜单模块选择的游戏或者设置来将相关数据传输给FPGA顶层外部接口以实现不同模块的切换。
在这里插入图片描述

3.2 游戏菜单模块game_machine_menu

其中menu_ctrl模块为菜单界面控制模块,根据菜单状态产生相应控制信号,通过上下按键实现菜单选择切换,左右按键进入选择的菜单界面。四个vga_menu模块为上下移动形成的四种菜单情况。
在这里插入图片描述

3.3 贪吃蛇模块snakeeat

图为贪吃蛇模块RTL设计图,其中game_ctrl模块为游戏控制模块,根据当前游戏状态产生相应控制信号,按下任意按键,游戏开始,游戏结束后按下任意按键,返回游戏开始界面。
其中主要模块为vga_game模块与vga_ctrl模块。vga_game模块实现游戏正常运行逻辑。vga_ctrl模块产生有效图像的坐标信息显示到vga显示屏幕上去。vga_menu与vga_die模块为游戏开始与结束界面显示,seg_score模块实现游戏分数显示到数码管上。
在这里插入图片描述
具体游戏运行流程图如图所示。
在这里插入图片描述

3.4 俄罗斯方块模块tetris

图为俄罗斯方块模块RTL设计图,其中game_ctrl模块为游戏控制模块,根据当期游戏状态产生相应控制信号,按下任意按键,游戏开始,游戏结束后按下任意按键,返回游戏开始界面。
其中主要模块为vga_game模块与vga_ctrl模块。vga_game模块实现游戏正常运行逻辑。vga_ctrl模块产生有效图像的坐标信息显示到vga显示屏幕上去。vga_menu与vga_die模块为游戏开始与结束界面显示,seg_score模块实现游戏分数显示到数码管上。
在这里插入图片描述
具体游戏运行状态流程图如图所示。
在这里插入图片描述

  1. S_idle态为初始空状态,即屏幕显示为空白
  2. S_new态用于产生新的俄罗斯方块。
  3. S_hold态为保持状态。在这个状态中进行计时,当时间到达一定间隔时,转到下落状态(S_down);或者等待输入信号(up,down,left,right)时,转到下落状态(S_down)或者(up,left,right)状态。
  4. S_down下降状态判断当前俄罗斯块能否下移一格。如果可以,则转到更新状态S_shift,如果不行,则转到更新矩阵状态S_remove_1。
  5. S_shift更新状态更新俄罗斯方块的坐标信息,之后返回保持状态(S_hold)。
  6. S_remove_1更新矩阵状态更新整个屏幕的矩阵信息。转移到消除状态2状态(S_remove_2)。
  7. S_remove_2消除状态判断是否可以消除,将可以消除的行消除,并将上面的行下移一行。重复此过程,直到没有可消除的行为止。跳转判定状态(S_isdie)
  8. S_isdie判定状态判断是否游戏结束。如果结束,则跳转到停止状态(S_stop)。如果没有,则跳转到产生俄罗斯方块状态,生成新的俄罗斯方块。
  9. S_stop停止状态清空整个屏幕,并跳转到判断状态(S_isdie)。
    具体状态转移表如图所示。
    在这里插入图片描述
    设计俄罗斯方块种类如图所示。
    在这里插入图片描述
    在游戏设计时,方块分为非活动方块与活动方块。
    1)非活动方块为:(1)之前下落的方块;(2)下落后方块消除之后的结果。由背景矩阵Background表示。根据Background的每个位上是否为1判断该点是否有方块。
    2)活动方块为当前下落中的方块,由活动方块坐标与方块类型表示。
    因为需要对方块实现旋转。所以方块固定点为方块旋转时不变的格点,依据方块种类决定。不同的种类有着不同的旋转点。同时横纵两个坐标确定方块固定点位置,再根据方块形状与旋转状态进行分类判断实现方块的显示。
    其中基础俄罗斯方块共有8种,每个方块都具有2-4个不等的旋转种类。

3.5 五子棋模块gomoku

图为五子棋模块RTL设计图,其中game_ctrl模块为游戏控制模块,根据当期游戏状态产生相应控制信号,按下任意按键,游戏开始,游戏结束后按下任意按键,返回游戏开始界面。
其中主要模块为vga_game模块与vga_ctrl模块。vga_game模块实现游戏正常运行逻辑。vga_ctrl模块产生有效图像的坐标信息显示到vga显示屏幕上去。vga_menu与vga_b_win模块,vga_w_win模块为游戏开始与结束界面显示。
在这里插入图片描述
具体游戏运行流程图如图所示。
在这里插入图片描述
其中S_idle为空状态,即屏幕显示为空白;S_balck_down为黑棋落子态;S_balck_judge态判断黑棋是否胜利;S_white_down为白棋落子态;
S_white_judge态判断白棋是否胜利。

3.6 游戏机设置模块setting

图为游戏机设置模块RTL设计图,其中vga_pic模块进行图像的处理,vga_ctrl模块产生有效图像的坐标信息显示到vga显示屏幕上去。
在这里插入图片描述
可以更改的数据为贪吃蛇与俄罗斯方块游戏的运行速度。

4. 项目测试

启动游戏机,初始界面如图所示。
在这里插入图片描述
进入其中一个游戏操作都是,上下按键选择到游戏,此时再按下任意左右一个按键进入该游戏名称界面,或者按下上下任意一个退回到游戏选择界面,进入游戏后再次按下上下任意一个开始游戏,游戏结束后,按下上下按键退回该游戏名称界面,或者按下左右按键重新开始该游戏。

下图分别为贪吃蛇,俄罗斯方块与五子棋游戏界面进行图。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
进入游戏设置更改游戏数据。如图所示。
在这里插入图片描述

5. 项目源码

链接:https://pan.baidu.com/s/1beuTb0pmbuVCdytBj7wSPA?pwd=CWM0
提取码:CWM0

部分源码见下:

5.1 顶层模块game_machine

`timescale  1ns/1ns

module  game_machine
(
    input   wire            sys_clk     ,   //输入工作时钟,频率50MHz
    input   wire            sys_rst_n   ,   //输入复位信号,低电平有效
    input   wire            up          ,   //上
    input   wire            down        ,   //下
    input   wire            left        ,   //左
    input   wire            right       ,   //右
    input   wire            confirm     ,   //落子
    
    output  wire            hsync       ,   //输出行同步信号
    output  wire            vsync       ,   //输出场同步信号
    output  wire    [7:0]   vga_r       ,   //输出像素信息  //高八位
    output  wire    [7:0]   vga_g       ,   //输出像素信息
    output  wire    [7:0]   vga_b       ,   //输出像素信息  //低八位
    output  wire            vga_clk_dis ,   //vga引脚时钟
    output  wire            disp_vld    ,    //背光开启标志
    output  wire     [6:0]  SG0,SG1,SG2,SG3,SG4,SG5,SG6,SG7  
);

//********************************************************************//
//****************** Parameter and Internal Signal *******************//
//********************************************************************//
wire            vga_clk ;   //VGA工作时钟,频率25MHz
wire            locked  ;   //PLL locked信号
wire            rst_n   ;   //VGA模块复位信号

wire    [2:0]   game_machine_status;//当前游戏机状态
wire    [3:0]   game_ch            ;   //根据菜单选择的游戏,输出到顶层控制游戏界面
wire            snake_game_return,tetris_game_return,gomoku_game_return,setting_game_return;   //返回游戏选择界面
wire            up_flag,down_flag,left_flag,right_flag,confirm_flag;
//game_machine_menu
wire            hsync_menu,vsync_menu,vga_clk_dis_menu,disp_vld_menu;
wire    [7:0]   vga_r_menu,vga_g_menu,vga_b_menu;
//snakeeat
wire            hsync_snake,vsync_snake,vga_clk_dis_snake,disp_vld_snake;
wire    [7:0]   vga_r_snake,vga_g_snake,vga_b_snake;
wire    [6:0]   SG0_snake,SG1_snake,SG2_snake,SG3_snake,SG4_snake,SG5_snake,SG6_snake,SG7_snake;
//tetris
wire            hsync_tetris,vsync_tetris,vga_clk_dis_tetris,disp_vld_tetris;
wire    [7:0]   vga_r_tetris,vga_g_tetris,vga_b_tetris;
wire    [6:0]   SG0_tetris,SG1_tetris,SG2_tetris,SG3_tetris,SG4_tetris,SG5_tetris,SG6_tetris,SG7_tetris;
//gomoku
wire            hsync_gomoku,vsync_gomoku,vga_clk_dis_gomoku,disp_vld_gomoku;
wire    [7:0]   vga_r_gomoku,vga_g_gomoku,vga_b_gomoku;
//setting
wire     [7:0]   snake_speed,tetris_speed;    //游戏速度
wire            hsync_setting,vsync_setting,vga_clk_dis_setting,disp_vld_setting;
wire    [7:0]   vga_r_setting,vga_g_setting,vga_b_setting;
//rst_n:VGA模块复位信号
assign  rst_n = (sys_rst_n & locked);

//------------- clk_gen_inst -------------
clk_25	clk_25_inst (
	.areset ( ~sys_rst_n ),//输入复位信号,高电平有效,1bit
	.inclk0 ( sys_clk ),   //输入50MHz晶振时钟,1bit
	.c0 ( vga_clk ),       
	.locked ( locked )     //输出VGA工作时钟,频率25Mhz,1bit
	);                     //输出pll locked信号,1bit
//游戏控制模块 根据游戏状态产生相应控制信号
game_choose game_choose_inst
(
	.vga_clk            (vga_clk            ) ,   //25MHz
	.sys_rst_n          (sys_rst_n          ) ,   //系统复位

    .up_flag            (up_flag            ) ,   //上
    .down_flag          (down_flag          ) ,   //下
    .left_flag          (left_flag          ) ,   //左
    .right_flag         (right_flag         ) ,   //右	
	.game_ch            (game_ch            ) ,   //根据菜单选择的游戏,输出到顶层控制游戏界面
    .snake_game_return  (snake_game_return),  //返回游戏选择界面
    .tetris_game_return (tetris_game_return),  //返回游戏选择界面
    .gomoku_game_return (gomoku_game_return),  //返回游戏选择界面
    .setting_game_return (setting_game_return),  //返回游戏选择界面
    
    .hsync_menu         (hsync_menu         ) ,   //输出行同步信号
    .vsync_menu         (vsync_menu         ) ,   //输出场同步信号
    .vga_r_menu         (vga_r_menu         ) ,   //输出像素信息  //高八位
    .vga_g_menu         (vga_g_menu         ) ,   //输出像素信息
    .vga_b_menu         (vga_b_menu         ) ,   //输出像素信息  //低八位
    .vga_clk_dis_menu   (vga_clk_dis_menu   ) ,   //vga引脚时钟
    .disp_vld_menu      (disp_vld_menu      ) ,   //背光开启标志

    .hsync_snake        (hsync_snake        ) ,   //输出行同步信号
    .vsync_snake        (vsync_snake        ) ,   //输出场同步信号
    .vga_r_snake        (vga_r_snake        ) ,   //输出像素信息  //高八位
    .vga_g_snake        (vga_g_snake        ) ,   //输出像素信息
    .vga_b_snake        (vga_b_snake        ) ,   //输出像素信息  //低八位
    .vga_clk_dis_snake  (vga_clk_dis_snake  ) ,   //vga引脚时钟
    .disp_vld_snake     (disp_vld_snake     ) ,   //背光开启标志
    .SG0_snake          (SG0_snake          ) ,       
    .SG1_snake          (SG1_snake          ) ,       
    .SG2_snake          (SG2_snake          ) ,       
    .SG3_snake          (SG3_snake          ) ,       
    .SG4_snake          (SG4_snake          ) ,       
    .SG5_snake          (SG5_snake          ) ,       
    .SG6_snake          (SG6_snake          ) ,       
    .SG7_snake          (SG7_snake          ) ,       

    .hsync_tetris       (hsync_tetris       ) ,   //输出行同步信号
    .vsync_tetris       (vsync_tetris       ) ,   //输出场同步信号
    .vga_r_tetris       (vga_r_tetris       ) ,   //输出像素信息  //高八位
    .vga_g_tetris       (vga_g_tetris       ) ,   //输出像素信息
    .vga_b_tetris       (vga_b_tetris       ) ,   //输出像素信息  //低八位
    .vga_clk_dis_tetris (vga_clk_dis_tetris ) ,   //vga引脚时钟
    .disp_vld_tetris    (disp_vld_tetris    ) ,   //背光开启标志
    .SG0_tetris         (SG0_tetris         ) ,       
    .SG1_tetris         (SG1_tetris         ) ,       
    .SG2_tetris         (SG2_tetris         ) ,       
    .SG3_tetris         (SG3_tetris         ) ,       
    .SG4_tetris         (SG4_tetris         ) ,       
    .SG5_tetris         (SG5_tetris         ) ,       
    .SG6_tetris         (SG6_tetris         ) ,       
    .SG7_tetris         (SG7_tetris         ) ,  

    .hsync_gomoku       (hsync_gomoku       ) ,   //输出行同步信号
    .vsync_gomoku       (vsync_gomoku       ) ,   //输出场同步信号
    .vga_r_gomoku       (vga_r_gomoku       ) ,   //输出像素信息  //高八位
    .vga_g_gomoku       (vga_g_gomoku       ) ,   //输出像素信息
    .vga_b_gomoku       (vga_b_gomoku       ) ,   //输出像素信息  //低八位
    .vga_clk_dis_gomoku (vga_clk_dis_gomoku ) ,   //vga引脚时钟
    .disp_vld_gomoku    (disp_vld_gomoku    ) ,   //背光开启标志

    .hsync_setting       (hsync_setting       ) ,   //输出行同步信号
    .vsync_setting       (vsync_setting       ) ,   //输出场同步信号
    .vga_r_setting       (vga_r_setting       ) ,   //输出像素信息  //高八位
    .vga_g_setting       (vga_g_setting       ) ,   //输出像素信息
    .vga_b_setting       (vga_b_setting       ) ,   //输出像素信息  //低八位
    .vga_clk_dis_setting (vga_clk_dis_setting ) ,   //vga引脚时钟
    .disp_vld_setting    (disp_vld_setting    ) ,   //背光开启标志

	.game_machine_status(game_machine_status) ,//当前游戏机状态
    .hsync              (hsync              ) ,   //输出行同步信号
    .vsync              (vsync              ) ,   //输出场同步信号
    .vga_r              (vga_r              ) ,   //输出像素信息  //高八位
    .vga_g              (vga_g              ) ,   //输出像素信息
    .vga_b              (vga_b              ) ,   //输出像素信息  //低八位
    .vga_clk_dis        (vga_clk_dis        ) ,   //vga引脚时钟
    .disp_vld           (disp_vld           ) ,   //背光开启标志
    .SG0                (SG0                ) ,
    .SG1                (SG1                ) ,
    .SG2                (SG2                ) ,
    .SG3                (SG3                ) ,
    .SG4                (SG4                ) ,
    .SG5                (SG5                ) ,
    .SG6                (SG6                ) ,
    .SG7                (SG7                )  
);

//------------- 选择游戏菜单 -------------
game_machine_menu game_machine_menu_inst
(
    .vga_clk    (vga_clk    ) ,   //输入工作时钟,频率50MHz
    .rst_n      (rst_n      ) ,   //输入复位信号,低电平有效
    .up_flag    (up_flag    ) ,   //上
    .down_flag  (down_flag  ) ,   //下
    .left_flag  (left_flag  ) ,   //左
    .right_flag (right_flag ) ,   //右
    .game_machine_status(game_machine_status),//当前游戏机状态
    
    .game_ch    (game_ch)   ,
    .hsync      (hsync_menu      ) ,   //输出行同步信号
    .vsync      (vsync_menu      ) ,   //输出场同步信号
    .vga_r      (vga_r_menu      ) ,   //输出像素信息  //高八位
    .vga_g      (vga_g_menu      ) ,   //输出像素信息
    .vga_b      (vga_b_menu      ) ,   //输出像素信息  //低八位
    .vga_clk_dis(vga_clk_dis_menu) ,   //vga引脚时钟
    .disp_vld   (disp_vld_menu   )     //背光开启标志
);
//------------- 贪吃蛇 -------------
snakeeat snakeeat_inst
(
    .vga_clk    (vga_clk    ) ,   //输入工作时钟,频率50MHz
    .rst_n      (rst_n  ) ,   //输入复位信号,低电平有效
    .up_flag    (up_flag    ) ,   //上
    .down_flag  (down_flag  ) ,   //下
    .left_flag  (left_flag  ) ,   //左
    .right_flag (right_flag ) ,   //右
    .game_machine_status(game_machine_status),//当前游戏机状态
    .snake_speed        (snake_speed        )    ,  //游戏速度
    
    .snake_game_return (snake_game_return),  //返回游戏选择界面
    .hsync      (hsync_snake      ) ,   //输出行同步信号
    .vsync      (vsync_snake      ) ,   //输出场同步信号
    .vga_r      (vga_r_snake      ) ,   //输出像素信息  //高八位
    .vga_g      (vga_g_snake      ) ,   //输出像素信息
    .vga_b      (vga_b_snake      ) ,   //输出像素信息  //低八位
    .vga_clk_dis(vga_clk_dis_snake) ,   //vga引脚时钟
    .disp_vld   (disp_vld_snake   ) ,   //背光开启标志
    .SG0        (SG0_snake        ) ,
    .SG1        (SG1_snake        ) ,
    .SG2        (SG2_snake        ) ,
    .SG3        (SG3_snake        ) ,
    .SG4        (SG4_snake        ) ,
    .SG5        (SG5_snake        ) ,
    .SG6        (SG6_snake        ) ,
    .SG7        (SG7_snake        ) 
);
//------------- 俄罗斯方块 -------------
tetris tetris_inst
(
    .vga_clk    (vga_clk    ) ,   //输入工作时钟,频率50MHz
    .rst_n  (rst_n      ) ,   //输入复位信号,低电平有效
    .up_flag    (up_flag    ) ,   //上
    .down_flag  (down_flag  ) ,   //下
    .left_flag  (left_flag  ) ,   //左
    .right_flag (right_flag ) ,   //右
    .game_machine_status(game_machine_status),//当前游戏机状态
    .tetris_speed        (tetris_speed        )    ,  //游戏速度
    
    .tetris_game_return (tetris_game_return),  //返回游戏选择界面
    .hsync      (hsync_tetris      ) ,   //输出行同步信号
    .vsync      (vsync_tetris      ) ,   //输出场同步信号
    .vga_r      (vga_r_tetris      ) ,   //输出像素信息  //高八位
    .vga_g      (vga_g_tetris      ) ,   //输出像素信息
    .vga_b      (vga_b_tetris      ) ,   //输出像素信息  //低八位
    .vga_clk_dis(vga_clk_dis_tetris) ,   //vga引脚时钟
    .disp_vld   (disp_vld_tetris   ) ,   //背光开启标志
    .SG0        (SG0_tetris        ) ,
    .SG1        (SG1_tetris        ) ,
    .SG2        (SG2_tetris        ) ,
    .SG3        (SG3_tetris        ) ,
    .SG4        (SG4_tetris        ) ,
    .SG5        (SG5_tetris        ) ,
    .SG6        (SG6_tetris        ) ,
    .SG7        (SG7_tetris        )  
);
//------------- 五子棋 -------------
gomoku gomoku_inst
(
    .vga_clk    (vga_clk    ) ,   //输入工作时钟,频率50MHz
    .rst_n      (rst_n      ) ,   //输入复位信号,低电平有效
    .up_flag    (up_flag    ) ,   //上
    .down_flag  (down_flag  ) ,   //下
    .left_flag  (left_flag  ) ,   //左
    .right_flag (right_flag ) ,   //右
    .confirm_flag(confirm_flag),  //落子
    .game_machine_status(game_machine_status),//当前游戏机状态
    
    .gomoku_game_return (gomoku_game_return),  //返回游戏选择界面
    .hsync      (hsync_gomoku      ) ,   //输出行同步信号
    .vsync      (vsync_gomoku      ) ,   //输出场同步信号
    .vga_r      (vga_r_gomoku      ) ,   //输出像素信息  //高八位
    .vga_g      (vga_g_gomoku      ) ,   //输出像素信息
    .vga_b      (vga_b_gomoku      ) ,   //输出像素信息  //低八位
    .vga_clk_dis(vga_clk_dis_gomoku) ,   //vga引脚时钟
    .disp_vld   (disp_vld_gomoku   )     //背光开启标志
);
setting setting_inst
(
    .vga_clk    (vga_clk    ) ,   //输入工作时钟,频率50MHz
    .rst_n      (rst_n      ) ,   //输入复位信号,低电平有效
    .up_flag    (up_flag    ) ,   //上
    .down_flag  (down_flag  ) ,   //下
    .left_flag  (left_flag  ) ,   //左
    .right_flag (right_flag ) ,   //右
    .game_machine_status(game_machine_status),//当前游戏机状态
    
    .setting_game_return(setting_game_return)    , //返回游戏选择界面
    .snake_speed        (snake_speed        )    ,  //游戏速度
    .tetris_speed       (tetris_speed       )    ,  //游戏速度
    .hsync      (hsync_setting      ) ,   //输出行同步信号
    .vsync      (vsync_setting      ) ,   //输出场同步信号
    .vga_r      (vga_r_setting    ) ,   //输出像素信息  //高八位
    .vga_g      (vga_g_setting      ) ,   //输出像素信息
    .vga_b      (vga_b_setting      ) ,   //输出像素信息  //低八位
    .vga_clk_dis(vga_clk_dis_setting) ,   //vga引脚时钟
    .disp_vld   (disp_vld_setting   )     //背光开启标志 
);

key_filiter  key_filiter_inst0
(
	.sys_clk     (sys_clk  )   ,
	.sys_rst_n   (sys_rst_n    )   ,
	.key_in      (up)      ,
	.key_flag    (up_flag )
);
key_filiter  key_filiter_inst1
(
	.sys_clk     (sys_clk  )   ,
	.sys_rst_n   (sys_rst_n    )   ,
	.key_in      (down   )   ,
	.key_flag    (down_flag )
);
key_filiter  key_filiter_inst2
(
	.sys_clk     (sys_clk  )   ,
	.sys_rst_n   (sys_rst_n    )   ,
	.key_in      (left   )   ,
	.key_flag    (left_flag )
);
key_filiter  key_filiter_inst3
(
	.sys_clk     (sys_clk  )   ,
	.sys_rst_n   (sys_rst_n    )   ,
	.key_in      (right   )   ,
	.key_flag    (right_flag )
);
key1_filiter  key_filiter1_inst0
(
	.sys_clk     (sys_clk  )   ,
	.sys_rst_n   (sys_rst_n    )   ,
	.key_in      (confirm   )   ,
	.key_flag    (confirm_flag )
);
endmodule

5.2 游戏控制模块game_choose

//游戏控制模块 根据游戏状态产生相应控制信号
module game_choose
(
	input   wire            vga_clk             ,   //25MHz
	input   wire            sys_rst_n           ,   //系统复位
                        
    input   wire            up_flag             ,   //上
    input   wire            down_flag           ,   //下
    input   wire            left_flag           ,   //左
    input   wire            right_flag          ,   //右	
	input   wire    [3:0]   game_ch             ,   //根据菜单选择的游戏,输出到顶层控制游戏界面
	input   wire            snake_game_return  ,   //返回游戏选择界面
    input   wire            tetris_game_return  ,   //返回游戏选择界面
    input   wire            gomoku_game_return  ,   //返回游戏选择界面
    input   wire            setting_game_return  ,   //返回游戏选择界面    
    
    input   wire            hsync_menu          ,   //输出行同步信号
    input   wire            vsync_menu          ,   //输出场同步信号
    input   wire    [7:0]   vga_r_menu          ,   //输出像素信息  //高八位
    input   wire    [7:0]   vga_g_menu          ,   //输出像素信息
    input   wire    [7:0]   vga_b_menu          ,   //输出像素信息  //低八位
    input   wire            vga_clk_dis_menu    ,   //vga引脚时钟
    input   wire            disp_vld_menu       ,   //背光开启标志
    
    input   wire            hsync_snake         ,   //输出行同步信号
    input   wire            vsync_snake         ,   //输出场同步信号
    input   wire    [7:0]   vga_r_snake         ,   //输出像素信息  //高八位
    input   wire    [7:0]   vga_g_snake         ,   //输出像素信息
    input   wire    [7:0]   vga_b_snake         ,   //输出像素信息  //低八位
    input   wire            vga_clk_dis_snake   ,   //vga引脚时钟
    input   wire            disp_vld_snake      ,   //背光开启标志
    input   wire    [6:0]   SG0_snake           ,       
    input   wire    [6:0]   SG1_snake           ,       
    input   wire    [6:0]   SG2_snake           ,       
    input   wire    [6:0]   SG3_snake           ,       
    input   wire    [6:0]   SG4_snake           ,       
    input   wire    [6:0]   SG5_snake           ,       
    input   wire    [6:0]   SG6_snake           ,       
    input   wire    [6:0]   SG7_snake           ,       
    
    input   wire            hsync_tetris        ,   //输出行同步信号
    input   wire            vsync_tetris        ,   //输出场同步信号
    input   wire    [7:0]   vga_r_tetris        ,   //输出像素信息  //高八位
    input   wire    [7:0]   vga_g_tetris        ,   //输出像素信息
    input   wire    [7:0]   vga_b_tetris        ,   //输出像素信息  //低八位
    input   wire            vga_clk_dis_tetris  ,   //vga引脚时钟
    input   wire            disp_vld_tetris     ,   //背光开启标志
    input   wire    [6:0]   SG0_tetris          ,       
    input   wire    [6:0]   SG1_tetris          ,       
    input   wire    [6:0]   SG2_tetris          ,       
    input   wire    [6:0]   SG3_tetris          ,       
    input   wire    [6:0]   SG4_tetris          ,       
    input   wire    [6:0]   SG5_tetris          ,       
    input   wire    [6:0]   SG6_tetris          ,       
    input   wire    [6:0]   SG7_tetris          ,  

    input   wire            hsync_gomoku        ,   //输出行同步信号
    input   wire            vsync_gomoku        ,   //输出场同步信号
    input   wire    [7:0]   vga_r_gomoku        ,   //输出像素信息  //高八位
    input   wire    [7:0]   vga_g_gomoku        ,   //输出像素信息
    input   wire    [7:0]   vga_b_gomoku        ,   //输出像素信息  //低八位
    input   wire            vga_clk_dis_gomoku  ,   //vga引脚时钟
    input   wire            disp_vld_gomoku     ,   //背光开启标志
 
    input   wire            hsync_setting        ,   //输出行同步信号
    input   wire            vsync_setting        ,   //输出场同步信号
    input   wire    [7:0]   vga_r_setting        ,   //输出像素信息  //高八位
    input   wire    [7:0]   vga_g_setting        ,   //输出像素信息
    input   wire    [7:0]   vga_b_setting        ,   //输出像素信息  //低八位
    input   wire            vga_clk_dis_setting  ,   //vga引脚时钟
    input   wire            disp_vld_setting     ,   //背光开启标志

	output  reg     [2:0]   game_machine_status ,//当前游戏机状态
    output  wire             hsync               ,   //输出行同步信号
    output  wire             vsync               ,   //输出场同步信号
    output  reg     [7:0]   vga_r               ,   //输出像素信息  //高八位
    output  reg     [7:0]   vga_g               ,   //输出像素信息
    output  reg     [7:0]   vga_b               ,   //输出像素信息  //低八位
    output  wire             vga_clk_dis         ,   //vga引脚时钟
    output  wire             disp_vld            ,   //背光开启标志
    output  reg     [6:0]   SG0,SG1,SG2,SG3,SG4,SG5,SG6,SG7

);

//游戏机状态
localparam GAMESEL  = 3'b000;		//游戏选择
localparam SNAKE    = 3'b001;	    //贪吃蛇
localparam TETRIS   = 3'b010;		//俄罗斯方块
localparam GOMOKU   = 3'b011;		//五子棋
localparam SETTING  = 3'b100;		//设置


assign  hsync = (game_machine_status == GAMESEL) ? hsync_menu : ((game_machine_status == SNAKE) ? hsync_snake: ((game_machine_status == TETRIS) ? hsync_tetris :((game_machine_status == GOMOKU) ? hsync_gomoku: ((game_machine_status == SETTING)?hsync_setting:1'd0)) ) ) ;
assign  vsync = (game_machine_status == GAMESEL) ? vsync_menu : ((game_machine_status == SNAKE) ? vsync_snake: ((game_machine_status == TETRIS) ? vsync_tetris :((game_machine_status == GOMOKU) ?vsync_gomoku: ((game_machine_status == SETTING)?vsync_setting:1'd0)) ) ) ;
assign vga_clk_dis = (game_machine_status == GAMESEL) ? vga_clk_dis_menu : ((game_machine_status == SNAKE) ? vga_clk_dis_snake: ((game_machine_status == TETRIS) ? vga_clk_dis_tetris :((game_machine_status == GOMOKU) ?vga_clk_dis_gomoku: ((game_machine_status == SETTING)?vga_clk_dis_setting:1'd0)) ) ) ;
assign  disp_vld = (game_machine_status == GAMESEL) ? disp_vld_menu : ((game_machine_status == SNAKE) ? disp_vld_snake: ((game_machine_status == TETRIS) ? disp_vld_tetris :((game_machine_status == GOMOKU) ?disp_vld_gomoku: ((game_machine_status == SETTING)?disp_vld_setting:1'd0)) ) ) ;


always@(posedge vga_clk or negedge sys_rst_n)
    if(!sys_rst_n) begin
        game_machine_status <= GAMESEL;  //开始界面
        vga_r      <=   8'b0      ;
        vga_g      <=   8'b0      ;
        vga_b      <=   8'b0      ;
        SG0        <=   7'b1111111;
        SG1        <=   7'b1111111;
        SG2        <=   7'b1111111;
        SG4        <=   7'b1111111;
        SG5        <=   7'b1111111;
        SG6        <=   7'b1111111;
        SG7        <=   7'b1111111;
        SG3        <=   7'b1111111;               
    end
    else begin
        case(game_machine_status)
            GAMESEL:begin           //游戏选择界面
                vga_r      <=   vga_r_menu      ;
                vga_g      <=   vga_g_menu      ;
                vga_b      <=   vga_b_menu      ;
                SG0        <=   7'b1110111;
                SG1        <=   7'b1111111;
                SG2        <=   7'b1111111;
                SG4        <=   7'b1111111;
                SG5        <=   7'b1111111;
                SG6        <=   7'b1111111;
                SG7        <=   7'b1111111;
                SG3        <=   7'b1111111;   
                case(game_ch)
                    3'd0:  game_machine_status <= GAMESEL;
                    3'd1:  game_machine_status <= SNAKE;
                    3'd2:  game_machine_status <= TETRIS;
                    3'd3:  game_machine_status <= GOMOKU;
                    3'd4:  game_machine_status <= SETTING;
                endcase                    
            end      
            SNAKE:begin           //贪吃蛇游戏
                vga_r      <=   vga_r_snake      ;
                vga_g      <=   vga_g_snake      ;
                vga_b      <=   vga_b_snake      ;
                SG0        <=   SG0_snake        ;
                SG1        <=   SG1_snake        ;
                SG2        <=   SG2_snake        ;
                SG3        <=   SG3_snake        ;
                SG4        <=   SG4_snake        ;
                SG5        <=   SG5_snake        ;
                SG6        <=   SG6_snake        ;
                SG7        <=   SG7_snake        ;
                if(snake_game_return)
                    game_machine_status <= GAMESEL;
            end
            TETRIS:begin           //俄罗斯方块
                vga_r      <=   vga_r_tetris      ;
                vga_g      <=   vga_g_tetris      ;
                vga_b      <=   vga_b_tetris      ;
                SG0        <=   SG0_tetris        ;
                SG1        <=   SG1_tetris        ;
                SG2        <=   SG2_tetris        ;
                SG3        <=   SG3_tetris        ;
                SG4        <=   SG4_tetris        ;
                SG5        <=   SG5_tetris        ;
                SG6        <=   SG6_tetris        ;
                SG7        <=   SG7_tetris        ;
                if(tetris_game_return)
                    game_machine_status <= GAMESEL;
            end
            GOMOKU:begin           //五子棋
                vga_r      <=   vga_r_gomoku      ;
                vga_g      <=   vga_g_gomoku      ;
                vga_b      <=   vga_b_gomoku      ;
                SG0        <=   7'b1111111;
                SG1        <=   7'b1111111;
                SG2        <=   7'b1111111;
                SG4        <=   7'b1111111;
                SG5        <=   7'b1111111;
                SG6        <=   7'b1111111;
                SG7        <=   7'b1111111;
                SG3        <=   7'b1111111;  
                if(gomoku_game_return)
                    game_machine_status <= GAMESEL;
            end
            SETTING:begin           //设置
                vga_r      <=   vga_r_setting      ;
                vga_g      <=   vga_g_setting      ;
                vga_b      <=   vga_b_setting      ;
                SG0        <=   7'b1111111;
                SG1        <=   7'b1111111;
                SG2        <=   7'b1111111;
                SG4        <=   7'b1111111;
                SG5        <=   7'b1111111;
                SG6        <=   7'b1111111;
                SG7        <=   7'b1111111;
                SG3        <=   7'b1111111;  
                if(setting_game_return)
                    game_machine_status <= GAMESEL;
            end            
        endcase
    end
endmodule

5.3 贪吃蛇游戏模块部分代码

    else if((v == snake_speed/diff)&&(pix_x == H_VALID -1'd1)&&(pix_y == V_VALID - 1'd1)) begin //经过一个游戏时间
            
            cube_x[1] <= cube_x[0];
            cube_y[1] <= cube_y[0];
                                        
            cube_x[2] <= cube_x[1];
            cube_y[2] <= cube_y[1];
                                        
            cube_x[3] <= cube_x[2];
            cube_y[3] <= cube_y[2];
                                        
            cube_x[4] <= cube_x[3];
            cube_y[4] <= cube_y[3];
                                        
            cube_x[5] <= cube_x[4];
            cube_y[5] <= cube_y[4];
                                        
            cube_x[6] <= cube_x[5];
            cube_y[6] <= cube_y[5];
                                        
            cube_x[7] <= cube_x[6];
            cube_y[7] <= cube_y[6];
                                        
            cube_x[8] <= cube_x[7];
            cube_y[8] <= cube_y[7];
                                        
            cube_x[9] <= cube_x[8];
            cube_y[9] <= cube_y[8];
                                        
            cube_x[10] <= cube_x[9];
            cube_y[10] <= cube_y[9];
                                        
            cube_x[11] <= cube_x[10];
            cube_y[11] <= cube_y[10];
                                        
            cube_x[12] <= cube_x[11];
            cube_y[12] <= cube_y[11];
                                         
            cube_x[13] <= cube_x[12];
            cube_y[13] <= cube_y[12];
                                        
            cube_x[14] <= cube_x[13];
            cube_y[14] <= cube_y[13];
                                        
            cube_x[15] <= cube_x[14];
            cube_y[15] <= cube_y[14];
            
            //根据按下按键判断是否到边缘 按规律改变头部坐标
            if(direct_r==UP)begin           //到最上边
                if(cube_y[0] == 0)
                    cube_y[0] <= 460;
                else
                    cube_y[0] <= cube_y[0] - PIC_H;
                end											
            else if(direct_r==DOWN)begin    //到最下边
                if(cube_y[0] == 460)
                    cube_y[0] <= 0;
                else
                    cube_y[0] <= cube_y[0] + PIC_H;
                end												
            else if(direct_r==LEFT)begin    //到最左边
                if(cube_x[0] == 0)
                    cube_x[0] <= 620;
                else
                    cube_x[0] <= cube_x[0] - PIC_W;											
                end
            else if(direct_r==RIGHT)begin   //到最右边
                if(cube_x[0] == 620)
                    cube_x[0] <= 0;
                else
                    cube_x[0] <= cube_x[0] + PIC_W;
                end

5.4 俄罗斯方块游戏模块部分代码

case(state)         
            S_idle     : begin //空状态,即屏幕显示为空白
                        if(game_over == 1'd0)
                            state <= S_new;
                end
            S_new     :    begin //用于产生新的俄罗斯方块。
                        Actblock_x <= FIXPOINT_X;  Actblock_y <= FIXPOINT_Y;
                        Block_next <= Block;
                        Block_now <= Block_next;  //方块类型
                        Block_spin <= 0; //旋转类型
                        state <= S_hold;
                end
            S_hold    :begin //保持状态。在这个状态中进行计时,当时间到达一定间隔时,转到下落状态(S_down);或者等待输入信号,转到下落状态(S_down)/(up,left,right)状态。                        
                        if(up_flag) begin
                            Block_spin <= Block_spin + 1'd1;
                            if(Block_spin == 2'd3)
                                Block_spin <= 2'd1;
                        end
                        Background[1][10-2+1] 第1行第1列   Background[1][10-2] 第1行第2列   Background[1][10-2-1] 第1行第3列
                        if(left_flag) begin      //往左移一格                     
                            case(Block_now)
                                0:  begin                              
                                    if(((Background[fixpoint_h][10-fixpoint_l+1]==0)&&(Background[fixpoint_h+1][10-fixpoint_l+1]==0))&&(Actblock_x >= 10'd240))
                                        Actblock_x <= Actblock_x - 20;
                                end
                                1:  begin
                                    if((Background[fixpoint_h][10-fixpoint_l+1]==0)&&(Actblock_x >= 10'd240))
                                        Actblock_x <= Actblock_x - 20;
                                end
                                2:  begin
                                    case(Block_spin)
                                        0,2:  begin
                                            if(((Background[fixpoint_h-1][10-fixpoint_l+1]==0)&&(Background[fixpoint_h][10-fixpoint_l+1]==0)&&
                                               (Background[fixpoint_h+1][10-fixpoint_l+1]==0)&&(Background[fixpoint_h+2][10-fixpoint_l+1]==0))&&(Actblock_x >= 10'd240))
                                                Actblock_x <= Actblock_x - 20;
                                        end
                                        1,3:  begin
                                            if((Background[fixpoint_h][10-fixpoint_l+2]==0)&&(Actblock_x >= 10'd260))
                                                Actblock_x <= Actblock_x - 20;
                                        end
                                    endcase                                
                                end
                                3:  begin
                                    case(Block_spin)
                                        0:  begin
                                            if(((Background[fixpoint_h-1][10-fixpoint_l+1]==0)&&(Background[fixpoint_h][10-fixpoint_l+1]==0)&&
                                               (Background[fixpoint_h+1][10-fixpoint_l+1]==0))&&(Actblock_x >= 10'd240))
                                                Actblock_x <= Actblock_x - 20;
                                        end
                                        1:  begin
                                            if(((Background[fixpoint_h][10-fixpoint_l+1]==0)&&(Background[fixpoint_h+1][10-fixpoint_l+1]==0))&&(Actblock_x >= 10'd260))
                                                Actblock_x <= Actblock_x - 20;
                                        end
                                        2:  begin
                                            if(((Background[fixpoint_h-1][10-fixpoint_l+2]==0)&&(Background[fixpoint_h][10-fixpoint_l+1]==0)&&
                                               (Background[fixpoint_h+1][10-fixpoint_l+1]==0))&&(Actblock_x >= 10'd260))
                                                Actblock_x <= Actblock_x - 20;
                                        end
                                        3:  begin
                                            if(((Background[fixpoint_h-1][10-fixpoint_l]==0)&&(Background[fixpoint_h][10-fixpoint_l+2]==0))&&(Actblock_x >= 10'd260))
                                                Actblock_x <= Actblock_x - 20;
                                        end                                        
                                    endcase  
                                end
                                4:  begin
                                    case(Block_spin)
                                        0:  begin
                                            if(((Background[fixpoint_h-1][10-fixpoint_l+1]==0)&&(Background[fixpoint_h][10-fixpoint_l+1]==0)&&
                                               (Background[fixpoint_h+1][10-fixpoint_l+2]==0))&&(Actblock_x >= 10'd260))
                                                Actblock_x <= Actblock_x - 20;
                                        end
                                        1:  begin
                                            if(((Background[fixpoint_h-1][10-fixpoint_l+2]==0)&&(Background[fixpoint_h][10-fixpoint_l+2]==0))&&(Actblock_x >= 10'd260))
                                                Actblock_x <= Actblock_x - 20;
                                        end
                                        2:  begin
                                            if(((Background[fixpoint_h-1][10-fixpoint_l+1]==0)&&(Background[fixpoint_h][10-fixpoint_l+1]==0)&&
                                               (Background[fixpoint_h+1][10-fixpoint_l+1]==0))&&(Actblock_x >= 10'd240))
                                                Actblock_x <= Actblock_x - 20;
                                        end
                                        3:  begin
                                            if(((Background[fixpoint_h][10-fixpoint_l+2]==0)&&(Background[fixpoint_h+2][10-fixpoint_l]==0))&&(Actblock_x >= 10'd260))
                                                Actblock_x <= Actblock_x - 20;
                                        end                                        
                                    endcase                              
                                end
                                5:  begin
                                    case(Block_spin)
                                        0:  begin
                                            if(((Background[fixpoint_h-1][10-fixpoint_l+1]==0)&&(Background[fixpoint_h][10-fixpoint_l+2]==0))&&(Actblock_x >= 10'd260))
                                                Actblock_x <= Actblock_x - 20;
                                        end
                                        1:  begin
                                            if(((Background[fixpoint_h-1][10-fixpoint_l+1]==0)&&(Background[fixpoint_h][10-fixpoint_l+1]==0)&&
                                               (Background[fixpoint_h+1][10-fixpoint_l+1]==0))&&(Actblock_x >= 10'd240))
                                                Actblock_x <= Actblock_x - 20;
                                        end
                                        2:  begin
                                            if(((Background[fixpoint_h][10-fixpoint_l+2]==0)&&(Background[fixpoint_h+1][10-fixpoint_l+1]==0))&&(Actblock_x >= 10'd260))
                                                Actblock_x <= Actblock_x - 20;
                                        end
                                        3:  begin
                                            if(((Background[fixpoint_h-1][10-fixpoint_l+1]==0)&&(Background[fixpoint_h][10-fixpoint_l+2]==0)&&
                                               (Background[fixpoint_h+1][10-fixpoint_l+1]==0))&&(Actblock_x >= 10'd240))
                                                Actblock_x <= Actblock_x - 20;
                                        end                                        
                                    endcase                              
                                end
                                6:  begin
                                    case(Block_spin)
                                        0,2:  begin
                                            if(((Background[fixpoint_h-1][10-fixpoint_l+1]==0)&&(Background[fixpoint_h][10-fixpoint_l+2]==0)&&
                                               (Background[fixpoint_h+1][10-fixpoint_l+2]==0))&&(Actblock_x >= 10'd260))
                                                Actblock_x <= Actblock_x - 20;
                                        end
                                        1,3:  begin
                                            if(((Background[fixpoint_h-1][10-fixpoint_l+2]==0)&&(Background[fixpoint_h][10-fixpoint_l+1]==0))&&(Actblock_x >= 10'd260))
                                                Actblock_x <= Actblock_x - 20;
                                        end
                                    endcase   
                                end
                                7:  begin
                                    case(Block_spin)
                                        0,2:  begin
                                            if(((Background[fixpoint_h-1][10-fixpoint_l+2]==0)&&(Background[fixpoint_h][10-fixpoint_l+2]==0)&&
                                               (Background[fixpoint_h+1][10-fixpoint_l+1]==0))&&(Actblock_x >= 10'd260))
                                                Actblock_x <= Actblock_x - 20;
                                        end
                                        1,3:  begin
                                            if(((Background[fixpoint_h-1][10-fixpoint_l+1]==0)&&(Background[fixpoint_h][10-fixpoint_l+2]==0))&&(Actblock_x >= 10'd260))
                                                Actblock_x <= Actblock_x - 20;
                                        end
                                    endcase                                  
                                end                            
                            endcase  end
                                                                      
                        if(right_flag)begin      //往右移一格                      
                            case(Block_now)
                                0:  begin                              
                                    if(((Background[fixpoint_h][10-fixpoint_l-2]==0)&&(Background[fixpoint_h+1][10-fixpoint_l+1]==0))&&(Actblock_x <= 10'd380))
                                        Actblock_x <= Actblock_x + 20;
                                end
                                1:  begin
                                    if(((Background[fixpoint_h][10-fixpoint_l-1]==0))&&(Actblock_x <= 10'd400))
                                        Actblock_x <= Actblock_x + 20;
                                end
                                2:  begin
                                    case(Block_spin)
                                        0,2:  begin
                                            if(((Background[fixpoint_h-1][10-fixpoint_l-1]==0)&&(Background[fixpoint_h][10-fixpoint_l-1]==0)&&
                                               (Background[fixpoint_h+1][10-fixpoint_l-1]==0)&&(Background[fixpoint_h+2][10-fixpoint_l-1]==0))&&(Actblock_x <= 10'd380))
                                                Actblock_x <= Actblock_x + 20;
                                        end
                                        1,3:  begin
                                            if(((Background[fixpoint_h][10-fixpoint_l-3]==0))&&(Actblock_x <= 10'd340))
                                                Actblock_x <= Actblock_x + 20;
                                        end
                                    endcase                                
                                end
                                3:  begin
                                    case(Block_spin)
                                        0:  begin
                                            if(((Background[fixpoint_h-1][10-fixpoint_l-1]==0)&&(Background[fixpoint_h][10-fixpoint_l-1]==0)&&
                                               (Background[fixpoint_h+1][10-fixpoint_l-2]==0))&&(Actblock_x <= 10'd360))
                                                Actblock_x <= Actblock_x + 20;
                                        end
                                        1:  begin
                                            if(((Background[fixpoint_h][10-fixpoint_l-2]==0)&&(Background[fixpoint_h+1][10-fixpoint_l]==0))&&(Actblock_x <= 10'd360))
                                                Actblock_x <= Actblock_x + 20;
                                        end
                                        2:  begin
                                            if(((Background[fixpoint_h-1][10-fixpoint_l-1]==0)&&(Background[fixpoint_h][10-fixpoint_l-1]==0)&&
                                               (Background[fixpoint_h+1][10-fixpoint_l-1]==0))&&(Actblock_x <= 10'd380))
                                                Actblock_x <= Actblock_x + 20;
                                        end
                                        3:  begin
                                            if(((Background[fixpoint_h-1][10-fixpoint_l-2]==0)&&(Background[fixpoint_h][10-fixpoint_l-2]==0))&&(Actblock_x <= 10'd360))
                                                Actblock_x <= Actblock_x + 20;
                                        end                                 
                                    endcase  
                                end
                                4:  begin
                                    case(Block_spin)
                                        0:  begin
                                            if(((Background[fixpoint_h-1][10-fixpoint_l-1]==0)&&(Background[fixpoint_h][10-fixpoint_l-1]==0)&&
                                               (Background[fixpoint_h+1][10-fixpoint_l-1]==0))&&(Actblock_x <= 10'd380))
                                                Actblock_x <= Actblock_x + 20;
                                        end
                                        1:  begin
                                            if(((Background[fixpoint_h-1][10-fixpoint_l]==0)&&(Background[fixpoint_h][10-fixpoint_l-2]==0))&&(Actblock_x <= 10'd360))
                                                Actblock_x <= Actblock_x + 20;
                                        end
                                        2:  begin
                                            if(((Background[fixpoint_h-1][10-fixpoint_l-2]==0)&&(Background[fixpoint_h][10-fixpoint_l-1]==0)&&
                                               (Background[fixpoint_h+1][10-fixpoint_l-1]==0))&&(Actblock_x <= 10'd360))
                                                Actblock_x <= Actblock_x + 20;
                                        end
                                        3:  begin
                                            if(((Background[fixpoint_h][10-fixpoint_l-2]==0)&&(Background[fixpoint_h+1][10-fixpoint_l-2]==0))&&(Actblock_x <= 10'd360))
                                                Actblock_x <= Actblock_x + 20;
                                        end                                 
                                    endcase                           
                                end
                                5:  begin
                                    case(Block_spin)
                                        0:  begin
                                            if(((Background[fixpoint_h-1][10-fixpoint_l-1]==0)&&(Background[fixpoint_h][10-fixpoint_l-2]==0))&&(Actblock_x <= 10'd360))
                                                Actblock_x <= Actblock_x + 20;
                                        end
                                        1:  begin
                                            if(((Background[fixpoint_h-1][10-fixpoint_l-1]==0)&&(Background[fixpoint_h][10-fixpoint_l-2]==0)&&
                                               (Background[fixpoint_h+1][10-fixpoint_l-1]==0))&&(Actblock_x <= 10'd360))
                                                Actblock_x <= Actblock_x + 20;
                                        end
                                        2:  begin
                                            if(((Background[fixpoint_h][10-fixpoint_l-2]==0)&&(Background[fixpoint_h+1][10-fixpoint_l-1]==0))&&(Actblock_x <= 10'd360))
                                                Actblock_x <= Actblock_x + 20;
                                        end
                                        3:  begin
                                            if(((Background[fixpoint_h-1][10-fixpoint_l-1]==0)&&(Background[fixpoint_h][10-fixpoint_l-1]==0)&&
                                               (Background[fixpoint_h+1][10-fixpoint_l-1]==0))&&(Actblock_x <= 10'd380))
                                                Actblock_x <= Actblock_x + 20;
                                        end
                                    endcase                              
                                end
                                6:  begin
                                    case(Block_spin)
                                        0,2:  begin
                                            if(((Background[fixpoint_h-1][10-fixpoint_l-1]==0)&&(Background[fixpoint_h][10-fixpoint_l-1]==0)&&
                                               (Background[fixpoint_h+1][10-fixpoint_l]==0))&&(Actblock_x <= 10'd380))
                                                Actblock_x <= Actblock_x + 20;
                                        end
                                        1,3:  begin
                                            if(((Background[fixpoint_h-1][10-fixpoint_l-1]==0)&&(Background[fixpoint_h-1][10-fixpoint_l-2]==0))&&(Actblock_x <= 10'd360))
                                                Actblock_x <= Actblock_x + 20;
                                        end  
                                    endcase 
                                end
                                7:  begin
                                    case(Block_spin)
                                        0,2:  begin
                                            if(((Background[fixpoint_h-1][10-fixpoint_l]==0)&&(Background[fixpoint_h][10-fixpoint_l-1]==0)&&
                                               (Background[fixpoint_h+1][10-fixpoint_l-1]==0))&&(Actblock_x <= 10'd380))
                                                Actblock_x <= Actblock_x + 20;
                                        end
                                        1,3:  begin
                                            if(((Background[fixpoint_h-1][10-fixpoint_l-2]==0)&&(Background[fixpoint_h][10-fixpoint_l-1]==0))&&(Actblock_x <= 10'd360))
                                                Actblock_x <= Actblock_x + 20;
                                        end  
                                    endcase  
                                end
                            endcase
                        end                            
                        
                        if(down_flag)
                            state <= S_down;
                        if((v == (tetris_speed>>diff))&&(pix_x == H_VALID -1'd1)&&(pix_y == V_VALID - 1'd1))
                            state <= S_down;        
                end
            
            S_down    :begin //判断当前俄罗斯块能否下移一格。如果可以,则转到更新状态-S_shift,如果不行,则转到更新矩阵状态-S_remove_1。
                        //Background[1][10-2+1] 第1行第1列   Background[1][10-2] 第1行第2列   Background[1][10-2-1] 第1行第3列                       
                        case(Block_now)
                            0:  begin                              
                                if((Background[fixpoint_h+2][10-fixpoint_l]==1)||(Background[fixpoint_h+2][10-fixpoint_l-1]==1)||(Actblock_y == 440))
                                    state <= S_remove_1;   
                                else
                                    state <= S_shift;
                            end
                            1:  begin
                                if((Background[fixpoint_h+1][10-fixpoint_l]==1)||(Actblock_y == 460))
                                    state <= S_remove_1;   
                                else
                                    state <= S_shift;
                            end
                            2:  begin
                                case(Block_spin)
                                    0,2:  begin
                                        if((Background[fixpoint_h+3][10-fixpoint_l]==1)||(Actblock_y == 420))
                                            state <= S_remove_1;   
                                        else
                                            state <= S_shift;
                                    end
                                    1,3:  begin
                                        if(Actblock_x == 220)  //旋转后超过左边界,自动归位
                                            Actblock_x <= 240;                                    
                                        if((Actblock_x == 380)||(Actblock_x == 400))  //旋转后超过右边界,自动归位
                                            Actblock_x <= 360;
                                        if((Background[fixpoint_h+1][10-fixpoint_l+1]==1)||(Background[fixpoint_h+1][10-fixpoint_l]==1)||
                                           (Background[fixpoint_h+1][10-fixpoint_l-1]==1)||(Background[fixpoint_h+1][10-fixpoint_l-2]==1)||(Actblock_y == 460))
                                            state <= S_remove_1;   
                                        else
                                            state <= S_shift;
                                    end
                                endcase                                
                            end
                            3:  begin
                                case(Block_spin)
                                    0:  begin
                                        if(Actblock_x == 400)
                                            Actblock_x <= 380;
                                        if((Background[fixpoint_h+2][10-fixpoint_l]==1)||(Background[fixpoint_h+2][10-fixpoint_l-1]==1)||(Actblock_y == 440))
                                            state <= S_remove_1;   
                                        else
                                            state <= S_shift;
                                    end
                                    1:  begin
                                        if(Actblock_x == 220)
                                            Actblock_x <= 240;                                        
                                        if(Actblock_x == 400)
                                            Actblock_x <= 380;
                                        if((Background[fixpoint_h+2][10-fixpoint_l+1]==1)||(Background[fixpoint_h+1][10-fixpoint_l]==1)||(Background[fixpoint_h+1][10-fixpoint_l-1]==1)||(Actblock_y == 440))
                                            state <= S_remove_1;   
                                        else
                                            state <= S_shift;
                                    end
                                    2:  begin
                                        if(Actblock_x == 220)
                                            Actblock_x <= 240;                                        
                                        if((Background[fixpoint_h][10-fixpoint_l+1]==1)||(Background[fixpoint_h+2][10-fixpoint_l]==1)||(Actblock_y == 440))
                                            state <= S_remove_1;   
                                        else
                                            state <= S_shift;
                                    end
                                    3:  begin
                                        if(Actblock_x == 220)
                                            Actblock_x <= 240;                                        
                                        if(Actblock_x == 400)
                                            Actblock_x <= 380;
                                        if((Background[fixpoint_h+1][10-fixpoint_l+1]==1)||(Background[fixpoint_h+1][10-fixpoint_l]==1)||(Background[fixpoint_h+1][10-fixpoint_l-1]==1)||(Actblock_y == 460))
                                            state <= S_remove_1;   
                                        else
                                            state <= S_shift;
                                    end                                    
                                endcase  
                            end
                            4:  begin
                                case(Block_spin)
                                    0:  begin
                                        if(Actblock_x == 220)
                                            Actblock_x <= 240;                                        
                                        if((Background[fixpoint_h+2][10-fixpoint_l]==1)||(Background[fixpoint_h+2][10-fixpoint_l+1]==1)||(Actblock_y == 440))
                                            state <= S_remove_1;   
                                        else
                                            state <= S_shift;
                                    end
                                    1:  begin
                                        if(Actblock_x == 220)
                                            Actblock_x <= 240;                                        
                                        if(Actblock_x == 400)
                                            Actblock_x <= 380;
                                        if((Background[fixpoint_h+1][10-fixpoint_l+1]==1)||(Background[fixpoint_h+1][10-fixpoint_l]==1)||(Background[fixpoint_h+1][10-fixpoint_l-1]==1)||(Actblock_y == 460))
                                            state <= S_remove_1;   
                                        else
                                            state <= S_shift;
                                    end
                                    2:  begin
                                        if(Actblock_x == 400)
                                            Actblock_x <= 380;                                        
                                        if((Background[fixpoint_h+2][10-fixpoint_l]==1)||(Background[fixpoint_h][10-fixpoint_l-1]==1)||(Actblock_y == 440))
                                            state <= S_remove_1;   
                                        else
                                            state <= S_shift;
                                    end
                                    3:  begin
                                        if(Actblock_x == 220)
                                            Actblock_x <= 240;                                        
                                        if(Actblock_x == 400)
                                            Actblock_x <= 380;                                        
                                        if((Background[fixpoint_h+1][10-fixpoint_l+1]==1)||(Background[fixpoint_h+1][10-fixpoint_l]==1)||(Background[fixpoint_h+2][10-fixpoint_l-1]==1)||(Actblock_y == 440))
                                            state <= S_remove_1;   
                                        else
                                            state <= S_shift;
                                    end                                    
                                endcase                             
                            end
                            5:  begin
                                case(Block_spin)
                                    0:  begin
                                        if(Actblock_x == 220)
                                            Actblock_x <= 240;                                        
                                        if(Actblock_x == 400)
                                            Actblock_x <= 380;                                        
                                        if((Background[fixpoint_h+1][10-fixpoint_l]==1)||(Background[fixpoint_h+1][10-fixpoint_l-1]==1)||(Background[fixpoint_h+1][10-fixpoint_l+1]==1)||(Actblock_y == 460))
                                            state <= S_remove_1;   
                                        else
                                            state <= S_shift;
                                    end
                                    1:  begin
                                        if(Actblock_x == 400)
                                            Actblock_x <= 380;                                        
                                        if((Background[fixpoint_h+2][10-fixpoint_l]==1)||(Background[fixpoint_h+1][10-fixpoint_l-1]==1)||(Actblock_y == 440))
                                            state <= S_remove_1;   
                                        else
                                            state <= S_shift;
                                    end
                                    2:  begin
                                        if(Actblock_x == 220)
                                            Actblock_x <= 240;                                        
                                        if(Actblock_x == 400)
                                            Actblock_x <= 380;                                        
                                        if((Background[fixpoint_h+1][10-fixpoint_l+1]==1)||(Background[fixpoint_h+2][10-fixpoint_l]==1)||(Background[fixpoint_h+1][10-fixpoint_l-1]==1)||(Actblock_y == 440))
                                            state <= S_remove_1;   
                                        else
                                            state <= S_shift;
                                    end
                                    3:  begin
                                        if(Actblock_x == 220)
                                            Actblock_x <= 240;                                        
                                        if((Background[fixpoint_h+1][10-fixpoint_l+1]==1)||(Background[fixpoint_h+2][10-fixpoint_l]==1)||(Actblock_y == 440))
                                            state <= S_remove_1;   
                                        else
                                            state <= S_shift;
                                    end                                    
                                endcase                              
                            end
                            6:  begin
                                case(Block_spin)
                                    0,2:  begin
                                        if((Background[fixpoint_h+2][10-fixpoint_l+1]==1)||(Background[fixpoint_h+1][10-fixpoint_l]==1)||(Actblock_y == 440))
                                            state <= S_remove_1;   
                                        else
                                            state <= S_shift;
                                    end
                                    1,3:  begin
                                        if(Actblock_x == 400)
                                            Actblock_x <= 380;                                        
                                        if((Background[fixpoint_h][10-fixpoint_l+1]==1)||(Background[fixpoint_h+1][10-fixpoint_l]==1)||(Background[fixpoint_h+1][10-fixpoint_l+1]==1)||(Actblock_y == 460))
                                            state <= S_remove_1;   
                                        else
                                            state <= S_shift;
                                    end
                                endcase  

                            end
                            7:  begin
                                case(Block_spin)
                                    0,2:  begin
                                        if((Background[fixpoint_h+1][10-fixpoint_l+1]==1)||(Background[fixpoint_h+2][10-fixpoint_l]==1)||(Actblock_y == 440))
                                            state <= S_remove_1;   
                                        else
                                            state <= S_shift;   
                                    end
                                    1,3:  begin
                                        if(Actblock_x == 400)
                                            Actblock_x <= 380;                                        
                                        if((Background[fixpoint_h+1][10-fixpoint_l+1]==1)||(Background[fixpoint_h+1][10-fixpoint_l]==1)||(Background[fixpoint_h][10-fixpoint_l-1]==1)||(Actblock_y == 460))
                                            state <= S_remove_1;   
                                        else
                                            state <= S_shift;   
                                    end
                                endcase                                  
                            end                            
                        endcase
                end
            
            S_shift   :begin //更新俄罗斯方块的坐标信息。返回保持状态(S_hold)。
                        Actblock_y <= Actblock_y + 20;;
                        state <= S_hold;
                end
            
            S_remove_1:begin //更新整个屏幕的矩阵信息。将活动方块变成不活动方块,转移到消除状态2状态(S_remove_2)。
                        //[9:0]   Background [23:0]   ;    //Background[1] = 10'b0000000000; 第一行       Background总24行10列
                        //Background[fixpoint_h] <= Background[fixpoint_h] | (10'b1000_000_000 >> (fixpoint_l-2));    方块固定点往左一列
                        //Background[fixpoint_h] <= Background[fixpoint_h] | (10'b1000_000_000 >> (fixpoint_l-1));  方块固定点
                        //Background[fixpoint_h] <= Background[fixpoint_h] | (10'b1000_000_000 >> (fixpoint_l));  方块固定点往右一列
                        case (Block_now) 
                                4'd0:   begin  //A1-正方形   x300-5l   y440-23h   300-440    100000  10000
                                    Background[fixpoint_h] <= Background[fixpoint_h] | (10'b1000_000_000 >> (fixpoint_l-1)) | (10'b1000_000_000 >> fixpoint_l) ;//Background[24]= 10'b0_000_110_000
                                    Background[fixpoint_h+1] <= Background[fixpoint_h+1] | (10'b1000_000_000 >> (fixpoint_l-1)) | (10'b1000_000_000 >> fixpoint_l)  ; //Background[23]= 10'b0_000_110_000
                                end
                                4'd1:   begin //B1-一格  作为炸弹  消除周围一圈所有固定方块
                                    //Background[fixpoint_h] <= Background[fixpoint_h] | (10'b1000_000_000 >> (fixpoint_l-1));   
                                    Background[fixpoint_h-1] <= Background[fixpoint_h-1] & (10'b0111_111_111 >> (fixpoint_l-2)) 
                                                  & (10'b0111_111_111 >> (fixpoint_l-1)) & (10'b0111_111_111 >> (fixpoint_l));  
                                    Background[fixpoint_h] <= Background[fixpoint_h] & (10'b0111_111_111 >> (fixpoint_l-2)) 
                                                  & (10'b0111_111_111 >> (fixpoint_l-1)) & (10'b0111_111_111 >> (fixpoint_l));
                                    Background[fixpoint_h+1] <= Background[fixpoint_h+1] & (10'b0111_111_111 >> (fixpoint_l-2)) 
                                                  & (10'b0111_111_111 >> (fixpoint_l-1)) & (10'b0111_111_111 >> (fixpoint_l));                                                  
                                end
                                4'd2:   begin //C1-竖条4格
                                    case(Block_spin)
                                    0,2:  begin
                                        Background[fixpoint_h-1] <= Background[fixpoint_h-1] | (10'b1000_000_000 >> (fixpoint_l-1));
                                        Background[fixpoint_h] <= Background[fixpoint_h] | (10'b1000_000_000 >> (fixpoint_l-1));    
                                        Background[fixpoint_h+1] <= Background[fixpoint_h+1] | (10'b1000_000_000 >> (fixpoint_l-1));    
                                        Background[fixpoint_h+2] <= Background[fixpoint_h+2] | (10'b1000_000_000 >> (fixpoint_l-1));        
                                    end
                                    1,3:  begin
                                        Background[fixpoint_h] <= Background[fixpoint_h] | (10'b1000_000_000 >> (fixpoint_l-2)) | (10'b1000_000_000 >> (fixpoint_l-1))
                                                                                             | (10'b1000_000_000 >> (fixpoint_l))   | (10'b1000_000_000 >> (fixpoint_l+1));          
                                    end
                                    endcase                                                                      
                                end
                                4'd3:   begin  //D1  L形
                                    case(Block_spin)
                                    0:  begin
                                        Background[fixpoint_h-1] <= Background[fixpoint_h-1] | (10'b1000_000_000 >> (fixpoint_l-1));
                                        Background[fixpoint_h] <= Background[fixpoint_h] | (10'b1000_000_000 >> (fixpoint_l-1));    
                                        Background[fixpoint_h+1] <= Background[fixpoint_h+1] | (10'b1000_000_000 >> (fixpoint_l-1)) | (10'b1000_000_000 >> fixpoint_l);     
                                    end
                                    1:  begin
                                        Background[fixpoint_h] <= Background[fixpoint_h] | (10'b1000_000_000 >> (fixpoint_l-2)) | (10'b1000_000_000 >> (fixpoint_l-1)) | (10'b1000_000_000 >> (fixpoint_l));    
                                        Background[fixpoint_h+1] <= Background[fixpoint_h+1] | (10'b1000_000_000 >> (fixpoint_l-2));     
                                    end
                                    2:  begin
                                        Background[fixpoint_h-1] <= Background[fixpoint_h-1] | (10'b1000_000_000 >> (fixpoint_l-2)) | (10'b1000_000_000 >> (fixpoint_l-1));
                                        Background[fixpoint_h] <= Background[fixpoint_h] | (10'b1000_000_000 >> (fixpoint_l-1));    
                                        Background[fixpoint_h+1] <= Background[fixpoint_h+1] | (10'b1000_000_000 >> (fixpoint_l-1));     
                                    end
                                    3:  begin
                                        Background[fixpoint_h-1] <= Background[fixpoint_h-1] | (10'b1000_000_000 >> (fixpoint_l));
                                        Background[fixpoint_h] <= Background[fixpoint_h] | (10'b1000_000_000 >> (fixpoint_l-2)) | (10'b1000_000_000 >> (fixpoint_l-1)) | (10'b1000_000_000 >> (fixpoint_l));        
                                    end                                    
                                    endcase
                                end
                                4'd4:   begin  //E1  反L形
                                    case(Block_spin)
                                    0:  begin
                                        Background[fixpoint_h-1] <= Background[fixpoint_h-1] | (10'b1000_000_000 >> (fixpoint_l-1));
                                        Background[fixpoint_h] <= Background[fixpoint_h] | (10'b1000_000_000 >> (fixpoint_l-1));    
                                        Background[fixpoint_h+1] <= Background[fixpoint_h+1] | (10'b1000_000_000 >> (fixpoint_l-1)) | (10'b1000_000_000 >> fixpoint_l-2);        
                                    end
                                    1:  begin
                                        Background[fixpoint_h-1] <= Background[fixpoint_h-1] | (10'b1000_000_000 >> (fixpoint_l-2));         
                                        Background[fixpoint_h] <= Background[fixpoint_h] | (10'b1000_000_000 >> (fixpoint_l-2)) | (10'b1000_000_000 >> (fixpoint_l-1)) | (10'b1000_000_000 >> (fixpoint_l));                                      
                                    end
                                    2:  begin
                                        Background[fixpoint_h-1] <= Background[fixpoint_h-1] | (10'b1000_000_000 >> (fixpoint_l-1)) | (10'b1000_000_000 >> (fixpoint_l));
                                        Background[fixpoint_h] <= Background[fixpoint_h] | (10'b1000_000_000 >> (fixpoint_l-1));    
                                        Background[fixpoint_h+1] <= Background[fixpoint_h+1] | (10'b1000_000_000 >> (fixpoint_l-1));     
                                    end
                                    3:  begin
                                        Background[fixpoint_h] <= Background[fixpoint_h] | (10'b1000_000_000 >> (fixpoint_l-2)) | (10'b1000_000_000 >> (fixpoint_l-1)) | (10'b1000_000_000 >> (fixpoint_l));        
                                        Background[fixpoint_h+1] <= Background[fixpoint_h+1] | (10'b1000_000_000 >> (fixpoint_l));
                                    end                                    
                                    endcase 
                                end
                                4'd5:   begin  //F1-上三角
                                    case(Block_spin)
                                    0:  begin
                                        Background[fixpoint_h-1] <= Background[fixpoint_h-1] | (10'b1000_000_000 >> (fixpoint_l-1));
                                        Background[fixpoint_h] <= Background[fixpoint_h] | (10'b1000_000_000 >> (fixpoint_l-2)) | (10'b1000_000_000 >> (fixpoint_l-1)) | (10'b1000_000_000 >> fixpoint_l);         
                                    end
                                    1:  begin
                                        Background[fixpoint_h-1] <= Background[fixpoint_h-1] | (10'b1000_000_000 >> (fixpoint_l-1));
                                        Background[fixpoint_h] <= Background[fixpoint_h] | (10'b1000_000_000 >> (fixpoint_l-1)) | (10'b1000_000_000 >> (fixpoint_l));    
                                        Background[fixpoint_h+1] <= Background[fixpoint_h+1] | (10'b1000_000_000 >> (fixpoint_l-1));           
                                    end
                                    2:  begin                                        
                                        Background[fixpoint_h] <= Background[fixpoint_h] | (10'b1000_000_000 >> (fixpoint_l-2)) | (10'b1000_000_000 >> (fixpoint_l-1)) | (10'b1000_000_000 >> fixpoint_l);    
                                        Background[fixpoint_h+1] <= Background[fixpoint_h+1] | (10'b1000_000_000 >> (fixpoint_l-1));
                                    end
                                    3:  begin
                                        Background[fixpoint_h-1] <= Background[fixpoint_h-1] | (10'b1000_000_000 >> (fixpoint_l-1));
                                        Background[fixpoint_h] <= Background[fixpoint_h] | (10'b1000_000_000 >> (fixpoint_l-2)) | (10'b1000_000_000 >> (fixpoint_l-1));    
                                        Background[fixpoint_h+1] <= Background[fixpoint_h+1] | (10'b1000_000_000 >> (fixpoint_l-1));  
                                    end                                    
                                    endcase                                     
                                end
                                4'd6:   begin  //G1-N形
                                    case(Block_spin)
                                    0,2:  begin
                                        Background[fixpoint_h-1] <= Background[fixpoint_h-1] | (10'b1000_000_000 >> (fixpoint_l-1));
                                        Background[fixpoint_h] <= Background[fixpoint_h] | (10'b1000_000_000 >> (fixpoint_l-2)) | (10'b1000_000_000 >> (fixpoint_l-1));    
                                        Background[fixpoint_h+1] <= Background[fixpoint_h+1] | (10'b1000_000_000 >> (fixpoint_l-2) );            
                                    end
                                    1,3:  begin
                                        Background[fixpoint_h-1] <= Background[fixpoint_h-1] | (10'b1000_000_000 >> (fixpoint_l-2)) | (10'b1000_000_000 >> (fixpoint_l-1));
                                        Background[fixpoint_h] <= Background[fixpoint_h] | (10'b1000_000_000 >> (fixpoint_l-1)) | (10'b1000_000_000 >> (fixpoint_l));    
                                    end
                                    endcase  
                                end
                                4'd7:   begin  //H1-反N形
                                    case(Block_spin)
                                    0,2:  begin
                                        Background[fixpoint_h-1] <= Background[fixpoint_h-1] | (10'b1000_000_000 >> (fixpoint_l-2));
                                        Background[fixpoint_h] <= Background[fixpoint_h] | (10'b1000_000_000 >> (fixpoint_l-2)) | (10'b1000_000_000 >> (fixpoint_l-1));    
                                        Background[fixpoint_h+1] <= Background[fixpoint_h+1] | (10'b1000_000_000 >> (fixpoint_l-1) );               
                                    end
                                    1,3:  begin
                                        Background[fixpoint_h-1] <= Background[fixpoint_h-1] | (10'b1000_000_000 >> (fixpoint_l-1)) | (10'b1000_000_000 >> (fixpoint_l));
                                        Background[fixpoint_h] <= Background[fixpoint_h] | (10'b1000_000_000 >> (fixpoint_l-2)) | (10'b1000_000_000 >> (fixpoint_l-1));    
                                    end
                                    endcase  
                                end
                         endcase
                        state <= S_remove_2;
                end
            
            S_remove_2:begin //判断是否可以消除,将可以消除的行消除,并将上面的行下移一行。重复此过程,直到没有可消除的行为止。跳转判定状态(S_isdie)
                        S_remove_2_h <= S_remove_2_h + 1'd1;
                        if(S_remove_2_h == 5'd25) begin
                            S_remove_2_h <= 5'd1;
                            state <= S_isdie;
                        end   
                        else if(Background[S_remove_2_h] == 10'b1_111_111_111) begin
                            for(i=0;i<S_remove_2_h;i=i+1) begin
                                Background[S_remove_2_h-i] <= Background[S_remove_2_h-i-1];
                            end
                            score <= score + 1;
                            state <= S_remove_2;
                        end 
                end
            S_isdie   :begin //判断是否游戏结束。如果结束,则跳转到停止状态(S_stop)。如果没有,则跳转到产生俄罗斯方块状态,生成新的俄罗斯方块。
                        if(Background[2][9-5] == 1)
                            state <= S_stop;
                        else    
                            state <= S_new;
                end
            S_stop    : begin //清楚整个屏幕,并跳转到判断状态(S_isdie)。
                        game_over <= 1'd1;
                end
        endcase

5.5 五子棋游戏模块部分代码

case(state)
            S_idle       : begin  //空状态,即屏幕显示为空白
                if((balck_win == 0)||(white_win == 0))
                    state <= S_balck_down;               
            end
            S_balck_down : begin   //黑棋落子
                if(up_flag)begin
                    if(spot_y == UP_BORDER)  //到达上边界.再按到下边界
                        spot_y <= DOWN_BORDER;
                    else
                        spot_y <= spot_y - INTERVAL;  //往上走一格                  
                end                 
                if(down_flag)begin
                    if(spot_y == DOWN_BORDER)  //到达下边界.再按到上边界
                        spot_y <= UP_BORDER;
                    else
                        spot_y <= spot_y + INTERVAL;  //往下走一格                  
                end
                if(left_flag)begin
                    if(spot_x == LEFT_BORDER)  //到达左边界.再按到右边界
                        spot_x <= RIGHT_BORDER;
                    else
                        spot_x <= spot_x - INTERVAL;  //往左走一格                 
                end
                if(right_flag)begin
                    if(spot_x == RIGHT_BORDER)  //到达右边界.再按到左边界
                        spot_x <= LEFT_BORDER;
                    else
                        spot_x <= spot_x + INTERVAL;  //往右走一格 
                end                            //第一行    第一列
                if(confirm_flag)begin //balck_chess[1] = 10'b000_000_000;   balck_chess[0]不算   balck_chess[x][0] 也不算   balck_chess[1][1] 第一行第一列
                    //SHIFTING    =    10'b0_000_000_010 , //用于移位1存储落子地址  初始第一列
                    if((balck_chess[spot_h][spot_l] == 0) || (white_chess[spot_h][spot_l] == 0))  begin//只有当落子地方没有棋子时才能落子
                        balck_chess[spot_h] <= balck_chess[spot_h] | (SHIFTING << (spot_l-1)) ;
                        state <= S_balck_judge ;
                     end
                    else
                        state <= S_balck_down ;
                end
             end
            S_balck_judge: begin   //黑子判断
                spot_x <= START_X;  //置位初始落子点
                spot_y <= START_Y;
                for(i=1;i<=LINE;i=i+1) begin  //横线
                    if((balck_chess[i][5:1] == FIVE_LINE)||(balck_chess[i][6:2] == FIVE_LINE)||
                       (balck_chess[i][7:3] == FIVE_LINE)||(balck_chess[i][8:4] == FIVE_LINE)||(balck_chess[i][9:5] == FIVE_LINE))
                        balck_win <= 1'd1;
                end
                for(j=1;j<=COLUMN;j=j+1)begin  //竖线
                    if((balck_chess[5][j]&&balck_chess[4][j]&&balck_chess[3][j]&&balck_chess[2][j]&&balck_chess[1][j])||
                    (balck_chess[6][j]&&balck_chess[5][j]&&balck_chess[4][j]&&balck_chess[3][j]&&balck_chess[2][j])||
                    (balck_chess[7][j]&&balck_chess[6][j]&&balck_chess[5][j]&&balck_chess[4][j]&&balck_chess[3][j])||
                    (balck_chess[8][j]&&balck_chess[7][j]&&balck_chess[6][j]&&balck_chess[5][j]&&balck_chess[4][j])||
                    (balck_chess[9][j]&&balck_chess[8][j]&&balck_chess[7][j]&&balck_chess[6][j]&&balck_chess[5][j]))
                        balck_win <= 1'd1;
                end 
                if((balck_chess[5][1]&&balck_chess[6][2]&&balck_chess[7][3]&&balck_chess[8][4]&&balck_chess[9][5])||  //左斜线
                   (balck_chess[4][1]&&balck_chess[5][2]&&balck_chess[6][3]&&balck_chess[7][4]&&balck_chess[8][5])||(balck_chess[5][2]&&balck_chess[6][3]&&balck_chess[7][4]&&balck_chess[8][5]&&balck_chess[9][6])||
                   (balck_chess[3][1]&&balck_chess[4][2]&&balck_chess[5][3]&&balck_chess[6][4]&&balck_chess[7][5])||(balck_chess[4][2]&&balck_chess[5][3]&&balck_chess[6][4]&&balck_chess[7][5]&&balck_chess[8][6])||(balck_chess[5][3]&&balck_chess[6][4]&&balck_chess[7][5]&&balck_chess[8][6]&&balck_chess[9][7])||
                   (balck_chess[2][1]&&balck_chess[3][2]&&balck_chess[4][3]&&balck_chess[5][4]&&balck_chess[6][5])||(balck_chess[3][2]&&balck_chess[4][3]&&balck_chess[5][4]&&balck_chess[6][5]&&balck_chess[7][6])||(balck_chess[4][3]&&balck_chess[5][4]&&balck_chess[6][5]&&balck_chess[7][6]&&balck_chess[8][7])||(balck_chess[5][4]&&balck_chess[6][5]&&balck_chess[7][6]&&balck_chess[8][7]&&balck_chess[9][8])||                   
                   (balck_chess[1][1]&&balck_chess[2][2]&&balck_chess[3][3]&&balck_chess[4][4]&&balck_chess[5][5])||(balck_chess[2][2]&&balck_chess[3][3]&&balck_chess[4][4]&&balck_chess[5][5]&&balck_chess[6][6])||(balck_chess[3][3]&&balck_chess[4][4]&&balck_chess[5][5]&&balck_chess[6][6]&&balck_chess[7][7])||(balck_chess[4][4]&&balck_chess[5][5]&&balck_chess[6][6]&&balck_chess[7][7]&&balck_chess[8][8])||(balck_chess[5][5]&&balck_chess[6][6]&&balck_chess[7][7]&&balck_chess[8][8]&&balck_chess[9][9])||                   
                   (balck_chess[1][2]&&balck_chess[2][3]&&balck_chess[3][4]&&balck_chess[4][5]&&balck_chess[5][6])||(balck_chess[2][3]&&balck_chess[3][4]&&balck_chess[4][5]&&balck_chess[5][6]&&balck_chess[6][7])||(balck_chess[3][4]&&balck_chess[4][5]&&balck_chess[5][6]&&balck_chess[6][7]&&balck_chess[7][8])||(balck_chess[4][5]&&balck_chess[5][6]&&balck_chess[6][7]&&balck_chess[7][8]&&balck_chess[8][9])||                
                   (balck_chess[1][3]&&balck_chess[2][4]&&balck_chess[3][5]&&balck_chess[4][6]&&balck_chess[5][7])||(balck_chess[2][4]&&balck_chess[3][5]&&balck_chess[4][6]&&balck_chess[5][7]&&balck_chess[6][8])||(balck_chess[3][5]&&balck_chess[4][6]&&balck_chess[5][7]&&balck_chess[6][8]&&balck_chess[7][9])||
                   (balck_chess[1][4]&&balck_chess[2][5]&&balck_chess[3][6]&&balck_chess[4][7]&&balck_chess[5][8])||(balck_chess[2][5]&&balck_chess[3][6]&&balck_chess[4][7]&&balck_chess[5][8]&&balck_chess[6][9])||
                   (balck_chess[1][5]&&balck_chess[2][6]&&balck_chess[3][7]&&balck_chess[4][8]&&balck_chess[5][9]))
                        balck_win <= 1'd1;    
                if((balck_chess[5][1]&&balck_chess[4][2]&&balck_chess[3][3]&&balck_chess[2][4]&&balck_chess[1][5])||  //右斜线
                   (balck_chess[6][1]&&balck_chess[5][2]&&balck_chess[4][3]&&balck_chess[3][4]&&balck_chess[2][5])||(balck_chess[5][2]&&balck_chess[4][3]&&balck_chess[3][4]&&balck_chess[2][5]&&balck_chess[1][6])||
                   (balck_chess[7][1]&&balck_chess[6][2]&&balck_chess[5][3]&&balck_chess[4][4]&&balck_chess[3][5])||(balck_chess[6][2]&&balck_chess[5][3]&&balck_chess[4][4]&&balck_chess[3][5]&&balck_chess[2][6])||(balck_chess[5][3]&&balck_chess[4][4]&&balck_chess[3][5]&&balck_chess[2][6]&&balck_chess[1][7])||
                   (balck_chess[8][1]&&balck_chess[7][2]&&balck_chess[6][3]&&balck_chess[5][4]&&balck_chess[4][5])||(balck_chess[7][2]&&balck_chess[6][3]&&balck_chess[5][4]&&balck_chess[4][5]&&balck_chess[3][6])||(balck_chess[6][3]&&balck_chess[5][4]&&balck_chess[4][5]&&balck_chess[3][6]&&balck_chess[2][7])||(balck_chess[5][4]&&balck_chess[4][5]&&balck_chess[3][6]&&balck_chess[2][7]&&balck_chess[1][8])||                  
                   (balck_chess[9][1]&&balck_chess[8][2]&&balck_chess[7][3]&&balck_chess[6][4]&&balck_chess[5][5])||(balck_chess[8][2]&&balck_chess[7][3]&&balck_chess[6][4]&&balck_chess[5][5]&&balck_chess[4][6])||(balck_chess[7][3]&&balck_chess[6][4]&&balck_chess[5][5]&&balck_chess[4][6]&&balck_chess[3][7])||(balck_chess[6][4]&&balck_chess[5][5]&&balck_chess[4][6]&&balck_chess[3][7]&&balck_chess[2][8])||(balck_chess[5][5]&&balck_chess[4][6]&&balck_chess[3][7]&&balck_chess[2][8]&&balck_chess[1][9])||                  
                   (balck_chess[9][2]&&balck_chess[8][3]&&balck_chess[7][4]&&balck_chess[6][5]&&balck_chess[5][6])||(balck_chess[8][3]&&balck_chess[7][4]&&balck_chess[6][5]&&balck_chess[5][6]&&balck_chess[4][7])||(balck_chess[7][4]&&balck_chess[6][5]&&balck_chess[5][6]&&balck_chess[4][7]&&balck_chess[3][8])||(balck_chess[6][5]&&balck_chess[5][6]&&balck_chess[4][7]&&balck_chess[3][8]&&balck_chess[2][9])||                
                   (balck_chess[9][3]&&balck_chess[8][4]&&balck_chess[7][5]&&balck_chess[6][6]&&balck_chess[5][7])||(balck_chess[8][4]&&balck_chess[7][5]&&balck_chess[6][6]&&balck_chess[5][7]&&balck_chess[4][8])||(balck_chess[7][5]&&balck_chess[6][6]&&balck_chess[5][7]&&balck_chess[4][8]&&balck_chess[3][9])||
                   (balck_chess[9][4]&&balck_chess[8][5]&&balck_chess[7][6]&&balck_chess[6][7]&&balck_chess[5][8])||(balck_chess[8][5]&&balck_chess[7][6]&&balck_chess[6][7]&&balck_chess[5][8]&&balck_chess[4][9])||
                   (balck_chess[9][5]&&balck_chess[8][6]&&balck_chess[7][7]&&balck_chess[6][8]&&balck_chess[5][9]))
                        balck_win <= 1'd1;     
                state <= S_white_down ;        
           end
            S_white_down : begin   //白子落子
                if(up_flag)begin
                    if(spot_y == UP_BORDER)  //到达上边界.再按到下边界
                        spot_y <= DOWN_BORDER;
                    else
                        spot_y <= spot_y - INTERVAL;  //往上走一格                  
                end                
                if(down_flag)begin
                    if(spot_y == DOWN_BORDER)  //到达下边界.再按到上边界
                        spot_y <= UP_BORDER;
                    else
                        spot_y <= spot_y + INTERVAL;  //往下走一格                  
                end
                if(left_flag)begin
                    if(spot_x == LEFT_BORDER)  //到达左边界.再按到右边界
                        spot_x <= RIGHT_BORDER;
                    else
                        spot_x <= spot_x - INTERVAL;  //往左走一格                 
                end
                if(right_flag)begin
                    if(spot_x == RIGHT_BORDER)  //到达右边界.再按到左边界
                        spot_x <= LEFT_BORDER;
                    else
                        spot_x <= spot_x + INTERVAL;  //往右走一格 
                 end                            //第一行    第一列
                if(confirm_flag)begin //white_chess[1] = 15'b000_000_000_000_000;   balck_chess[0]不算 
                    if((balck_chess[spot_h][spot_l] == 0) || (white_chess[spot_h][spot_l] == 0))  begin//只有当落子地方没有棋子时才能落子
                        white_chess[spot_h] <= white_chess[spot_h] | (SHIFTING << (spot_l-1)) ;
                        state <= S_white_judge ;
                     end
                    else
                        state <= S_white_down ;
                end            
            end 
            S_white_judge: begin   //白子判断
                spot_x <= START_X;  //置位初始落子点
                spot_y <= START_Y;
                for(i=1;i<=LINE;i=i+1)begin  //横线
                    if((white_chess[i][5:1] == FIVE_LINE)||(white_chess[i][6:2] == FIVE_LINE)||
                       (white_chess[i][7:3] == FIVE_LINE)||(white_chess[i][8:4] == FIVE_LINE)||(white_chess[i][9:5] == FIVE_LINE))
                        white_win <= 1'd1;
                end
                for(j=1;j<=COLUMN;j=j+1)begin  //竖线
                    if((white_chess[5][j]&&white_chess[4][j]&&white_chess[3][j]&&white_chess[2][j]&&white_chess[1][j])||
                    (white_chess[6][j]&&white_chess[5][j]&&white_chess[4][j]&&white_chess[3][j]&&white_chess[2][j])||
                    (white_chess[7][j]&&white_chess[6][j]&&white_chess[5][j]&&white_chess[4][j]&&white_chess[3][j])||
                    (white_chess[8][j]&&white_chess[7][j]&&white_chess[6][j]&&white_chess[5][j]&&white_chess[4][j])||
                    (white_chess[9][j]&&white_chess[8][j]&&white_chess[7][j]&&white_chess[6][j]&&white_chess[5][j]))
                        white_win <= 1'd1;
                end 
                if((white_chess[5][1]&&white_chess[6][2]&&white_chess[7][3]&&white_chess[8][4]&&white_chess[9][5])||  //左斜线
                   (white_chess[4][1]&&white_chess[5][2]&&white_chess[6][3]&&white_chess[7][4]&&white_chess[8][5])||(white_chess[5][2]&&white_chess[6][3]&&white_chess[7][4]&&white_chess[8][5]&&white_chess[9][6])||
                   (white_chess[3][1]&&white_chess[4][2]&&white_chess[5][3]&&white_chess[6][4]&&white_chess[7][5])||(white_chess[4][2]&&white_chess[5][3]&&white_chess[6][4]&&white_chess[7][5]&&white_chess[8][6])||(white_chess[5][3]&&white_chess[6][4]&&white_chess[7][5]&&white_chess[8][6]&&white_chess[9][7])||
                   (white_chess[2][1]&&white_chess[3][2]&&white_chess[4][3]&&white_chess[5][4]&&white_chess[6][5])||(white_chess[3][2]&&white_chess[4][3]&&white_chess[5][4]&&white_chess[6][5]&&white_chess[7][6])||(white_chess[4][3]&&white_chess[5][4]&&white_chess[6][5]&&white_chess[7][6]&&white_chess[8][7])||(white_chess[5][4]&&white_chess[6][5]&&white_chess[7][6]&&white_chess[8][7]&&white_chess[9][8])||                   
                   (white_chess[1][1]&&white_chess[2][2]&&white_chess[3][3]&&white_chess[4][4]&&white_chess[5][5])||(white_chess[2][2]&&white_chess[3][3]&&white_chess[4][4]&&white_chess[5][5]&&white_chess[6][6])||(white_chess[3][3]&&white_chess[4][4]&&white_chess[5][5]&&white_chess[6][6]&&white_chess[7][7])||(white_chess[4][4]&&white_chess[5][5]&&white_chess[6][6]&&white_chess[7][7]&&white_chess[8][8])||(white_chess[5][5]&&white_chess[6][6]&&white_chess[7][7]&&white_chess[8][8]&&white_chess[9][9])||                   
                   (white_chess[1][2]&&white_chess[2][3]&&white_chess[3][4]&&white_chess[4][5]&&white_chess[5][6])||(white_chess[2][3]&&white_chess[3][4]&&white_chess[4][5]&&white_chess[5][6]&&white_chess[6][7])||(white_chess[3][4]&&white_chess[4][5]&&white_chess[5][6]&&white_chess[6][7]&&white_chess[7][8])||(white_chess[4][5]&&white_chess[5][6]&&white_chess[6][7]&&white_chess[7][8]&&white_chess[8][9])||                
                   (white_chess[1][3]&&white_chess[2][4]&&white_chess[3][5]&&white_chess[4][6]&&white_chess[5][7])||(white_chess[2][4]&&white_chess[3][5]&&white_chess[4][6]&&white_chess[5][7]&&white_chess[6][8])||(white_chess[3][5]&&white_chess[4][6]&&white_chess[5][7]&&white_chess[6][8]&&white_chess[7][9])||
                   (white_chess[1][4]&&white_chess[2][5]&&white_chess[3][6]&&white_chess[4][7]&&white_chess[5][8])||(white_chess[2][5]&&white_chess[3][6]&&white_chess[4][7]&&white_chess[5][8]&&white_chess[6][9])||
                   (white_chess[1][5]&&white_chess[2][6]&&white_chess[3][7]&&white_chess[4][8]&&white_chess[5][9]))
                        white_win <= 1'd1;    
                if((white_chess[5][1]&&white_chess[4][2]&&white_chess[3][3]&&white_chess[2][4]&&white_chess[1][5])||  //右斜线
                   (white_chess[6][1]&&white_chess[5][2]&&white_chess[4][3]&&white_chess[3][4]&&white_chess[2][5])||(white_chess[5][2]&&white_chess[4][3]&&white_chess[3][4]&&white_chess[2][5]&&white_chess[1][6])||
                   (white_chess[7][1]&&white_chess[6][2]&&white_chess[5][3]&&white_chess[4][4]&&white_chess[3][5])||(white_chess[6][2]&&white_chess[5][3]&&white_chess[4][4]&&white_chess[3][5]&&white_chess[2][6])||(white_chess[5][3]&&white_chess[4][4]&&white_chess[3][5]&&white_chess[2][6]&&white_chess[1][7])||
                   (white_chess[8][1]&&white_chess[7][2]&&white_chess[6][3]&&white_chess[5][4]&&white_chess[4][5])||(white_chess[7][2]&&white_chess[6][3]&&white_chess[5][4]&&white_chess[4][5]&&white_chess[3][6])||(white_chess[6][3]&&white_chess[5][4]&&white_chess[4][5]&&white_chess[3][6]&&white_chess[2][7])||(white_chess[5][4]&&white_chess[4][5]&&white_chess[3][6]&&white_chess[2][7]&&white_chess[1][8])||                  
                   (white_chess[9][1]&&white_chess[8][2]&&white_chess[7][3]&&white_chess[6][4]&&white_chess[5][5])||(white_chess[8][2]&&white_chess[7][3]&&white_chess[6][4]&&white_chess[5][5]&&white_chess[4][6])||(white_chess[7][3]&&white_chess[6][4]&&white_chess[5][5]&&white_chess[4][6]&&white_chess[3][7])||(white_chess[6][4]&&white_chess[5][5]&&white_chess[4][6]&&white_chess[3][7]&&white_chess[2][8])||(white_chess[5][5]&&white_chess[4][6]&&white_chess[3][7]&&white_chess[2][8]&&white_chess[1][9])||                  
                   (white_chess[9][2]&&white_chess[8][3]&&white_chess[7][4]&&white_chess[6][5]&&white_chess[5][6])||(white_chess[8][3]&&white_chess[7][4]&&white_chess[6][5]&&white_chess[5][6]&&white_chess[4][7])||(white_chess[7][4]&&white_chess[6][5]&&white_chess[5][6]&&white_chess[4][7]&&white_chess[3][8])||(white_chess[6][5]&&white_chess[5][6]&&white_chess[4][7]&&white_chess[3][8]&&white_chess[2][9])||                
                   (white_chess[9][3]&&white_chess[8][4]&&white_chess[7][5]&&white_chess[6][6]&&white_chess[5][7])||(white_chess[8][4]&&white_chess[7][5]&&white_chess[6][6]&&white_chess[5][7]&&white_chess[4][8])||(white_chess[7][5]&&white_chess[6][6]&&white_chess[5][7]&&white_chess[4][8]&&white_chess[3][9])||
                   (white_chess[9][4]&&white_chess[8][5]&&white_chess[7][6]&&white_chess[6][7]&&white_chess[5][8])||(white_chess[8][5]&&white_chess[7][6]&&white_chess[6][7]&&white_chess[5][8]&&white_chess[4][9])||
                   (white_chess[9][5]&&white_chess[8][6]&&white_chess[7][7]&&white_chess[6][8]&&white_chess[5][9]))
                        white_win <= 1'd1;  
                state <= S_balck_down ;         
            end     
        endcase
评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值