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

基于FPGA的“俄罗斯方块”系统设计

[复制链接]

该用户从未签到

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

EDA365欢迎您登录!

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

x
今天给各位大侠带来基于FPGA的“俄罗斯方块”设计。# h3 ?8 Y1 K9 @# Q
1 C) P$ d! u& s( ]/ [& @
: G4 A# ~4 k3 b/ f4 V, G

6 z3 x, E0 F) m  _4 j% g% A
2 O! W/ Y/ l2 @& \, h. r$ m

% c1 l5 g$ G3 ?1 Z, y! P# g/ g

' I. q8 o* G0 `1 M1 ]
设计目的

) J) [  @/ ?! G* L$ w4 X
# @  ?/ E' [. h- f7 h, }$ a
: g( G' i( q# H8 }: z$ u* V% y

: ^4 ^, G* ]; x* w/ R
; }- P; w1 l0 h8 m3 d: ^* H2 f

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

/ {3 e+ l8 @, _( Y1 C& @" I, t

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

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


' O1 }, A( A& [) D8 v

2 G6 F9 ?# F$ H6 c4 F- ~& [) U

设计内容


8 Z% T8 R% Z% y: h

2 M/ k- Z0 r9 }. h3 _


% d7 f3 }( p: Z0 d- v& b. I" t7 M5 s

1. 项目介绍

) M) ~5 G" }. {. x0 l

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

4 s7 N. g( ~% z/ e& |2 ^

2. 系统框架


1 ^, k9 {" o! T% Z9 Z

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


- ?' K, X& u3 a

! l. s& a9 T% J, B& X

4 L3 B& Z8 _$ a. n) [% K: v


7 f) O( Y# v' H$ l* E. b" t2 D0 @

. q( }8 G0 ~' H1 P+ O

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


$ {& G2 o( B# j$ l/ s( a7 a

1) 按键输入处理模块


2 u# E1 n2 ?3 m- H( M

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

9 d' w. W  F+ N: F/ G) p

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


6 v6 |7 B! |, p/ E; ?# o

5 w( Z; x% c2 }: g# d9 Z- @


! r: q* w7 u0 ^) c  h

1 z  p8 u) E1 a

- m8 p, }. K- H  l, S

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


; |; ~2 S" ~1 ?: F+ O

- ~# T5 n7 l' Q2 o! _, L7 b

2) 控制模块


, z3 d% a7 X# r7 E: g7 b5 \# r

控制模块采用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状态。

0 F" h! P" N# a: A# p2 k

4 F$ k, v3 Y" i

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


2 C2 r6 e5 Q/ U/ e, {4 h: l

6 }: T5 W; |1 ]1 x" b/ Q0 S


# {3 p# ]) L" a7 _# w


. W# n3 h: k  B5 o

0 n' Z9 j+ M3 y( X1 l

3) 数据路径

/ i$ T# j6 d% D4 S6 a1 Z8 K

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


; y# r: _7 ^/ `, _

方块:

$ L$ L, F, C3 s1 K& h3 e6 r  ?' t

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

8 R# G- [+ _3 h: \+ _) c

背景矩阵:


0 d) ]& ]; e0 s2 P( T- D

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

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

活动方块坐标:


* ~- `# l8 v6 ]: f/ U/ S6 Z

output reg [4:0] n,

output reg [3:0] m,

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

0 o5 F0 U" H+ W# c; A

方块类型:


# t7 J; T' p$ N4 z* X& j/ H2 ~# K

output reg [6:0] BLOCK,

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

数据交换:


! K% |2 e8 J2 S+ U- b; W" `0 \

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

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

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

6 p( v7 j; ^% G/ D3 N. D  k

方块模型:


) e3 u& U+ _. J7 H) O

: N' R/ E, i2 k5 }

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

" q& O( t! }7 ^) n9 k

. x) ?) V+ u* L2 K, n, S9 I+ p


+ O' @7 Y* N) p6 ~+ c


, Y0 }3 c. Y: h( f! o


$ @' n3 w6 c" ^' Z5 E

方块运动:

8 s: f1 S+ ]" g: A

产生:

# r7 R& P7 e) w" ~' A+ K$ o# A

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

移动:


, U+ k7 J4 h' V$ }3 \

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

5 q6 C9 }$ x" P2 p- w: C; w# z4 S

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


6 d. z& {4 ]; U/ O

判断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 z. T9 @! [7 B. W0 Z$ u0 f

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

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

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


/ X$ `- I+ v# }  K

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


8 E7 [. l3 T6 J& j+ R1 e

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

! D- A1 X$ i. X

死亡判定:

/ N( e' G" b3 e' R

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

4) 显示部分

0 ]; V% J( E, i. Y8 Y9 U

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

/ b2 c* K3 K- n; l0 `* i5 T

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

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

2 |$ h& M4 d+ |- o9 u

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


# f/ z; |4 m" T7 w" s% N( b3 l& S

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

5 e. [. g/ [. E, @! M4 `

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

1 S  j' g' Z4 c5 d, U) B


, k* r9 u& S9 w( @

) z) A; N* K1 J/ C* S# u

1 ^3 m# `1 Y( M1 _6 y

( f+ ^1 R7 k5 l8 c9 `

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


) `2 h! Y" r8 D3 F* p

/ C  S/ r$ d, G8 B9 U

2 _9 V& M9 A+ p" {1 ^- _. @) T1 g

设计结果

  w( P. u! {; k1 ?4 x: d8 Y

9 c4 k7 X$ }/ S% B- B. ~


* `/ T, x, x0 q0 Q/ z' Z


. P) p1 }" q  ]1 C


6 J8 l2 V* Y$ Z% _

设计代码

' }5 x* l& T) W; u9 Z3 |; b


7 d7 H( D8 Y. ~! N

2 _/ i7 f% W) G0 G. i% g- f% {+ x

由于代码量较大,这里只展示了部分代码,需要的大侠可以按照开篇介绍的方法进入“FPGA技术江湖”知识星球获取设计文档,获取设计代码。
9 T4 X2 L9 m' ~! G% G* w8 F


9 ?. P- |4 B. E  g% a# `

顶层模块设计代码:

) w9 b* k1 @8 r


. ?, X9 c: r9 A( D+ q8 ]: m5 h


! p. V4 y8 t0 Z( B& N" C


1 a$ F9 B0 D9 M9 f. X

7 Q9 v0 k& J& y4 [7 Q' D/ {

4 @$ F& T$ n. X4 c1 a! v


. E4 u. O. A2 m" G" N5 ]1 k& x


8 D# D, r9 \- i- I  u0 E9 B0 @

KeyBoard模块代码:


  q$ Q2 m1 f2 z


- y/ ?% W6 u8 V2 e6 T# d7 R


# u) T. |# v7 M( f! s# ]


) j' {# ^9 T# V


2 k% _$ A! K: r$ Q* }


' B+ B. g; m" R# y

控制模块代码:

2 V* Z- E3 X" {; y# S

, u. B! ~, z0 \( h5 V4 }% g' M


. P3 h2 T% N$ _/ k& r* B! q7 }& x) s

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


$ ?# Z- \0 u) u$ b% e

) X* I5 t/ Q& ]/ E1 O4 f; M0 n* m

6 V' O; ~! Y2 K& k5 p
您需要登录后才可以回帖 登录 | 注册

本版积分规则

关闭

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

EDA365公众号

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

GMT+8, 2025-7-19 15:36 , Processed in 0.156250 second(s), 26 queries , Gzip On.

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

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

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