基于 Basys3 教学 FPGA 开发板的俄罗斯方块游戏。某大学的数字逻辑课程实验项目。
-
基本机制:
- 地图尺寸:标准的 10列 × 20行 网格。
- 方块类型:包含 7 种标准俄罗斯方块(I, J, L, O, S, T, Z),通过 LFSR(线性反馈移位寄存器)随机生成。
- 游戏结束:当新生成的方块在出生点直接发生碰撞时,游戏结束。
-
操作方式:
- 左右移动:控制方块水平位移。
- 旋转:控制方块顺时针旋转 90 度。
- 自然下落:方块受重力影响自动下落,速度可通过开关调节(默认 2Hz,加速模式 4Hz)。
- 硬降 (Hard Drop):按下“下”键,方块瞬间掉落到最底部并锁定。这是本项目的一个高级特性。
-
消除与得分:
- 行消除:当一行被方块填满时,该行消除,上方的方块整体下移。
- 计分规则:消除行数越多得分越高,公式为
消除行数² × 100。分数通过数码管实时显示。
整个系统采用模块化设计,数据流清晰,主要包含以下几个子系统:
-
时钟与复位系统:
- 输入时钟为 100MHz。
- 通过
clk_vga_divider生成 25.175MHz 的 VGA 像素时钟 (clk_vga),作为游戏逻辑和 VGA 显示的主时钟。 - 通过
clock_divider生成 1kHz 时钟 (clk_1khz),用于数码管动态扫描。 - 通过计数器逻辑生成重力时钟使能信号 (
grav_ce),控制方块自动下落速度(默认 2Hz,可加速至 4Hz)。 - 全局异步复位 (
rst)。
-
输入处理系统:
- 按键消抖:使用
debounce模块对上、下、左、右四个物理按键进行消抖处理,输出干净的信号 (*_clean) 给游戏逻辑。 - 速度调节:通过
adjust开关实时调节重力下落速度。
- 按键消抖:使用
-
游戏核心逻辑系统 (
tetris_logic):- 这是系统的“大脑”,负责维护游戏状态、处理用户输入、执行游戏规则。
- 状态机 (FSM):使用有限状态机管理游戏流程,包括初始化 (
INIT)、生成方块 (SPAWN)、下落 (FALLING)、着陆 (LANDED)、消除行 (CLEAR LINES) 和游戏结束 (GAME OVER)。 - 数据存储:使用二维数组
gm_memory[19:0][9:0]存储 20x10 的游戏网格状态。 - 随机数生成:使用 LFSR (线性反馈移位寄存器)
lfsr_galois_3bit生成伪随机数,决定下一个方块的类型。
-
显示输出系统:
- VGA 显示:
vga_controller:生成 VGA 时序信号 (HSYNC, VSYNC) 和当前像素坐标 (x_pos, y_pos)。block_renderer:根据当前像素坐标和游戏网格数据 (game_grid_array),计算当前像素的 RGB 颜色值。
- 数码管显示:
score_display:接收游戏分数 (score),将其转换为数码管的段选和位选信号,实时显示得分。
- VGA 显示:
-
硬降 (Hard Drop) 功能:
- 实现了“硬降”逻辑,即按下“下”键后,方块瞬间掉落到底部。
- 实时计算:为了实现硬降,设计了一个纯组合逻辑电路来实时计算当前方块到底部的距离 (
drop_distance)。 - 并行检测:利用
get_column_distance函数并行计算方块每一列下方的障碍物距离,通过位掩码和优先级编码器替代了传统的循环查找,极大地提高了硬件效率,能够在一个时钟周期内得出结果。 - 防抖与时序优化:对硬降按键进行了额外的消抖处理,并优化了状态机逻辑,确保硬降操作的原子性和优先级,防止了“空中悬停”或“双重掉落”等时序问题。
-
碰撞检测:
- 实现了
check_collision函数,能够检测方块在移动、旋转或下落时是否会碰到边界或已存在的方块。
- 实现了
-
行消除算法:
- 在
CLEAR LINES状态中,采用了一种“双缓冲/顺序复制”的策略。先创建一个空网格,然后扫描旧网格,只将未填满的行复制到新网格中,从而实现消除满行并让上方方块下落的效果。
- 在
-
显示渲染:
- 游戏逻辑输出的
grid信号是包含了已固定方块和当前活动方块(动态叠加)的完整画面,简化了渲染模块的逻辑,渲染器只需根据坐标查表即可。
- 游戏逻辑输出的
-
纯硬件逻辑设计:
- 没有使用软核处理器(如 MicroBlaze 或 Nios II),所有的游戏逻辑、渲染、控制完全由 SystemVerilog 描述的数字逻辑电路实现。
- 核心控制采用 有限状态机 (FSM),清晰地划分了
SPAWN(生成)、FALLING(下落)、LANDED(着陆)、CLEAR(消除)等状态。
-
模块化架构:
- 逻辑与显示分离:
tetris_logic模块只负责维护游戏数据(网格状态、坐标),vga_controller和block_renderer负责将数据转换为图像信号。这种解耦设计使得逻辑修改不影响显示驱动。
- 逻辑与显示分离:
-
伪随机数生成:
- 使用 Galois LFSR 算法生成伪随机序列,相比传统的计数器取模,能提供更好的随机性,保证方块出现的不可预测性。
本项目采用 BSD 3-Clause 许可证,详情请参阅 LICENSE 文件。