




已阅读5页,还剩24页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
贪吃蛇游戏设计基于xilinx spartan-3anfpga开发板专业:电子科学与技术学号:姓名: 贪吃蛇游戏设计基于xilinx spartan-3anfpga开发板一、实验要求设计一款贪吃蛇游戏。设计平台为xilinx的spartan3an fpga开发板。通过vga接口控制液晶显示器,在液晶显示器上实现该游戏。具体要求为,在液晶显示器上有一移动的”蛇”,通过开发板上的拨码开关实现“蛇”上下左右移动。并且要求“蛇”只能在显示器一定范围内运动,若碰到坐标区域的边缘或者“蛇”的身体,则游戏结束。同时会在屏幕有效区域随机出现“苹果”,“蛇”每吃到一次苹果则表示一次成功操作,得分加1,并在数码管上显示得分。本实验刚开始的蛇身长度定位3。为了便于书写程序,我们设定蛇的最大长度为16。二、实验原理 (1)vga接口 本开发板提供vga接口。对硬件进行编程,输出标准的vga信号(红、绿、蓝三色信号和行、帧同步信号),通过15针vga接口输出至显示器,可驱动显示器显示图像信号。如下图所示: 在实验中只需使用其中的五个引脚,如上图所示。vga接口信号基本时序图如下图所示:符号含义垂直同步水平同步时间时钟线数时间时钟ts同步脉冲时间16.7ms41680052132us800tdisp显示时间15.36ms38400048025.6us640tpwvsync脉冲宽度64us160023.84us96tfp前沿320us800010640ns16tbp后沿928us23200291.92us48表1 640*480模式下的vga时序图信号fpga管教约束vga_rt13vga_gv13vga_bu13h_syncw13v_syncy13表2 vga引脚配置(2)拨码开关 本游戏通过开发板下方的四个拨码开关来实现上下左右控制。4拨码开关直接接入fpga管脚,用户可自行配置。拨码开关拨到“on”位置时,其状态为“0”,否则状态为“1”;按键连接原理图如下:信号fpga管脚约束sw1_1j4sw1_2h3sw1_3j3sw1_4j2表3 4码开关fpga引脚配置(3)led数码管此开发板提供4个led数码管,可显示数字,直接与fpga相连,其控制方法为扫描式,如图所示,此数码管内部接线为共阴方式,即低电平亮。所以若要控制左边第一个七节灯管输出2的字型,可以先输出“0010010”到cadp,然后输出“0111”到a1a4即可。 信号fpga管教约束led_bit1m2led_bit2m3led_bit3m4led_bit4m5led_can1led_cbn2led_ccn3led_cdn4led_cet1led_cft2led_cgt3led_dpr4表4 7段数码管fpga引脚配置三、实验代码1. 由于本实验涉及的模块较多,我们采用小模块化设计的思想。本设计含有六个子模块,分别是: game_ctrl_unit snake_eating_apple snake key vga_control seg_display顶层模块代码如下:module greedy_snake (input clk,input reset,input left,input right,input up,input down,output h_sync,output v_sync,output 2:0 color_out,output 7:0 seg_out,output 3:0 sel);wire left_key_press,right_key_press, up_key_press, down_key_press;wire 1:0 snake;wire 9:0 x_pos;wire 9:0 y_pos;wire 5:0 apple_x;wire 4:0 apple_y;wire 5:0 head_x;wire 5:0 head_y;wire add_cube;wire 1:0 game_status;wire hit_wall;wire hit_body;wire die_flash;wire restart;wire 6:0 cube_num;game_ctrl_unit game_ctrl_unit1( .clk(clk),.reset(reset),.key1_press(left_key_press),.key2_press(right_key_press),.key3_press(up_key_press),.key4_press(down_key_press),.game_status(game_status),.hit_wall(hit_wall),.hit_body(hit_body),.die_flash(die_flash),.restart(restart) ); snake_eating_apple snake_eating_apple1( .clk(clk),.reset(reset),.apple_x(apple_x),.apple_y(apple_y),.head_x(head_x),.head_y(head_y),.add_cube(add_cube) );snake snake(.clk(clk),reset(reset),.left_press(left_key_press),.right_press(right_key_press),.up_press(up_key_press),.down_press(down_key_press),.snake(snake),.x_pos(x_pos),.y_pos(y_pos),.head_x(head_x),.head_y(head_y),.add_cube(add_cube),.game_status(game_status),.cube_num(cube_num),.hit_body(hit_body),.hit_wall(hit_wall),.die_flash(die_flash) );vga_control vga_control(.clk(clk),.reset(reset),.h_sync(h_sync), .v_sync(v_sync), .snake(snake),.color_out(color_out),.x_pos(x_pos), .y_pos(y_pos),.apple_x(apple_x),.apple_y(apple_y) );key key1( .clk(clk),.reset(reset),.left(left),.right(right),.up(up),.down(down),.left_key_press(left_key_press), .right_key_press(right_key_press),.up_key_press(up_key_press),.down_key_press(down_key_press) ); seg_display seg_display1( .clk(clk),.reset(reset),.add_cube(add_cube),.seg_out(seg_out),.sel(sel) );endmodule2.每个子模块的实现方法及要求 2.1 game_ctrl_unit本模块从其他模块接受信号,决定游戏状态(ready、play、die),并且产生其他模块的控制信号。在ready的状态下,只要有键按下(上下左右),则蛇就会自动向右运动,从而进入play的状态。在play状态下,本模块等待hit_wall或者hit_body的信号,如果这两个信号发生,则进入die状态,即游戏结束。在die状态下,屏幕会闪烁一段时间,最后进入ready状态。此子模块代码如下:module game_ctrl_unit(input clk,input reset,input key1_press,input key2_press,input key3_press,input key4_press,input hit_wall,input hit_body,output reg 1:0 game_status,output reg die_flash,output reg restart);localparam restart = 2b00;localparam start = 2b01;localparam play = 2b10;localparam die = 2b11;reg 31:0 clk_cnt;always ( posedge clk ) begin if( !reset ) begin game_status = start; clk_cnt = 0; die_flash = 1; restart = 0; endelse begin case( game_status ) restart:begin if( clk_cnt = 5 ) begin clk_cnt = clk_cnt + 1; restart = 1; end else begin game_status = start; clk_cnt = 0; restart = 0; endend start: begin if( key1_press | key2_press | key3_press | key4_press ) begingame_status = play; end end play: begin if( hit_wall | hit_body ) game_status = die;end die: begin if( clk_cnt = 200000000 ) begin clk_cnt = clk_cnt + 1; if( clk_cnt = 25000000 ) die_flash = 0; else if( clk_cnt = 50000000 ) die_flash = 1; else if( clk_cnt = 75000000 )die_flash = 0; else if( clk_cnt = 100000000 )die_flash = 1; else if( clk_cnt = 125000000 )die_flash = 0; else if( clk_cnt = 150000000 )die_flash = 1; end else begin die_flash = 1; clk_cnt = 0; game_status = restart; end end endcaseendendendmodule2.2 snake 这是本次试验最复杂的部分,此模块需要完成四项任务:(1)保持蛇的运动 (2)根据按下的键改变蛇的运动方向 (3)判断蛇是否碰撞墙或者自己的身体 (4)在液晶显示器上显示根据vga_control模块此子模块代码如下:module snake (input clk,input reset,input left_press,input right_press,input up_press,input down_press,input 9:0 x_pos,input 9:0 y_pos,input add_cube,input 1:0 game_status,input die_flash,output reg 1:0 snake,output reg 6:0 cube_num,output 5:0 head_x,output 5:0 head_y,output reg hit_body,output reg hit_wall);localparam up = 2b00;localparam down = 2b01;localparam left = 2b10;localparam right = 2b11;localparam none = 2b00;localparam head = 2b01;localparam body = 2b10;localparam wall = 2b11;localparam play = 2b10;reg 31:0 cnt;wire 1:0 direct; reg 1:0 direct_r;assign direct=direct_r;reg 1:0 direct_next;reg change_to_left;reg change_to_right;reg change_to_up;reg change_to_down; reg 5:0 cube_x15:0;reg 5:0 cube_y15:0;reg 15:0 is_exist;reg 2:0 color;assign head_x = cube_x0;assign head_y = cube_y0;always ( posedge clk ) /初始化刚开始时我们设定蛇向右运动if( !reset)direct_r=right ;elsedirect_r=direct_next;always ( posedge clk )beginif(!reset ) begin /设定初始化后刚开始三个蛇块的位置cnt = 0;cube_x0 = 10;cube_y0 = 5;cube_x1 = 9;cube_y1 = 5;cube_x2 = 8;cube_y2 = 5;hit_wall = 0;hit_body = 0; endelse begincnt = cnt + 1;if( cnt = 12500000 ) begincnt = 0;if( game_status = play ) begin /在play过程中判断是否hit_wallif( ( direct = up & cube_y0 = 1 ) | ( direct = down & cube_y0 = 28 )| ( direct = left & cube_x0 = 1 )| ( direct = right & cube_x0 = 38 ) )hit_wall = 1;/下边判断是否hit_dodyelse if( ( cube_y0 = cube_y1 & cube_x0 = cube_x1 & is_exist1 = 1 )| ( cube_y0 = cube_y2 & cube_x0 = cube_x2 & is_exist2 = 1 )| ( cube_y0 = cube_y3 & cube_x0 = cube_x3 & is_exist3 = 1 )| ( cube_y0 = cube_y4 & cube_x0 = cube_x4 & is_exist4 = 1 )| ( cube_y0 = cube_y5 & cube_x0 = cube_x5 & is_exist5 = 1 )| ( cube_y0 = cube_y6 & cube_x0 = cube_x6 & is_exist6 = 1 )| ( cube_y0 = cube_y7 & cube_x0 = cube_x7 & is_exist7 = 1 )| ( cube_y0 = cube_y8 & cube_x0 = cube_x8 & is_exist8 = 1 )| ( cube_y0 = cube_y9 & cube_x0 = cube_x9 & is_exist9 = 1 )| ( cube_y0 = cube_y10 & cube_x0 = cube_x10 & is_exist10 = 1 )| ( cube_y0 = cube_y11 & cube_x0 = cube_x11 & is_exist11 = 1 )| ( cube_y0 = cube_y12 & cube_x0 = cube_x12 & is_exist12 = 1 )| ( cube_y0 = cube_y13 & cube_x0 = cube_x13 & is_exist13 = 1 )| ( cube_y0 = cube_y14 & cube_x0 = cube_x14 & is_exist14 = 1 )| ( cube_y0 = cube_y15 & cube_x0 = cube_x15 & is_exist15 = 1 ) ) hit_body=1;else /蛇运动过程中相邻模块之间坐标存在联系,依次代替 begincube_x1 = cube_x0;cube_y1 = cube_y0;cube_x2 = cube_x1;cube_y2 = cube_y1;cube_x3 = cube_x2;cube_y3 = cube_y2;cube_x4 = cube_x3;cube_y4 = cube_y3;cube_x5 = cube_x4;cube_y5 = cube_y4;cube_x6 = cube_x5;cube_y6 = cube_y5;cube_x7 = cube_x6;cube_y7 = cube_y6;cube_x8 = cube_x7;cube_y8 = cube_y7;cube_x9 = cube_x8;cube_y9 = cube_y8;cube_x10 = cube_x9;cube_y10 = cube_y9;cube_x11 = cube_x10;cube_y11 = cube_y10;cube_x12 = cube_x11;cube_y12 = cube_y11;cube_x13 = cube_x12;cube_y13 = cube_y12;cube_x14 = cube_x13;cube_y14 = cube_y13;cube_x15 = cube_x14;cube_y15 = cube_y14;case( direct ) /根据运动方向来决定蛇头的坐标up:beginif( cube_y0 = 1 )hit_wall = 1;else cube_y0 = cube_y0 1;enddown: beginif( cube_y0 = 28 )hit_wall = 1;elsecube_y0 = cube_y0 + 1;endleft:beginif( cube_x0 = 1 )hit_wall = 1;else cube_x0 = cube_x0 1;endright: beginif( cube_x0 = 38 )hit_wall = 1;elsecube_x0 = cube_x0 + 1;endendcaseendendendendendalways ( * ) begindirect_next = direct;case( direct )up: beginif( change_to_left )direct_next = left;else if( change_to_right )direct_next = right;else direct_next = up;enddown : beginif( change_to_left )direct_next = left;else if( change_to_right )direct_next = right;else direct_next = down;endleft : beginif( change_to_up )direct_next = up;else if( change_to_down )direct_next = down;else direct_next = left;endright : beginif( change_to_up )direct_next = up;else if( change_to_down )direct_next = down;else direct_next = right;endendcaseendalways ( posedge clk ) beginif( left_press = 1 ) beginchange_to_left = 1;endelse if( right_press = 1 ) beginchange_to_right = 1;endelse if( up_press = 1 ) beginchange_to_up = 1;endelse if( down_press = 1 ) beginchange_to_down = 1;endelse beginchange_to_left = 0;change_to_right = 0;change_to_up = 0;change_to_down = 0;endendreg addcube_state;always ( posedge clk ) beginif( reset = 0 ) beginis_exist = 16b0000000000000111;cube_num = 3;addcube_state = 0;endelse begincase( addcube_state )0: beginif( add_cube ) begincube_num = cube_num + 1;is_existcube_num = 1;addcube_state = 1;endend1: beginif(!add_cube)addcube_state = 0 & x_pos = 0 & y_pos 480 ) beginif( ( x_pos9:4 = 0 | y_pos9:4 = 0 | x_pos9:4 = 39 | y_pos9:4 = 29 ) )snake = wall;else if( x_pos9:4 = cube_x0 & y_pos9:4 = cube_y0 & is_exist0 = 1 ) beginsnake = ( die_flash = 1 ) ? head : none;endelse if( ( x_pos9:4 = cube_x1 & y_pos9:4 = cube_y1 & is_exist1 = 1 )| ( x_pos9:4 = cube_x2 & y_pos9:4 = cube_y2 & is_exist2 = 1 )| ( x_pos9:4 = cube_x3 & y_pos9:4 = cube_y3 & is_exist3 = 1 )| ( x_pos9:4 = cube_x4 & y_pos9:4 = cube_y4 & is_exist4 = 1 )| ( x_pos9:4 = cube_x5 & y_pos9:4 = cube_y5 & is_exist5 = 1 )| ( x_pos9:4 = cube_x6 & y_pos9:4 = cube_y6 & is_exist6 = 1 )| ( x_pos9:4 = cube_x7 & y_pos9:4 = cube_y7 & is_exist7 = 1 )| ( x_pos9:4 = cube_x8 & y_pos9:4 = cube_y8 & is_exist8 = 1 )| ( x_pos9:4 = cube_x9 & y_pos9:4 = cube_y9 & is_exist9 = 1 )| ( x_pos9:4 = cube_x10 & y_pos9:4 = cube_y10 & is_exist10 = 1 )| ( x_pos9:4 = cube_x11 & y_pos9:4 = cube_y11 & is_exist11 = 1 )| ( x_pos9:4 = cube_x12 & y_pos9:4 = cube_y12 & is_exist12 = 1 )| ( x_pos9:4 = cube_x13 & y_pos9:4 = cube_y13 & is_exist13 = 1 )| ( x_pos9:4 = cube_x14 & y_pos9:4 = cube_y14 & is_exist14 = 1 )| ( x_pos9:4 = cube_x15 & y_pos9:4 = cube_y15 & is_exist15 = 1 )snake = ( die_flash = 1 ) ? body : none;elsesnake = none;endend endmodule2.3snake_eating_apple此模块需要在液晶显示器有效区域内随机产生一个苹果,而且需要判断蛇是否已吃下苹果。此子模块代码如下:module snake_eating_apple (input clk,input reset,input 5:0 head_x,input 5:0 head_y,output reg 5:0 apple_x,output reg 4:0 apple_y,output reg add_cube);reg 31:0 clk_cnt;reg 10:0 random_num;always ( posedge clk )random_num = random_num + 927; always ( posedge clk ) beginif( reset = 0 ) beginclk_cnt = 0;apple_x = 24;apple_y = 10;add_cube = 0;endelse beginclk_cnt = clk_cnt + 1;if( clk_cnt = 250000 ) beginclk_cnt = 0;if( apple_x = head_x & apple_y = head_y ) begin add_cube = 1;apple_x 38 ) ? ( random_num10:5 - 25 ) :( random_num10:5 = 0 ) ? 1:random_num10:5;apple_y 28 ) ? ( random_num4:0 - 3 ) :( random_num4:0 = 0 ) ? 1 : random_num4:0; endelse add_cube = 0;endendendendmodule2.4vga_control此模块直接控制液晶屏的显示。产生五个信号:红、绿、蓝三色信号和行帧同步信号。此子模块代码如下:module vga_control (input clk,input reset,input 1:0 snake,input 5:0 apple_x,input 4:0 apple_y,output reg 9:0 x_pos,output reg 9:0 y_pos,output reg h_sync,output reg v_sync,output reg 2:0 color_out);reg 19:0 clk_cnt;reg 9:0 line_cnt;reg clk_25m;localparam none = 2b00;localparam head = 2b01;localparam body = 2b10;localparam wall = 2b11;localparam head_color = 3b010;localparam body_color = 3b011;reg 3:0 lox;reg 3:0 loy;always ( posedge clk ) beginclk_25m = clk_25m;end/ generate display signalalways ( posedge clk_25m ) beginif( reset = 0) begin clk_cnt = 0;line_cnt = 0;h_sync = 1;v_sync = 1;endelse beginx_pos = clk_cnt 144;y_pos = line_cnt 33;/产生水平控制信号if( clk_cnt = 0 ) beginh_sync = 0;clk_cnt = clk_cnt + 1;endelse if( clk_cnt = 96 ) beginh_sync = 1;clk_cnt = clk_cnt + 1;endelse if( clk_cnt = 799 ) beginclk_cnt = 0;line_cnt = line_cnt + 1;endelse clk_cnt = clk_cnt + 1;/ 产生垂直控制信号if( line_cnt = 0 ) beginv_sync = 0;endelse if( line_cnt = 2 ) beginv_sync = 1;endelse if( line_cnt = 521 ) beginline_cnt = 0;v_sync = 0 & x_pos = 0 & y_pos 480 ) beginlox = x_pos3:0;loy = y_pos3:0;if( x_pos9:4 = apple_x & y_pos9:4 = apple_y )case( loy, lox )8b0000_0000: color_out = 3b000; default:color_out = 3b001; endcaseelse if( snake = none )color_out = 3b000;else if( snake = wall )color_out = 3b101;else if( snake = head | snake = body ) begincase( lox, loy )8b0000_0000: color_out = 3b000;default:color_out = ( snake = head ) ? head_color : body_color;endcaseendendelse color_out = 3b000;endend endmodule2.5key 本模块根据拨码开关的高低电平,来产生left、right、up和down的信号,从而控制蛇的运动方向。此子模块代码如下:module key (input clk,input reset,input left,input right,input up,input down,output reg left_key_press,output reg right_key_press,output reg up_key_press,output reg down_key_press);reg 31:0 clk_cnt;reg left_key_last;reg right_key_last;reg up_key_last;reg down_key_last;always ( posedge clk ) beginif( !rese
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 广东工商职业技术大学《地理学与生活》2023-2024学年第二学期期末试卷
- 西宁城市职业技术学院《中医经典金匮要略》2023-2024学年第二学期期末试卷
- 春节前期专项安全教育
- 交互式界面设计配色排版
- 小学理想教育活动设计
- 2025合同违约还是欺诈行为
- 2025安全器材采购合同模板
- 2025瓷砖销售合同范本
- 2025电子版劳动合同样本
- 2025授权加工合同示例
- 社会风险评估风险报告编制方案(技术方案)
- 4.2《 依法履行义务》教学设计 -2024-2025学年统编版道德与法治八年级下册
- 教师语言与沟通艺术知到智慧树章节测试课后答案2024年秋温州大学
- 学生常见病预防
- 大数据时代零食很忙营销现状及策略的优化
- SJG 39-2017 深圳市电动自行车充电库(棚)工程技术规程
- 中国糖尿病防治指南(2024版)解读
- 协力安全管理
- 《路基养护》课件
- 2025年上海二手房买卖合同参考范文(2篇)
- 食堂食材配送采购投标方案(技术标)
评论
0/150
提交评论