找回密码
 注册
关于网站域名变更的通知
查看: 335|回复: 2
打印 上一主题 下一主题

基于FPGA的“俄罗斯方块”设计(附代码)

[复制链接]

该用户从未签到

跳转到指定楼层
1#
 楼主| 发表于 2024-7-14 08:31 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式

EDA365欢迎您登录!

您需要 登录 才可以下载或查看,没有帐号?注册

x
今天给各位大侠带来基于FPGA的“俄罗斯方块”设计,设计思路以及代码参考文档。本篇主要在FPGA上实现了一个经典小游戏“俄罗斯方块”。本项目基本解决方案是,使用Xilinx Zynq系列开发板 ZedBoard 作为平台,实现主控模块,通过VGA接口来控制屏幕进行显示。
7 `$ }$ k7 b  n; r
  m  C4 m% S8 y1 ]3 y
         以后机会多多,慢慢分享一些项目开发以及深入学习方面的内容,欢迎各位大侠一起交流学习,取其精华,去其糟粕,共同进步。话不多说,上货。$ h: h. h: f0 V& o% ]. t2 Z6 Z
4 U4 E$ H2 E* y! y( z8 U: p6 X' {
设计目的
  B$ G9 k% w/ v9 v7 H

# U0 w" {) N3 P+ @: w. K

' B" L  v& C. c: H

通过此次项目,完成以下目的:

1) 熟悉Xilinx FPGA的架构及开发流程;

2) 设计一个功能完整的系统,掌握FSM + Datapath的设计方法。

) N' Q" \% y: Q: Y3 g* W' b6 ^$ c! P

3 |0 v$ E- _3 [7 D2 ^% l' W
# W2 Q# U6 g9 I& y

设计内容


# v6 `9 ]9 h( Y6 _" I
0 K: {1 s0 g* ?- W

1. 项目介绍

本项目主要在FPGA上实现了一个经典小游戏“俄罗斯方块”。本项目基本解决方案是,使用Xilinx Zynq系列开发板 ZedBoard 作为平台,实现主控模块,通过VGA接口来控制屏幕进行显示。

' v! p- K5 p4 C& M5 H; c$ A

2. 系统框架

/ {0 [( n/ R) k9 m; y! o( x$ J3 Q

整个系统由四部分组成,按键输入处理模块、控制模块、数据路径模块以及VGA显示接口模块。整个系统的结构如下图所示:

( g2 G  x" c  d% n% h

/ ]' z3 r; I1 h+ }3 r; K
1 A0 t6 F6 D) Y$ t1 O' c; i


! U& |) }2 W/ S% I6 S: j. P5 ~9 N: N) u% \/ \. s

下面分别对四个模块进行介绍:

1) 按键输入处理模块

按键处理模块的主要功能是对输入系统的up,down,left,right四个控制信号进行消抖处理,并对其进行上升沿检测。


$ {7 g' b1 ^0 o% s# x

消抖模块采用了一个4位的移位寄存器,先将输入信号延迟4个时钟周期,再对其以一个较低的时钟频率进行采用。消抖模块的结构如下图所示:

/ z0 R( V2 I. ]/ \" k. ~$ f) r3 ]
5 ]5 k: L/ _# u; u) {# p, o7 Z
  e' S) v; r6 B  |1 n2 I' H
