基于FPGA的五子棋游戏设计

基于FPGA的五子棋游戏设计
本文基于FPGA设计五子棋游戏,使用按键输入,使用VGA接口输出。五子棋的棋具与围棋相同,棋子分为黑白两色,棋盘为10×10,棋子放置于棋盘线交叉点上。两人对局,各执一色,轮流下一子,先将横、竖或斜线的5个或5个以上同色棋子连成不间断的一排者为胜。
VGA技术介绍:
VGA 接口就是显卡上输出模拟信号的接口,也叫 D-Sub 接口。VGA 接口是一种 D
型口,上面共有 15 针空,分成三排,每排五个。VGA 接口是目前中低端电脑配置上的主流口。
VGA显示中,FPGA需要产生5个信号:R、G、B三基色信号,行同步信号HS,场同步信号VS。以上接口的5个孔对应着我们FPGA中产生的5个重要的信号,其中R、G、B是数据信号;HS、VS是控制信号。下面是VGA 显示模块与CRT 显示器的控制框图:
在这里插入图片描述

像素是产生各种颜色的基本单元。根据物理学中的混色原理,三色发光的亮度比例适当,可呈现白色。适当的调整发光比例可以出现不同的颜色。三基色混色原理示意图如下图所示:
在这里插入图片描述

对于显示器来说,RGB三个信号其实是模拟信号,其电平的高低,可以表示颜色的深浅。利用这个原理,我们就可以产生丰富的色彩。为了控制电压的高低,我们就必须用到DA芯片。例如下图中,FPGA产生RGB三种信号,这时RGB都是多位的数字信号。DA芯片根据数字信号的值,产生不同电压的模拟信号rgb。

在这里插入图片描述

DE1-SoC板上有一个15针D-SUB连接器,用于VGA输出。VGA同步信号直接从Cyclone V SoC FPGA和Analog器件ADV7123三路10位高速视频DAC(仅使用较高的8位)转换从数字到模拟的信号代表三种基本颜色(红色,绿色和蓝色)。 它可以支持高达SXGA标准(1280 * 1024),信号以100MHz传输。 下图显示FPGA和VGA之间连接的信号。

在这里插入图片描述
在这里插入图片描述

显示器采用光栅扫描方式,即轰击荧光屏的电子束在 CRT 屏幕上从左到右(受水平同步信号 HSYNC 控制)、从上到下(受垂直同步信号 VSYNC 控制)做有规律的移动。电子束采用光栅扫描方式,从屏幕左上角一点开始,向右逐点进行扫描,形成一条水平线;到达最右端后,又回到下一条水平线的左端,重复上面的过程;当电子束完成右下角一点的扫描后,形成一帧。此后,电子束又回到左上方起点,开始下一帧的扫描。这种方法也就是常说的逐行扫描显示。
完成一行扫描的时间称为水平扫描时间,其倒数称为行频率;完成一帧(整屏)扫描的时间称为垂直扫描时间,其倒数称为场频率,即刷新一屏的频率,常见的有60Hz,75Hz等等。标准的VGA显示的场频60Hz。
行时序和场时序都需要同步脉冲(Sync a)、显示后沿(Back porch b)、显示时序段(Display interval c)和显示前沿(Front porch d)四部分。VGA工业标准显示模式要求:行同步,场同步都为负极性,即同步脉冲要求是负脉冲。

VGA支持的规格
在这里插入图片描述

在这里插入图片描述

我们以第一个分辨率640/480来分析,其刷新速率是60Hz,每幅图像有525行,每行有800个值。也就是说完成一幅图像约是1s/60=16.6ms,完成一行约为16.6ms/525=31.75us,完成一个像素传送约来31.75us /800=40ns。因此为了方便设计,接口的时候设为25MHz最方便,每个时钟送一个数据。

VGA时序设计

根据上节的介绍,VGA时序要求如下

在这里插入图片描述

VGA时序代码设计

