大多数硬件爱好者入门 custom CPU 设计时,会选择直接购买现成的 FPGA 开发板,在现成平台上编写 Verilog 代码 Petr Mikheev 选择了另一条路:先买一把烙铁,从电子设计开始。他的目标是构建一台能够启动 Linux、连接显示器和键盘、运行 Quake II 的自定义计算机。两年后,他做到了。
从零开始的硬件冒险
项目始于几乎为零的电子设计经验。Petr 在 KiCad 中完成了整个 PCB 设计,将文件发往中国工厂制造,随后在家自行焊接全部元件。这种「从沙子到游戏」的完整流程,意味着每一颗电容、每一根走线都必须亲自考量。
第一代原型使用 Intel MAX 10 系列 FPGA(10M50SAE144),搭配单片 DDR1 内存。FPGA 芯片只有单个 PLL,这对于需要多组时钟的系统来说是致命的缺陷:视频接口需要 pixel_clock 和 bit_clock,USB 需要 48MHz,内存控制器需要两组 90° 相移时钟,CPU 时钟尚未确定。为解决这一问题,板上配备了两颗 Si5351A 芯片 ——I2C 可编程时钟发生器,可以按需产生任意频率的时钟信号。
硬件布局的关键决策是将 FPGA 和 RAM 放置在 PCB 两侧,以缩短信号走线长度。这一技巧借鉴自 WangXuan95 的开源 DDR1 控制器项目,尽管 Petr 最终重写了大部分代码,但这个思路大幅降低了信号完整性问题的复杂度。
SoC 架构:从 AXI4 到 TileLink
硬件之外的另一条战线是 SoC 设计。初期版本使用 AXI4 总线连接各外设,随后迁移到 TileLink 协议栈。CPU 核心从 VexRiscv 升级到更高性能的 VexiiRiscv,这是一款面向 RISC-V 架构的乱序执行处理器核。
移植过程并非一帆风顺。最具挑战性的 bug 之一是 gcc 编译时触发的死锁问题。Petr 花了三个月时间追踪这个问题,最终将整个系统缩减到 40MB 的 initrd 镜像,创建了一个不含外设的精简测试平台,并在 Verilator 仿真环境中复现了该缺陷。问题定位后,发现是 VexiiRiscv 核心中的一个真实 bug,修复仅需一行代码 —— 提交给维护者后,三十分钟内得到修复。
另一个持久战是 USB OHCI 实现的调试。来自 SpinalHDL 仓库的 OHCI 代码始终无法正常工作,最终发现是内存控制器中对齐访问处理不当导致的。这一问题在纯软件仿真中难以暴露,必须在实际硬件上反复测试才能定位。
软件栈:没有依赖的纯粹代码
对于在工作中常年与各种框架周旋的工程师来说,从零编写 BIOS 是一种「解毒」。Petr 的 BIOS 从头编写,除了集成的 Dhrystone 基准测试外,不依赖任何外部库。功能包括系统初始化、内存测试、RISC-V SBI 标准接口实现、命令行界面、EXT2 文件系统支持,以及 Linux 启动加载程序。
Linux 部分同样体现了深度定制思路:自定义外设驱动、自定义 X11 视频驱动(包含窗口移动的硬件加速),甚至还有完整的 TTY 实现 —— 接收 ncurses 生成的 ANSI 转义序列,将其转换为视频控制器的文本模式输出。这些工作如果使用现成的 SoC builder 工具如 LiteX 可以大幅简化,但随之失去的,是整个过程中积累的深度理解。
视频输出与分辨率瓶颈
第二代硬件在 1280x720 分辨率下出现了恼人的绿色伪影。问题根源很可能是 I/O 端口在 742MHz 数据率下驱动能力不足,亦或电源噪声干扰了高速信号。降低分辨率后问题消失,但这也意味着在现有硬件上无法达到 Full HD 的游戏体验。
电源稳定性是另一个隐患。热插拔 USB 键盘经常导致整个开发板重启,这表明 USB 电源设计存在缺陷。后续版本中需要加入更好的电源隔离和缓启动电路。
Quake II 移植:工程化的最后一步
将 Quake II 移植到这台自研计算机上,是整个项目的集大成者。游戏引擎需要稳定的帧缓冲、合理的 GPU 类渲染管线、同步的时钟输入,以及足够的内存带宽。60MHz 运行的单核心 VexiiRiscv 编译一个简单的「Hello World」需要约十秒 —— 这个性能指标并不亮眼,但足以运行近三十年前的游戏。
最终,Quake II 成功在这块 DIY FPGA 开发板上运行。完整的代码、原理图和 Gerber 文件已在 GitHub 上开源。
可复用的工程参数
对于计划进行类似 DIY FPGA 游戏移植的开发者,以下参数可作为初始参考:FPGA 选择逻辑单元数大于 25K 的型号,以确保能够容纳 CPU 核心、内存控制器和视频输出模块;DDR 内存至少 32MB 以满足游戏引擎的纹理和场景数据需求;时钟发生器建议至少配置两组独立可编程源,分别供给 CPU 和视频路径;视频输出设计时优先选择支持 DDR 模式的 I/O 引脚,并在 PCB 布局中严格控制阻抗匹配;若计划运行 Linux,CPU 频率建议不低于 50MHz,并预留至少 64MB 系统内存。
这个项目的意义不在于实用价值 ——FPGA 上的 CPU 永远比不过真正的芯片 —— 而在于过程本身。从原理图到操作系统,从空白芯片到可玩游戏的完整链路,是对现代计算底层机制的彻底实践。当你在自研硬件上看到 Quake II 启动画面时,那十秒钟的等待便值得了。
资料来源:Petr Mikheev 的技术博客详细记录了完整开发历程,GitHub 仓库提供全部源代码与硬件设计文件。