. K' l  |: P: P2 K6 G; i
! j! _+ {; ^, q  N
8 ^: s1 d; v& ~& H, n9 i/ E

+ g, U# V" O/ _8 A% P8 M$ q
' q% E/ A  S4 p3 m: ]2 G" |- u/ v8 s# c; E3 m

# H* M2 p8 ]2 P
: `% t0 [5 D# |1 G* h% e

为了简化控制系统,在本系统的设计过程中,不考虑长时间按键产生连按效果。因而,需要对按键进行上升沿检测。上升沿检测的基本实现方案是加入一组寄存器,对前一个的按键信号进行暂存,将暂存的值与当前值进行比较,当上一个值为0而当前值为1时,即认为其检测到了一个上升沿。

3 }- E" o. o/ M

2) 控制模块

控制模块采用FSM的方式进行控制。在控制模块中,定义了10个状态:

S_idle:上电复位后进入空状态,当start信号为1时进入S_new状态

S_new:用于产生新的俄罗斯方块。

S_hold:保持状态。在这个状态中进行计时,当时间到达一定间隔时,转到S_down状态;或者等待输入信号(up,down,left,right)时,转到S_down(按键为down)或者S_move(up,left,right)状态。

S_down:判断当前俄罗斯块能否下移一格。如果可以,则转到S_remove_1状态,如果不行,则转到S_shift状态。

S_move:判断当前俄罗斯块能够按照按键信号指定的指令进行移动,如果可以,则转到S_shift状态,如果不可以,则转到S_remove_1状态。

S_shift:更新俄罗斯方块的坐标信息。返回S_hold。

S_remove_1:更新整个屏幕的矩阵信息。转移到S_remove_2状态。

S_remove_2:判断是否可以消除,将可以消除的行消除,并将上面的行下移一行。重复此过程,直到没有可消除的行为止。跳转到S_isdie状态

S_isdie:判断是否游戏结束。如果结束,则跳转到S_stop状态。如果没有,则跳转到S_new状态,生成新的俄罗斯方块。

S_stop:清除整个屏幕,并跳转到S_idle状态。

- r% Q+ J) K4 I% ]9 Y

整个控制过程的ASMD图如下图所示:

1 @* J; B6 w; y% M" q

7 ^2 g" c- B: D4 [1 a

0 v, a6 \" ~: X" l. \. Q$ f, Y7 Q
7 R! [2 R+ v+ N6 I& n

/ a- O: b5 G6 a5 T

3) 数据路径

数据路径模块主要功能是,根据控制模块给出的信号,对俄罗斯方块当前的逻辑状态进行判断,更新背景矩阵。具体如下:

方块:

方块分为非活动方块与活动方块。非活动方块为:(1)之前下落的方块;(2)下落后方块消除之后的结果。由背景矩阵表示。活动方块为当前下落中的方块,由活动方块坐标与方块类型表示(后简称方块)。

背景矩阵:

reg [9:0] R [23:0];

背景矩阵R是24行10列的寄存器组,负责保存非活动方块坐标,即R中任一位置,如方块存在,则该位置1,否则为0。

活动方块坐标:

output reg [4:0] n,

output reg [3:0] m,

n, m分别为当前活动方块的行、列指针,指向方块固定点位置。方块固定点为方块旋转时不变的格点,依据方块种类决定,下文方块模型中详述。

方块类型:

output reg [6:0] BLOCK,

BLOCK代表方块类型,由7位编码构成。


8 V/ y7 e1 q% V. b0 [

数据交换:

Datapath与其余模块的数据交换分为两部分:

(1)与control_unit间的状态指令交互;

(2)控制merge,间接实现对VGA的控制。


+ E+ m9 l$ }( V1 b6 W

方块模型:

7 B% [* ?/ c) m5 _. X- Z5 c# _

俄罗斯方块共有7种形状的方块(O,L,J,I,T,Z,S),每种方块有1-4种不同的旋转变形方式。为方便起见,将方块定位A-G,旋转编号为1-4,将方块编码成A_1-G_2的19种,如下图:(图中,深色方块是该种方块的固定点)

, @8 H( _" M- W8 l" S

: f5 c! |# h* P& W5 G  ^8 S9 u

6 ]- z0 K  t4 i/ B" x" U

: l' ~. x+ {1 x( o$ I8 G; c8 p6 U9 W) W1 _7 q: `( ~

方块运动:

产生:

方块产生由一个简单的伪随机过程决定。系统采用一个3位的计数器产生随机数,进入S_new,BLOCK的值被NEW_BLOCK覆盖,方块坐标n<=1;m<=5;同时,根据计数器,NEW_BLOCK的值刷新为A_1,B_1,…,G_1中的一种,作为下一次方块。

) j% A- l/ }6 t8 @( G' i

+ u- B9 j# `, {4 @/ R7 B

移动:

方块移动分为四种:旋转,下落,向左,向右,由键盘KEYBOARD=[UP, DOWN, LEFT, RIGHT]控制。移动分两步进行:(1)判断;(2)转换。

判断过程包含S_down,S_move。判断分两步:首先,判断变换后方块坐标是否合法,即变换后是否会造成方块越界。然后,判断变换后方块可能占据的新位置是否有背景矩阵方块存在。两步判断通过后返回成功信号,否则失败。因判断代码量较多,仅举一例说明:

判断D_1向右运动(MOVE_ABLE初值为0):

if (m<=8)

if (!((R[n-1][m+1])|(R[n][m+1])|(R[n+1][m+1])|(R[n+2][m+1])))

MOVE_ABLE=1;

else MOVE_ABLE=0;

转换过程(S_shift)进行方块的移动或变形。根据KEYBOARD,移动时,改变方块坐标;变形时,方块按类别变换,如:A_1→A_1;B_1→B_2; B_2→B_3; B_4→B_1;


6 J, C2 j) h- }3 {) X- H9 B7 D% {1 X$ u0 k, |/ v2 s2 ^

停止与消除:

方块停止与消除由两个状态完成:S_remove1,S_remove2。

前一状态中,根据BLOCK, n, m,将活动方块位置覆盖至R,变为非活动方块。

后一状态中,根据行满状态,进行行的消除与平移,具体如下:

显然,俄罗斯方块能影响的最大行数为4,因此,在REMOVE_2中,仅对R[n-1],R[n],R[n+1],R[n+2]四行依次进行处理。处理过程为:如果该行(k)满,则由k行开始,至1行结束,逐行向下平移,当前平移位置由计数器REMOVE_2_C控制,当前行消除截止由标志位SIG确认。

  Y+ r! j5 S- f' `  C) X

每行处理完后,将REMOVE_FINISH[3:0]中相应位置1,REMOVE_FINISH全1时,REMOVE_2完成。

0 C4 B7 p1 T3 m5 S. V

死亡判定:

R中的0-3行位于屏幕上方,不进行显示,仅有新生成的方块坐标会进入这一区域。因而,当消除完成后,如R[3]不为空,游戏结束。


' w' I) G  ?8 R6 i* T5 L- `' L  `/ L" F" s8 Y' a