/**********VGA驱动**********/
always@(posedge vga_clk or negedge rst_n)beginif(!rst_n)beginhcount <= 10'd0;endelse if(hcount == 10'd799)beginhcount <= 10'd0;endelse beginhcount <= hcount+1'b1;endendalways@(posedge vga_clk or negedge rst_n)beginif(!rst_n) beginvcount <= 10'd0;endelse if(hcount == 10'd799)beginif(vcount==524)vcount <= 0;elsevcount <= vcount+1;endendalways@(posedge vga_clk or negedge rst_n)beginif(!rst_n)beginhsync <= 1;endelse if(hcount==10'd95)beginhsync <= 1'b1;endelse if(hcount==10'd799)beginhsync <= 1'b0;end
endalways@(posedge vga_clk or negedge rst_n)beginif(!rst_n)beginvsync <= 1'b1;endelse if(vcount<10'd2)beginvsync <= 1'b0;endelse beginvsync <= 1'b1;end
end    

VGA时序仿真结果

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

五子棋设计
为了节约FPGA资源,本文设计并编写了10x10 五子棋的专用算法。棋子半径大小20个像素。光标当前的棋子所在位置使用青色表示,因为屏幕背景色是黑色,棋盘背景色是白色,所以黑白棋子使用紫色和黄色代替。
棋盘设计:
设10x10数组reg [9:0] PLAYED [9:0]; 数组中每一位代表棋盘的一个交叉点。数组的某位为0时,代表无子状态; 为l时,代表有棋子;
设10x10数组reg [9:0] CHESS_COLOR [9:0];表示棋子的颜色。
产生棋盘格的代码如下:

//产生竖长条
always@(posedge vga_clk )
beginif(hcount<=200||hcount>=640)beginv_flag <= 1'b1 ;    v_dat <= 12'h000;//heiend else if(hcount ==240||hcount ==280||hcount ==320||hcount ==360||hcount ==400||hcount ==440||hcount ==480||hcount ==520||hcount==560||hcount==600) beginv_flag <= 1'b1 ;    v_dat <= 12'h000;//heiend else beginv_flag <= 1'b0 ;    v_dat <= 12'hfff;//baiend
end//产生横长条
always@(posedge vga_clk )
beginif(vcount<=50||vcount>=490) beginh_flag <= 1'b1 ;h_dat <= 12'h000;//heiend else if(vcount ==90||vcount ==130||vcount ==170||vcount==210 ||vcount==250||vcount ==290||vcount ==330||vcount==370 ||vcount==410||vcount==450) beginh_flag <= 1'b1 ;    h_dat <= 12'h000;end else beginh_flag <= 1'b0 ;      h_dat <= 12'hfff;end
end  

2)当前棋子光标提示设计:
当前棋子位置提示显示数据为x_data,显示青色。V_dat和H_dat是横竖线的,显示为黑色,y_dat为棋子颜色。

/

/显示模块 
always@(posedge vga_clk)
begin
if(dat_act)beginif(over==0 && over2==0  &&   debug_flag==0    ) beginif(curchess_flag)disp_rgb <=x_dat;    // else if(v_flag)disp_rgb <=v_dat;    // else if(h_flag)disp_rgb <=h_dat;    // else if(chess_flag)disp_rgb <=y_dat;    //  elsedisp_rgb <=12'hfff;    //   end elsedisp_rgb <=z_dat;    			//游戏结束则显示另外画面
end
else begin
disp_rgb = 12'h000;  //VGA区域之外  
end   
end

3)按钮上、下、左、右、落子:

