当我们谈论现代电子设计时,FPGA、ASIC 和微控制器已经成为实现数字逻辑的默认选择。然而,MIT 旗下硬件工程师 schilk 在其个人项目「Fets & Crosses」中完成了一项令人惊叹的工程壮举 —— 使用 2458 个分立 MOSFET 从零构建了一个完整的 Tic-Tac-Toe(三子棋)游戏系统。这个项目不仅包含了人人对战和人机对战两种模式,更实现了一个基于纯组合逻辑的完美游戏 AI,整个设计过程与现代 IC 设计的 workflow 有着微妙的相似之处。
从逻辑仿真到硬件实现
整个项目的起点始于一个看似简单的想法:用最基础的电子元器件实现一个完整可玩的游戏。设计者在数字设计课程期间使用 Logisim 图形化逻辑仿真器进行了前期验证,设计出了一个能够检测所有可能的获胜和平局状态、具备落子验证功能的三子棋游戏。这个仿真版本同时支持双人对战和单人挑战计算机模式。
在软件仿真阶段,工程师首先使用并行输入输出的 ROM 作为大型查找表来实现游戏 AI。游戏的当前棋盘状态被作为 18 位地址输入 ROM,引擎的落子选择直接从存储器中读取。这种方法虽然能够工作,但效率极低 —— 因为所有可能的输入中只有不到 5% 对应实际有效的游戏状态。随后,设计者将实现方式替换为纯组合逻辑门模块,在不使用任何存储元件的情况下实现了完美游戏能力。
最终的硬件电路比最初预想的要简洁得多。整个系统只需要 19 个触发器 —— 其中 18 个用于存储当前游戏状态,1 个用于跟踪当前玩家。基于这个估计,使用 CMOS 工艺构建大约需要 2000 个晶体管。当实际完成时,最终使用了 2458 个分立 MOSFET,其中约 1074 个专门用于游戏引擎的组合逻辑部分。
基本单元库的设计方法论
与现代 IC 设计的理念类似,该项目采用了自底向上的设计方法。首先,设计者在 KiCad 中创建了一组基本逻辑单元,每个单元都包含在分层原理图页面中。以最基本的非门为例,它由两个 MOSFET 组成 —— 一个 P 沟道型和一个 N 沟道型,以 CMOS 反相器结构呈现。
在单元库建立之后,更复杂的逻辑门通过组合这些基本单元来构建。例如,一个两输入的与门实际上是由一个与非门和一个非门串联而成。这种构建方式遵循了标准 CMOS 逻辑设计的最佳实践,尽管设计者也承认效率和合理性并非首要考虑因素 —— 他在项目中明确表示「我确信可能有更高效的触发器设计或更少晶体管的实现方式,尤其是通过构建复合门来组合与非门和或非门,但我并不在意」。
完成基本单元库后,设计者使用分层原理图页面重新绘制了逻辑电路,而不是使用单独的组件。这种方法与实际 IC 布局设计中的流程类似 —— 每个基本单元布线一次,然后通过布局复制插件将布局应用到该门的所有实例。在完成所有单元的布局后,剩下的工作就是组装和布线所有单元之间的连接。
双 PCB 模块化架构
整个系统被划分为两个独立的 PCB 模块。主板承载用户界面、电源调节电路、基于 555 定时器的时钟源,以及除游戏引擎之外的所有逻辑电路。主板上留有一个大型 FLASH 存储器的插槽,该存储器可以像最初设计那样作为游戏引擎使用。另一种方案是将基于晶体管的引擎板通过一排排针连接到主板上。
两个 PCB 都采用双层板设计,布线采用曼哈顿风格 —— 顶层用于所有晶体管封装和垂直布线,底层用于水平布线。这种正交布线策略大大简化了布线和信号完整性的管理。设计者还特别开发了一个真空吸取笔工具来加速元件贴装过程,由于所有晶体管在板上共享相同的取向,贴装效率相当可观。
这个项目经历了三次修订才最终正常工作。设计者提到,在手工焊接过程中 PCB 加热不均匀导致板子产生翘曲,原型机在使用几周后会因为张力拉断焊点而随机出现故障。最终,他投资生产了五套主板和引擎板的组装件,以确保可靠性和一致性。
完美游戏 AI 的硬件实现
游戏引擎的实现是整个项目最引人注目的技术亮点。由于 Tic-Tac-Toe 是一个极其简单的博弈游戏,实现完美玩法非常直接。工程师将其描述为一个长的 if-else 语句,按照优先级依次检查各种棋局状态并选择第一个合理的落子。
具体来说,硬件实现中每个检查都对应一个简单的「决策门」,当其对应的特定棋局状态被检测到时激活。一旦某个决策门触发,它会阻塞所有后续决策门,防止多个落子决策同时产生。
决策门按照以下优先级顺序排列:首先是检查是否能在某行获胜(9 个门),然后是检查是否能在某列获胜(9 个门),接着是检查是否能在对角线获胜(6 个门)。完成这些进攻性检查后,系统转而进行防御性判断:阻止对方在某行连成(9 个门)、阻止对方在某列连成(9 个门)、阻止对方在对角线连成(6 个门)。之后是防止对方形成分叉(3 个门),最后是占据策略性位置 —— 如果中心空则占中心(1 个门)、如果对方占了角落且对角角落空则占对角角落(4 个门)、如果角落空则占角落(4 个门)、最后才是占边(4 个门)。
分叉是指玩家在两个不同的位置都有机会获胜的情况。精确的防分叉决策取决于决策门的具体顺序,设计者的实现只需要 3 个防分叉门就能完全消除被对方利用分叉策略击败的可能性。
值得注意的是,由于在 CMOS 工艺中构建反相逻辑(与非门和或非门)所需的晶体管更少,决策门连接的输入信号采用反相形式(低电平表示条件为真)。每个门的 block 输入连接到前一个决策门,当为高电平时禁止该门激活;block 输出连接到下一个决策门,当该门或前面的门触发时置位,锁定后续所有门。
验证与测试
作为最终验证步骤,工程师实现了一个基于 STM32 的小型测试平台,将游戏引擎连接到 PC。他还开发了一个 Python 脚本,该脚本能够与引擎对弈所有可能的 Tic-Tac-Toe 局面(虽然数量不少,但总数是有限的),并确认引擎在所有情况下都不会失败 —— 这意味着它确实实现了完美游戏。
这个项目展现了硬件工程中模块化设计、层次化验证和实际制造之间复杂而微妙的关系。虽然在今天看来使用数千个分立晶体管来实现一个简单的游戏似乎是不切实际的,但它为理解数字系统的本质提供了宝贵的实践视角,也为硬件设计教育提供了独特的教学案例。