
小引:
据我了解,目前国内很多大学是没有开设FPGA相关课程的,所以很多同学都是自学,但是自学需要一定的目标和项目,今天我们就去看看常春藤盟校Cornell University 康奈尔大学开设的FPGA项目课程,大部分课程是有源码的,而且和国内使用习惯类似都是Verilog开发,还是很有借鉴意义的。
项目链接
https://people.ece.cornell.edu/land/courses/ece5760/FinalProjects/
项目介绍
2024年春季 开发板:CycloneV DE1-SoC
太空射击游戏
项目介绍
本项目旨在利用DE1-SoC FPGA平台及其ARM/FPGA功能,开发一款名为“太空射击”的实时游戏。“太空射击”采用内存映射I/O技术,在VGA显示器上输出图形,并直接与硬件组件交互,实现流畅的游戏体验。玩家通过键盘输入控制飞船移动,并向屏幕上的敌人射击。游戏实时追踪玩家得分并进行碰撞检测。该实现方案注重硬件资源的高效利用、精确的动画时序控制以及有效的碰撞检测算法,以确保游戏的沉浸感和动态性。

数学背景
“太空射击游戏”项目涉及多个数学概念和技术,这些概念和技术对其开发和功能至关重要。以下是其中涉及的关键数学要素:
坐标几何:
屏幕坐标:游戏屏幕由一个坐标系定义,其中左上角为 (0,0),x 轴向右递增,y 轴向下递增。玩家和敌人的位置均使用 (x, y) 坐标进行追踪。 移动:玩家的飞船和子弹通过更新其 (x, y) 坐标来移动。例如,按下“a”键会减小飞船的 x 坐标,使其向左移动。
碰撞检测:
边界框碰撞检测:子弹与敌人之间的碰撞检测基于轴对齐边界框(AABB)碰撞检测。该算法检查两个物体的边界框是否重叠。 子弹要击中敌人,必须满足以下条件:
子弹.x ≤ 敌人.x + 敌人.size
子弹.x + 子弹.size ≥ 敌人.x
子弹的 y 轴 ≤ 敌人的 y 轴 + 敌人的大小
子弹.y + 子弹.大小 ≥ 敌人.y
向量数学:
方向和速度:子弹的运动涉及对其 y 坐标进行固定量的更新,从而模拟运动。这可以用向量加法表示:
子弹的 y 坐标 = 子弹的 y 坐标 - 子弹速度
该公式确保子弹以恒定速度向上运动。
时间安排和延误:
帧率控制:游戏循环中包含一个延迟来控制帧率,以确保动画和游戏运行流畅。延迟通过 usleep函数设置:`
usleep(100000)`。
这将提供 100 毫秒的延迟,从而实现大约每秒 10 帧的帧率。
几何变换:
缩放和平移:敌人的位置会进行缩放和平移,以创建不同的移动模式。例如:
`enemys[i].px = *(enemy_pos_x_ptr) + 20 × i`
此公式调整每个敌人的 x 坐标,从而在它们之间创建间距。更进一步的变换涉及修改敌人位置的条件,以实现更复杂的移动。
圆形几何:
绘制圆: VGA_disc函数使用圆的方程来绘制敌人和玩家的子弹。对于一个以 (x, y) 为圆心、半径为 r 的圆,所有满足以下条件的点 (px, py):( px − x)^2 + (py − y)^2 ≤ r^2
都是该圆的一部分。
评分和时间跟踪:
得分计算:玩家每击中一个敌人,得分增加100分,计算公式为:
得分 += 100
时间测量:游戏开始至今所经过的时间使用 gettimeofday函数计算,该函数提供当前时间(以秒和微秒为单位)。已用时间计算公式为:
time_used = end.tv_sec − start.tv_sec
摘要:《太空射击》游戏融合了这些数学原理,打造出引人入胜、动感十足的游戏体验。从用于运动和碰撞检测的坐标几何和向量数学,到用于流畅动画的时序控制,这些数学概念构成了游戏实现的核心。

RTL设计

这个项目基于 FPGA 实现了一个完整的《太空射击游戏》,核心由 VGA 控制器、游戏对象位置更新、碰撞检测、计分以及 HPS 软件控制组成。VGA 控制器负责根据当前游戏状态生成图像,并通过并行处理和组合逻辑完成像素绘制、坐标及颜色计算;玩家和敌人的位置则根据输入、速度和预设运动模式实时更新,同时加入边界检测,保证游戏对象始终处于有效区域。

