基于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模块实现游戏分数显示到数码管上。
具体游戏运行状态流程图如图所示。
- S_idle态为初始空状态,即屏幕显示为空白
- S_new态用于产生新的俄罗斯方块。
- S_hold态为保持状态。在这个状态中进行计时,当时间到达一定间隔时,转到下落状态(S_down);或者等待输入信号(up,down,left,right)时,转到下落状态(S_down)或者(up,left,right)状态。
- S_down下降状态判断当前俄罗斯块能否下移一格。如果可以,则转到更新状态S_shift,如果不行,则转到更新矩阵状态S_remove_1。
- S_shift更新状态更新俄罗斯方块的坐标信息,之后返回保持状态(S_hold)。
- S_remove_1更新矩阵状态更新整个屏幕的矩阵信息。转移到消除状态2状态(S_remove_2)。
- S_remove_2消除状态判断是否可以消除,将可以消除的行消除,并将上面的行下移一行。重复此过程,直到没有可消除的行为止。跳转判定状态(S_isdie)
- S_isdie判定状态判断是否游戏结束。如果结束,则跳转到停止状态(S_stop)。如果没有,则跳转到产生俄罗斯方块状态,生成新的俄罗斯方块。
- 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