4) 显示部分

3 J+ n7 q( ], H7 b8 N& d

输出结果通过VGA接口接入显示屏显示。VGA(Video Graphics Array)视频图形阵列是IBM于1987年提出的一个使用模拟信号的电脑显示标准。VGA接口即电脑采用VGA标准输出数据的专用接口。VGA接口共有15针,分成3排,每排5个孔,显卡上应用最为广泛的接口类型,绝大多数显卡都带有此种接口。它传输红、绿、蓝模拟信号以及同步信号(水平和垂直信号)。

% n" z1 U# }/ V$ h; s9 H$ w5 _' c

使用Verilog HDL语言对VGA进行控制一般只需控制行扫描信号、列扫描信号和红绿蓝三色信号输出即可。

- @+ `; l! N" H. ^4 ~

VGA输出可分为四个模块:时钟分频模块、数据组织模块、接口控制模块和顶层模块。以下进行分块描述。

6 J( q9 u% ~1 K6 c5 d

时钟模块分频模块对FPGA系统时钟进行分频。由于使用的显示屏参数为640*480*60Hz,其真实屏幕大小为800*525,因此所需时钟频率为800*525*60Hz=25.175MHz,可近似处理为25MHz。FPGA系统时钟为100M,因此将其四分频即可基本满足显示要求。

+ n  @6 x. ~0 i2 S( Z

数据组织模块是将预备输出的数据组织为可以通过VGA接口控制的数据形式,本次设计中因接口已经协调,数据可不经过此模块进行组织,故可忽略该模块。

& Y2 z* @$ m+ ]% S
7 f3 z- H3 r7 }' ^( c

接口控制模块通过VGA接口对显示屏进行控制。VGA的扫描顺序是从左到右,从上到下。例如在640X480的显示模式下,从显示器的左上角开始往右扫描,直到640个像素扫完,再回到最左边,开始第二行的扫描,如此往复,到第480行扫完时即完成一帧图像的显示。这时又回到左上角,开始下一帧图像的扫描。如果每秒能完成60帧,则称屏幕刷新频率为60Hz。宏观上,一帧屏幕由480个行和640个列填充而成,而实际上,一帧屏幕除了显示区,还包含其他未显示部分,作为边框或者用来同步。具体而言,一个完整的行同步信号包含了左边框、显示区、右边框还有返回区四个部分,总共800个像素,其分配如下:


9 ]# z( y* x' e5 K! a4 q
: i) D% V# P" h/ I


8 E) w! W1 \/ t1 t, v8 P  r8 L4 O  K8 V. K

) y+ j7 X5 @5 X8 s3 `& [- J( h) T0 v* a1 M. Z

同样的,一个完整的垂直同步信号也分为四个区域,总共525个像素,分配如下:

" G- g) c% P6 H" L$ X' x2 ~0 q
3 [8 m2 P/ ]. J& H/ ?$ R: Z( q' ?


* L& y3 D' C' k8 L" D7 [4 u- W  j! t. G1 F. K* _
8 j* _4 M* `' j) C( B8 G, K

4 c, _0 [  Z4 R9 _4 k2 \4 l

模块通过组织输出行扫描信号、列扫描信号和三原色信号对显示屏实现控制。

( P0 k9 I7 \6 [6 b  q' j

& j/ f" ?1 \1 `" V

设计结果

4 L0 a1 s. N; n( V8 H) d6 K

3 z+ E; U# E$ A5 N0 X2 K6 `1 P) V' \2 O

设计结果图如下:


0 f0 }6 j  r9 S
7 V% G# j5 W1 F, f% H4 D  U% v4 q7 t" Q: B! q/ A% }- k
5 n! V5 N; @! H" U" w
/ |  J$ f; }% w- q& q