在游戏逻辑方面,项目采用边界框碰撞检测判断玩家、敌人和子弹之间的重叠,并在碰撞发生后同步更新敌人状态、子弹状态以及玩家得分。系统还通过内存映射 I/O将 VGA 字符/像素缓冲区以及敌人位置寄存器映射到 HPS 地址空间,使软件能够直接访问 FPGA 硬件;键盘输入由独立线程处理,主游戏循环则负责统一协调位置更新、碰撞检测、计分和画面渲染,并通过定时机制维持稳定的游戏帧率。
HPS太空射击游戏设计
在“太空射击游戏”中,HPS 主要负责用户交互和游戏状态管理。玩家可以通过键盘控制飞船移动、发射子弹,以及启动、暂停和重置游戏,同时实时显示分数和游戏时间。HPS 通过 GPIO 和内存映射 I/O 与 FPGA 硬件进行通信,读取和更新玩家、敌人的位置以及 VGA 显示内容;键盘输入则由独立线程处理,保证游戏能够及时响应。整体上,HPS 负责输入、控制和状态管理,FPGA 负责图形渲染和实时游戏逻辑,两者共同完成完整的游戏系统。
结果与测试
为了验证“太空射击游戏”项目的功能和性能,记录了系统运行的各个方面并收集了性能指标。虽然照片本身无法完全展现实现的有效性,但我们提供了一些关键图片来说明具体结果。演示视频位于页面的演示部分。
视频和图片展示了游戏的主要特色,包括:
实时玩家移动和控制 子弹发射和碰撞检测 敌方行动与互动 得分和时间跟踪
这些要素突显了系统实时处理输入和更新游戏状态的能力,从而确保流畅且引人入胜的用户体验。






项目链接
https://people.ece.cornell.edu/land/courses/ece5760/FinalProjects/s2024/hgh36_kd496_ma2339_lz566/hgh36_kd496_ma2339_lz566/project.html
代码链接
https://people.ece.cornell.edu/land/courses/ece5760/FinalProjects/s2024/hgh36_kd496_ma2339_lz566/hgh36_kd496_ma2339_lz566/project.html_a
视频链接
https://youtu.be/1R6PA-tOjBY?si=Qba0tM9Vm2tj8DE-
格子玻尔兹曼钓鱼游戏

在这个项目中,构建了一个基于流体模拟的钓鱼游戏,并在 Dec1-Soc 开发板上使用两种不同的硬件加速方案实现了该游戏。使用格子玻尔兹曼算法对流体进行建模,因为它能够很好地近似流体物理特性,并且易于在 FPGA 上并行化。本项目的主要挑战在于为流体模拟创建一个硬件加速器,使其更接近实时,更适合游戏玩法。两种加速器分别实现了 1.2 倍和 53 倍的加速,而资源限制因素是内存。
数学背景
格子玻尔兹曼算法的开发是为了替代传统的计算流体动力学(CFD)方法。传统的CFD方法通常通过求解纳维-斯托克斯方程来模拟流体物理,而格子玻尔兹曼算法的出现是为了加快模拟速度,缩短模拟时间。在该算法中,流体被假定为由虚拟粒子组成的网格,这些粒子执行两种操作:流动和碰撞。这些虚拟粒子与9个密度相关联,这些密度量化了粒子密度在未来处于9种可能状态之一的趋势,每种状态代表一个可能的运动方向,即北、南、东、西、西北、东北、西南、东南和零(静止粒子)。
在流的过程中,这些密度会沿着与其相关的方向在晶格中传播,即,一个粒子的东向密度会复制到它右边粒子的东向密度,西向密度会复制到它左边粒子的西向密度,依此类推,如下图所示。

这种行为可以用数学公式描述如下:

在碰撞过程中,经过粒子流处理后得到的9个新的密度值会在每个粒子中进行调整,以保持质量和动量守恒。这种行为的数学描述如下:

这个项目采用 ARM + FPGA 异构架构实现流体模拟游戏。ARM 主要负责游戏运行、用户输入和任务调度,FPGA 则将计算量较大的碰撞运算、流式处理、飞船移动和 VGA 颜色更新等任务硬件化。项目还采用 2.25 定点格式表示振幅数据,在精度、DSP 和存储资源之间进行权衡。

项目重点比较了两种加速方案。第一种方案使用片外 SDRAM 存储较大的晶格,ARM 负责流式处理,仅将碰撞计算卸载给 FPGA,优点是能够支持更大的游戏区域、代码也相对简单,但串行内存访问和 ARM-FPGA 通信带来了明显开销。第二种方案则将密度、速度和颜色数据全部放入 FPGA 的 M10K 中,并通过多个 FSM 分别执行初始化、碰撞、流式传输、飞船移动和 VGA 更新,ARM 只负责调度。最终,第二种硬件化方案相比 ARM 实现获得了约 53 倍加速,主要得益于片上 SRAM 更快的访问速度、13 个 M10K 的并行访问以及 FPGA 内部的并行计算。由于加速效果过于明显,系统甚至需要在 ARM 端人为加入 1000 μs 延迟来控制游戏速度。