always@(posedge sysclk or negedge rst_n)beginif(!rst_n)beginPLAYED[0]<=10'd0;  PLAYED[1]<=10'd0;  PLAYED[2]<=10'd0;  PLAYED[3]<=10'd0;  PLAYED[4]<=10'd0;  PLAYED[5]<=10'd0;  PLAYED[6]<=10'd0;  PLAYED[7]<=10'd0;  PLAYED[8]<=10'd0;  PLAYED[9]<=10'd0;      CHESS_COLOR[0]<=10'd0;  CHESS_COLOR[1]<=10'd0;  CHESS_COLOR[2]<=10'd0;  CHESS_COLOR[3]<=10'd0;  CHESS_COLOR[4]<=10'd0;  CHESS_COLOR[5]<=10'd0;  CHESS_COLOR[6]<=10'd0;  CHESS_COLOR[7]<=10'd0;  CHESS_COLOR[8]<=10'd0;  CHESS_COLOR[9]<=10'd0;  endelse
begincase(key_en_tem)5'b00100:begin if (ball_x_pos== 10'd240)ball_x_pos<=10'd600;else ball_x_pos<=ball_x_pos-10'd40;end5'b01000:begin if (ball_x_pos==10'd600)ball_x_pos<=10'd240;else ball_x_pos<= ball_x_pos+10'd40;end 5'b00001: begin if (ball_y_pos== 10'd90)ball_y_pos<=10'd450;else ball_y_pos<=ball_y_pos-10'd40;                                                end5'b00010: beginif(ball_y_pos== 10'd450)ball_y_pos<=10'd90;else         ball_y_pos<=ball_y_pos+10'd40; end      5'b10000: beginif(PLAYED[current_y][current_x]==0)beginPLAYED[current_y][current_x]<=1;                                     
CHESS_COLOR[current_y][current_x]<=change_color;endend     

(4)判胜:
横竖正斜反斜四个方向出现连续落子,且颜色一样,输出胜利提示。