& x- o$ y2 U& {  j9 I
8 F! }7 q! M9 r( @& l* v' m# N
图7:设计结果图

6 R5 l+ h: S  ]2 c5 h, D7 m/ j4 y, e$ X$ d2 j" k* x
9 q9 K; i8 Z" o) {$ s  f0 e
$ G9 p, l; J2 a+ A5 T% }. s

* Y- L  }% R# x0 x" _" P4 @

设计代码


4 W% ?# c& M4 L; @" D) }% ~+ H# c5 B* u4 L7 u* i9 B

由于代码量较大,这里只展示了部分代码,需要的大侠可以按照开篇介绍的方法进入“FPGA技术江湖”知识星球获取设计文档,获取设计代码。/ H0 C+ a! k2 X+ j$ {


9 y9 n9 x/ n8 G. K

顶层模块设计代码:

9 P1 Q( f# X" d
" ~6 E6 O- A$ k8 C

) c9 O7 Y8 c4 g8 Z) F& B
& J# [1 v( b. O$ Y3 `% V& \. r! W

6 M# ~* s0 ^5 z% w3 I
3 s4 u* Q: A. T' B* T0 _

KeyBoard模块代码:

8 c$ G% X3 a& _3 Z2 ?4 Y6 u( ^
5 w$ q% i* U: e. J7 ~+ e2 a

5 H, L: A( h- I/ z
' {- x/ b( j8 Q: w, r6 B( E
9 ^+ i; D( z& B2 x

控制模块代码:

1 Z2 r  H3 D( Q( r) K2 w7 c

+ e$ S& j& [& H$ t+ F9 ^
# u) n  B. d" K& B8 p. t6 i

3 K4 n2 ]4 a; l

数据路径以及VGA等模块在这里就不展示,代码量过大,详情见开篇介绍。

4 \& z# E/ @- Z# B$ [# ~: C: e
  ?! u2 c% I$ C" `: H
  • TA的每日心情

    2019-11-20 15:16
  • 签到天数: 1 天

    [LV.1]初来乍到

    2#
    发表于 2024-7-16 10:40 | 只看该作者
    FPGA并行处理数据在这方面有很大的特点
  • TA的每日心情
    难过
    2024-3-9 15:56
  • 签到天数: 1 天

    [LV.1]初来乍到

    3#
    发表于 2024-8-23 16:36 | 只看该作者
    学习学习学习
    您需要登录后才可以回帖 登录 | 注册

    本版积分规则

    关闭

    推荐内容上一条 /1 下一条

    EDA365公众号

    关于我们|手机版|EDA365电子论坛网 ( 粤ICP备18020198号-1 )

    GMT+8, 2025-7-19 21:20 , Processed in 0.140625 second(s), 26 queries , Gzip On.

    深圳市墨知创新科技有限公司

    地址:深圳市南山区科技生态园2栋A座805 电话:19926409050

    快速回复 返回顶部 返回列表