资源利用
加速器 1

加速器2


项目链接
https://people.ece.cornell.edu/land/courses/ece5760/FinalProjects/s2024/sa2236_qx95/5760website_sa2236_qx95/index.html
代码链接
https://github.com/Siddhant-Ahlawat/fluid-simulation-accelerator-based-on-lattice-boltzmann-algorithm.git
视频链接
https://youtu.be/kUcm6xsBcNg?si=E3R3DcPeYqBmT60x
FPGA 数独谜题 求解器
利用FPGA解决数独难题,并配以简洁优雅的用户界面,使用户能够与数独网格进行交互。选择这个项目是为了充分利用FPGA的快速处理能力,为数独爱好者打造一个引人入胜的互动平台。数独不仅能带来娱乐,还能提升解决问题和批判性思维等认知能力。
在我们的实现方案中,用户可以通过鼠标和键盘控制数独网格。利用FPGA上的回溯算法高效地求解数独。片上CPU在FPGA的辅助下,将数独网格显示在VGA屏幕上,使用户能够输入数字并直观地查看数独结果。FPGA实时处理求解过程,更新网格并提供即时反馈。
数独是一种广受欢迎的数学游戏。最基本、最广为人知的数独游戏由一个 9×9 的方格组成,部分方格中已预先填入数字。游戏的目标是填满剩余的方格,使每一行、每一列以及九个 3×3 的子方格都恰好包含数字 1 到 9 各一次。解题的关键在于利用方格中已有的数字作为线索来推断可能的解法。下图展示了一个世界上最难的数独谜题示例。它极具挑战性,因为只有一个解,而谜题提供的线索却非常有限。


顶层设计
这个项目是一个基于 FPGA 的数独游戏/求解器,通过 HPS、FPGA 和 VGA 显示组成完整的互动系统。HPS 负责将数独题目发送到 FPGA,同时通过 VGA 界面将题目和求解过程呈现给用户;FPGA 内部则由控制单元、更新单元和检查器协同工作,对数独进行自动求解。

在求解过程中,系统采用经典的回溯算法,从空白单元格开始依次尝试 1~9,并检查数字是否满足行、列以及 3×3 子网格的约束。如果当前选择无法继续得到有效解,就回退到之前的单元格尝试其他数字,直到找到完整解或确定无解。硬件设计中使用 81 个寄存器保存数独网格,并额外保存待更新的空白单元格信息,在硬件资源和求解效率之间进行了权衡。整体来看,该项目将数独游戏、VGA 可视化、FPGA 硬件求解和 HPS 控制结合起来,展示了 FPGA 在逻辑搜索类应用中的硬件加速能力。
硬件设计
这部分主要介绍了数独求解器的硬件结构和模块之间的协同方式。整个设计由控制单元、数独寄存器、更新器和检查器四个核心模块组成:控制单元负责协调各模块的工作流程,数独寄存器保存 81 个单元格的当前状态,更新器负责根据回溯过程修改数独数据,而检查器则负责判断当前填入的数字是否满足行、列和 3×3 宫的约束。通过这种模块化设计,可以将数独求解过程拆分成明确的硬件功能单元,并分别进行设计和测试。

其中,HPS 与 FPGA 之间通过 Qsys 端口进行通信,HPS 负责将数独题目送入 FPGA,同时 FPGA 将求解过程中的状态通过相应接口进行交互。更新器和检查器之间不断传递控制信号,形成“更新 → 检查 → 回溯 → 再更新”的求解流程;数独寄存器则作为核心数据存储区域,为整个求解过程提供状态保存。整体结构体现了将传统软件回溯算法拆解成 FPGA 中多个硬件模块的设计思路,从而实现数独的硬件化求解。

软件设计与实现
这一部分主要介绍数独游戏的 HPS 软件设计和 FPGA 通信流程。系统基于 DE1-SoC 的 ARM Cortex-A9 HPS 运行 Linux 和 C 程序,负责 VGA 界面绘制、鼠标键盘输入以及游戏状态管理。软件通过外部 SDRAM 作为 VGA 帧缓冲区,并使用 drawPixel、drawLine、drawRectangle、drawDisk 等函数完成数独网格和数字的显示,同时通过 USB 鼠标和键盘实现类似纸笔操作的交互方式。用户可以在网格中输入、删除数字,并在用户模式和 FPGA 求解模式之间进行切换。