```c
//输赢状态判断1
always@(posedge vga_clk )if(!rst_n)beginover<=0; endelse
beginif (  (scan_x<=5&&CHESS_COLOR[scan_y][scan_x]==1&&CHESS_COLOR[scan_y][scan_x+1]==1&&CHESS_COLOR[scan_y][scan_x+2]==1&&CHESS_COLOR[scan_y][scan_x+3]==1&&CHESS_COLOR[scan_y][scan_x+4]==1)//heng&&   (PLAYED[scan_y][scan_x]==1&&PLAYED[scan_y][scan_x+1]==1&&PLAYED[scan_y][scan_x+2]==1&&PLAYED[scan_y][scan_x+3]==1&&PLAYED[scan_y][scan_x+4]==1)       )     beginover<=1;endelse if( (scan_y<=5&&CHESS_COLOR[scan_y][scan_x]==1&&CHESS_COLOR[scan_y+1][scan_x]==1&&CHESS_COLOR[scan_y+2][scan_x]==1&&CHESS_COLOR[scan_y+3][scan_x]==1&&CHESS_COLOR[scan_y+4][scan_x]==1)//shu&&     (PLAYED[scan_y][scan_x]==1&&PLAYED[scan_y+1][scan_x]==1&&PLAYED[scan_y+2][scan_x]==1&&PLAYED[scan_y+3][scan_x]==1&&PLAYED[scan_y+4][scan_x]==1) )beginover<=1;endelse if(  (scan_x<=5&&scan_y<=5&&CHESS_COLOR[scan_y][scan_x]==1&&CHESS_COLOR[scan_y+1][scan_x+1]==1&&CHESS_COLOR[scan_y+2][scan_x+2]==1&&CHESS_COLOR[scan_y+3][scan_x+3]==1&&CHESS_COLOR[scan_y+4][scan_x+4]==1)//chenggong&&  (PLAYED[scan_y][scan_x]==1&&PLAYED[scan_y+1][scan_x+1]==1&&PLAYED[scan_y+2][scan_x+2]==1&&PLAYED[scan_y+3][scan_x+3]==1&&PLAYED[scan_y+4][scan_x+4]==1) )over<=1;else if ( (scan_y<=5&&scan_x>=4&&CHESS_COLOR[scan_y][scan_x]==1&&CHESS_COLOR[scan_y+1][scan_x-1]==1&&CHESS_COLOR[scan_y+2][scan_x-2]==1&&CHESS_COLOR[scan_y+3][scan_x-3]==1&&CHESS_COLOR[scan_y+4][scan_x-4]==1)&& (PLAYED[scan_y][scan_x]==1&&PLAYED[scan_y+1][scan_x-1]==1&&PLAYED[scan_y+2][scan_x-2]==1&&PLAYED[scan_y+3][scan_x-3]==1&&PLAYED[scan_y+4][scan_x-4]==1) )over<=1;
end        

```c
//输赢状态判断2 yellow
always@(posedge vga_clk )if(!rst_n)beginover2<=0;    debug_flag<=0;   endelse
beginif( (scan_x<=5&&CHESS_COLOR[scan_y][scan_x]==0&&CHESS_COLOR[scan_y][scan_x+1]==0&&CHESS_COLOR[scan_y][scan_x+2]==0&&CHESS_COLOR[scan_y][scan_x+3]==0&&CHESS_COLOR[scan_y][scan_x+4]==0)//heng&&   (PLAYED[scan_y][scan_x]==1&&PLAYED[scan_y][scan_x+1]==1&&PLAYED[scan_y][scan_x+2]==1&&PLAYED[scan_y][scan_x+3]==1&&PLAYED[scan_y][scan_x+4]==1)       ) over2<=1;else if( (scan_y<=5&&CHESS_COLOR[scan_y][scan_x]==0&&CHESS_COLOR[scan_y+1][scan_x]==0&&CHESS_COLOR[scan_y+2][scan_x]==0&&CHESS_COLOR[scan_y+3][scan_x]==0&&CHESS_COLOR[scan_y+4][scan_x]==0)//shu&&     (PLAYED[scan_y][scan_x]==1&&PLAYED[scan_y+1][scan_x]==1&&PLAYED[scan_y+2][scan_x]==1&&PLAYED[scan_y+3][scan_x]==1&&PLAYED[scan_y+4][scan_x]==1) )beginover2<=1;debug_flag<=1;  endelse if(  (scan_x<=5&&scan_y<=5&&CHESS_COLOR[scan_y][scan_x]==0&&CHESS_COLOR[scan_y+1][scan_x+1]==0&&CHESS_COLOR[scan_y+2][scan_x+2]==0&&CHESS_COLOR[scan_y+3][scan_x+3]==0&&CHESS_COLOR[scan_y+4][scan_x+4]==0)//chenggong&&  (PLAYED[scan_y][scan_x]==1&&PLAYED[scan_y+1][scan_x+1]==1&&PLAYED[scan_y+2][scan_x+2]==1&&PLAYED[scan_y+3][scan_x+3]==1&&PLAYED[scan_y+4][scan_x+4]==1) )over2<=1;else if ( (scan_y<=5&&scan_x>=4&&CHESS_COLOR[scan_y][scan_x]==0&&CHESS_COLOR[scan_y+1][scan_x-1]==0&&CHESS_COLOR[scan_y+2][scan_x-2]==0&&CHESS_COLOR[scan_y+3][scan_x-3]==0&&CHESS_COLOR[scan_y+4][scan_x-4]==0)&& (PLAYED[scan_y][scan_x]==1&&PLAYED[scan_y+1][scan_x-1]==1&&PLAYED[scan_y+2][scan_x-2]==1&&PLAYED[scan_y+3][scan_x-3]==1&&PLAYED[scan_y+4][scan_x-4]==1) )over2<=1;  
end        

(5)win画面:在任一方胜利后VGA显示win三个字母画面输出胜利提示。根据棋子颜色win显示不同颜色以显示

//产生win画面1
always@(posedge vga_clk )
beginif(((hcount>=240&&hcount<=260)||(hcount>=300&&hcount<=320)||(hcount>=360&&hcount<=380)||(hcount>=420&&hcount<=440)||(hcount>=480&&hcount<=500)||(hcount>=560&&hcount<=580))&&(vcount >=200&&vcount <=360))beginz_flag <= 1'b1;if(over)z_dat <= 12'hf0f;elsez_dat <= 12'hff0;    end else if(hcount>=260&&hcount<=380&&vcount>=340&&vcount <=360) beginz_flag <= 1'b1;if(over)z_dat <= 12'hf0f;elsez_dat <= 12'hff0;    end else if(hcount>=500&&hcount<=560&&vcount>=200&&vcount <=220) beginz_flag <= 1'b1;if(over)z_dat <= 12'hf0f;elsez_dat <= 12'hff0;    end else beginz_flag <= 1'b0;z_dat <= 12'hfff;end
end       

遇到的问题:
1 棋子颜色显示不稳定,下棋时棋子颜色随机产生不受控制。原因怀疑是时钟一开始是分频产生的25M,后面换成pll锁相环后问题果然解决。
一开始的时钟产生方法:

always@(posedge sysclk)
beginvga_clk <= ~vga_clk;
end   
优化后的:pll pll(.inclk0(sysclk),.c0(vga_clk)
);

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/181859.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【IEEE出版】2024年第四届消费电子与计算机工程国际学术会议(ICCECE 2024)

2024年第四届消费电子与计算机工程国际学术会议&#xff08;ICCECE 2024&#xff09; 2024 4th International Conference on Consumer Electronics and Computer Engineering 进入21世纪以来&#xff0c;计算机技术的高速发展带来了消费电子产品的快速更迭。在技术迅速发展历…

关于免费SSL证书

JoySSL是一家提供免费SSL证书的服务商&#xff0c;它的免费SSL证书不仅包括单域名&#xff0c;还包括多域名和通配符的免费证书。这意味着&#xff0c;无论您是只有一个网站的个人用户&#xff0c;还是拥有多个子域名的企业用户&#xff0c;都可以在JoySSL找到适合您的免费SSL证…

\n\r:解析java中的\r、\n、\r\n、\n\r的区别

1 \r 1.1 内容 回车符,将光标定义到当前行行首 1.2 在idea中测试 1.2.1 表现形式 在\r后有新内容时,会先删除之前以前存在过的文本,即只打印\r后面的内容 1.2.2 示例代码 package Work; public class Test05 { public static void main(String[] args) { System.…

windows环境下载安装Nginx并配置防火墙

1、下载Nginx Nginx官网 下载稳定版 2、下载之后&#xff0c;解压 3、启动Nginx&#xff0c;命令&#xff1a;start nginx 最小化该窗口 主要&#xff0c;不要关闭&#xff0c;如果关闭&#xff0c;表示nginx服务关闭了 4、测试是否启动成功 在浏览器中输入http://localhos…

2021年09月 Scratch图形化(三级)真题解析#中国电子学会#全国青少年软件编程等级考试

Scratch等级考试(1~4级)全部真题・点这里 一、单选题(共25题,每题2分,共50分) 第1题 程序中要使用不确定的数值,这时要用到的是?( ) A、图章 B、变量 C、广播 D、随机数 答案:D 第2题 执行下列程序后,角色会说?( ) A、3 B、6 C、10 D、15 答案:D 第3题…

广州华锐视点:基于VR元宇宙技术开展法律法规常识在线教学,打破地域和时间限制

随着科技的飞速发展&#xff0c;人类社会正逐渐迈向一个全新的时代——元宇宙。元宇宙是一个虚拟的、数字化的世界&#xff0c;它将现实世界与数字世界紧密相连&#xff0c;为人们提供了一个全新的交流、学习和娱乐平台。在这个充满无限可能的元宇宙中&#xff0c;法律知识同样…

关于MongoDB

MongoDB介绍 MongoDB是一个介于关系数据库和非关系数据库之间的产品&#xff0c;是非关系数据库当中功能最丰富&#xff0c;最像关系数据库的。它支持的数据结构非常松散&#xff0c;因此可以存储比较复杂的数据类型。Mongo最大的特点是它支持的查询语言非常强大&#xff0c;其…

Panorama SCADA平台助力智能建筑管理,掌控未来建筑!

来源&#xff1a;宏集科技 工业物联网 宏集方案 Panorama SCADA平台助力智能建筑管理&#xff0c;掌控未来建筑&#xff01; 欢迎关注虹科&#xff0c;为您提供最新资讯&#xff01; 前言 在现代智能建筑管理中&#xff0c;随着设施管理&#xff08;FM&#xff09;、建筑管理…

数据结构与算法--特殊的完全二叉树--堆,堆排序,利用堆解决topk的问题

目录 前言 1.树概念及结构 1.1树的概念 1.2 树的相关概念 1.3 树的表示 1.4 树在实际中的运用&#xff08;表示文件系统的目录树结构&#xff09; 2.二叉树概念及结构 2.1概念 2.2现实中的二叉树&#xff1a; 2.3 特殊的二叉树&#xff1a; 2.4 二叉树的性质 …

YOLOv7独家原创改进:自研独家创新MSAM注意力,通道注意力升级,魔改CBAM

💡💡💡本文自研创新改进:MSAM(CBAM升级版):通道注意力具备多尺度性能,多分支深度卷积更好的提取多尺度特征,最后高效结合空间注意力 1)作为注意力MSAM使用; 推荐指数:五星 MSCA | 亲测在多个数据集能够实现涨点,对标CBAM。 在道路缺陷检测任务中,原始ma…

基于STM32+定时器中断和定时器外部时钟(标准库函数讲解)

前言 本篇博客主要学习了解定时器的标准库函数&#xff0c;以及定时器中断进行LED灯的反转&#xff0c;还有定时器外部时钟获取脉冲计数功能。本篇博客大部分是自己收集和整理&#xff0c;如有侵权请联系我删除。 本篇博客主要是对通用定时器来讲解&#xff0c;功能适中比较常…

Java高级技术(注解)

一&#xff0c;注解 二&#xff0c;案例 三&#xff0c;注解原理 四&#xff0c;元注解 五&#xff0c;案例 六&#xff0c;解析注解 七&#xff0c;案例

unity UI特效遮罩

using System.Collections; using System.Collections.Generic; using UnityEngine;/**UI特效遮罩 1.需要将ScrollRect 的遮罩Mask 换为 2D Mask2.将特效的Render里面的 Masking 设置为*/ public class UIParticleMaskControll : MonoBehaviour {// Start is called before …

低代码平台:房企建造领域数字化转型的必备利器

在数字化浪潮的推动下&#xff0c;越来越多的行业开始向数字化转型迈进&#xff0c;房地产建筑管理也不例外。低代码平台作为一种新兴的技术趋势&#xff0c;正逐渐成为推进房地产建筑管理数字化转型的重要工具。 房地产建筑管理作为一个庞大而复杂的行业&#xff0c;数字化转…

『Confetti 喜庆散花插件の使用』

以下用 VUE3 语法 举例使用&#xff1a; npm install js-confetti<script setup lang"ts"> import JSConfetti from js-confetticonst confetti new JSConfetti()function showConfetti() {confetti.addConfetti() } </script><template><h1 …

视频剪辑技巧:批量剪辑新思路,AI智剪来助阵

在视频制作过程中&#xff0c;剪辑是一项至关重要的任务。然而&#xff0c;对于许多创作者来说&#xff0c;批量剪辑视频是一项耗时且繁琐的工作。传统的批量剪辑方法通常要创作者逐个打开视频文件&#xff0c;进行剪辑、调整色彩等操作。这种方法不仅效率低下&#xff0c;而且…

探索低代码之路——JNPF

目录 一、低代码行业现状 二、产品分析 1.可视化应用开发 2.流程管理 3.整个平台源码合作 三、架构和技术 技术栈 四、规划和展望 低代码平台&#xff08;Low-code Development Platform&#xff09;是一种让开发者通过拖拽和配置&#xff0c;而非传统的手动编写大量代…

Linux 启动过程

linux启动步骤&#xff1a; <1>加电 <2>加载bios设置 <3>加载grup <4>加载内核系统到内存中 <5>加载配置文件 <6>加载内核模块 <7>完成相应的初始化工作和启动相应的服务 <8>启动系统进程 <9>出现登录界面 &l…

Python 装饰器与偏函数

目录 装饰器 概念 简单的装饰器 复杂点的装饰器 通用装饰器 定义通用装饰器 使用装饰器 偏函数 引入类库 应用 总结 装饰器 概念 装饰器就是个闭包&#xff1b;把一个函数当做参数&#xff0c;返回一个修改过功能的函数&#xff1b; 本质上是一个返回函数的函数。…

基于Java SSM框架+Vue实现垃圾分类网站系统项目【项目源码+论文说明】

基于java的SSM框架Vue实现垃圾分类网站系统演示 摘要 本论文主要论述了如何使用JAVA语言开发一个垃圾分类网站 &#xff0c;本系统将严格按照软件开发流程进行各个阶段的工作&#xff0c;采用B/S架构&#xff0c;面向对象编程思想进行项目开发。在引言中&#xff0c;作者将论述…