在 FPGA 模式下,HPS 通过 Qsys 端口将 81 个数独单元的数据逐个发送到 FPGA,并通过启动和完成信号控制数据传输;FPGA 完成求解后,再由 HPS 根据状态信号读取结果,并将最终数独重新显示在 VGA 屏幕上,同时显示 FPGA 的处理时间。整个软件采用持续运行的主循环,不断处理鼠标、键盘输入并刷新 VGA 画面,从而形成完整的“用户输入 → HPS 管理 → FPGA 求解 → HPS 读取结果 → VGA 显示”交互流程。
资源使用情况
该图显示了我们使用的所有资源。

下图展示了我们求解器的芯片规划器。图中展示了所有可用资源,深蓝色区域突出显示了当前正在使用的资源。值得注意的是,可用资源非常丰富,这表明有足够的空间进一步实现并行求解器。这一发现提示我们,通过利用额外的并行处理能力,可以提高求解器的效率和可扩展性。


项目链接
https://people.ece.cornell.edu/land/courses/ece5760/FinalProjects/s2024/kg535_yl3726_dt538/kg535_yl3726_dt538/index.html
代码链接
https://github.com/dengyutu/CU-Project-FPGA-Sudoku-Solver
视频链接
https://youtu.be/6yiWjeeNqF0?si=CDAxelN73wC2PzB9
总结
本文整理了康奈尔大学 2024 年春季 ECE5760 课程基于 CycloneV DE1-SoC 开发板的 3 个 FPGA 实战项目,全部采用 Verilog 开发,具体项目如下:
《太空射击游戏》:本项目基于 DE1-SoC 平台实现了一款完整的 FPGA 实时射击游戏,通过 ARM HPS 与 FPGA 协同完成用户交互、游戏逻辑和 VGA 图形显示。HPS 运行 C 程序负责键盘输入、游戏状态管理、得分与时间统计,并通过内存映射 I/O 与 FPGA 进行通信;FPGA 则负责 VGA 像素绘制、玩家与敌人位置更新以及碰撞检测等实时任务。项目采用坐标几何、AABB 边界框、向量运动和定时控制等方法实现游戏机制,同时利用并行处理和组合逻辑提高硬件执行效率,最终实现了玩家移动、射击、敌人交互和实时计分等功能。
格子玻尔兹曼钓鱼游戏:本项目基于 DE1-SoC 平台,将格子玻尔兹曼方法(LBM)应用于流体模拟游戏,并探索了 ARM+FPGA 两种不同的硬件加速方案。第一种方案主要由 ARM 负责流式计算,仅将计算量较大的碰撞操作卸载到 FPGA;第二种方案则进一步将密度、速度和颜色数据存储到 FPGA 的 M10K 片上存储器中,并通过多个 FSM 对初始化、碰撞、流式传输、飞船移动和 VGA 颜色更新进行硬件化处理。最终,第二种方案相比 ARM 实现获得了约 53 倍加速,体现了片上 SRAM 高速访问、多 M10K 并行读写以及 FPGA 并行计算在流体模拟中的优势,同时也展示了 FPGA 在实时物理仿真和游戏加速方面的应用潜力。
FPGA 数独谜题求解器:本项目将经典数独游戏与 FPGA 硬件求解相结合,基于 DE1-SoC 的 ARM Cortex-A9 HPS、FPGA 和 VGA 显示构建了一个完整的交互式数独平台。HPS 运行 Linux 和 C 程序,负责 VGA 界面绘制、鼠标键盘输入以及数独数据管理,用户可以像在纸面上解题一样输入和修改数字;FPGA 内部则由控制单元、数独寄存器、更新器和检查器组成,通过回溯算法不断尝试数字,并检查行、列和 3×3 子宫的约束,直到找到有效解。HPS 与 FPGA 之间通过 Qsys 端口进行数据交换,最终形成“用户输入—HPS 管理—FPGA 求解—结果回传—VGA 显示”的完整流程,展示了 FPGA 将传统搜索算法进行硬件化实现的思路。
- -THE END- -
往期精选


FPGA技术江湖广发江湖帖
无广告纯净模式,给技术交流一片净土,从初学小白到行业精英业界大佬等,从军工领域到民用企业等,从通信、图像处理到人工智能等各个方向应有尽有,QQ微信双选,FPGA技术江湖打造最纯净最专业的技术交流学习平台。
FPGA技术江湖微信交流群

加群主微信,备注姓名+学校/公司+专业/岗位进群
FPGA技术江湖QQ交流群

备注姓名+学校/公司+专业/岗位进群
