在 B 站当 UP 主,门槛是出了名的高。
有人会用 AI 还原朱元璋,有人能造自动驾驶自行车,还有人会手搓 CPU……
从外形来看,这个 CPU 采用了先进的「3D 堆叠」技术(手动狗头),全部由三极管、二极管和电阻焊接而成。
具体来说,UP 主林乃卫大约用了 1000 多个三极管、2000 多个二极管和 2000 多个电阻,焊点达到上万个,网购材料大约花了 1000 多块钱。
为了打造这款 CPU,UP 主花了大半年的时间逐点焊接,人送外号「焊武帝」。
由于其体型巨大,网友开玩笑说,「这是当年的巨型计算机啊。」连作者本人也调侃说,它的制程是 2.54mm,「比先进的 3 纳米大了将近 1 百万倍。」
不过,比外形更古朴的是 UP 主的编程方式:由于指令集和架构都是自主开发的,还没有适配任何编程语言,因此他选择采用二进制编程,也就是原始的机器语言——0 和 1。
这个「庞然大物」运行起来的效果也很炫酷:
有人说,「我看不懂也没怎么震撼,但这就是我小时候想象中的『科学家』,稀奇古怪的仪器和五颜六色的灯泡,拿各种五颜六色的液体互相勾兑,然后产生各类超强的氧化反应。」
我们知道,要自制这么一个 CPU,除了熟练掌握数电、模电、汇编等基础知识,还要具备超强的动手能力和毅力。其过程之艰辛普通人可能难以体会。那么,林同学为什么要费这么大工夫去做呢?
「在写代码时要分析可执行文件中的二进制,那时候在想,CPU 是怎么执行这一串 0101 的呢?结合数电课程,猜测大概是那么回事,就想试一试。当初想用门级电路来做的,但是感觉难度不是很高,想整个从零开始理解透,就从最基础的模拟电路开始搭建了。」林同学告诉机器之心。
当然,当 UP 主只是林同学的爱好之一,他的本职工作是 php/.net / 安卓 APP 程序员。他表示自己喜欢学习各种新科技,对高难度的技术有较强的动力去学习,有许多新奇的创意,却没资金去实现。在这次 B 站大火之后,希望林同学能有更多的资金去实现自己的创意。
一位 B 站 UP 主的手搓 CPU 之路
虽然打造这款 CPU 只用了半年,但林同学透露,它的原理图几年前就画好了,大概是这样:
图源:https://tieba.baidu.com/p/7432882849?see_lz=1
画完图,Up 主首先验证了门电路。这一步属于理论验证,是必要的步骤。
图源:https://tieba.baidu.com/p/7432882849?see_lz=1#140122397516l
做好验证之后,手搓的部分就正式开始了。CPU 通常由通用寄存器组、运算器、控制器和数据通路等部件组成。Up 主首先就从寄存器做起。
他先造了一个移位寄存器——一种在若干相同时间脉冲下工作的以触发器级联为基础的器件,用 Up 主的话说就是数据从一个方向进,一个时钟周期移动一个位置,最后从另一个方向出。最终 Up 主的成品是 6 位的移位寄存器:
有网友提问:「为什么移位寄存器不用现成的芯片?」Up 主表示「为了乐趣」。
图源:https://tieba.baidu.com/p/7432882849?see_lz=1#140122397516l
接着,Up 主手搓的第二个 CPU 部件是程序计数器(PC)。PC 是控制器的一部分,涉及的功能较多,也是手搓阶段最复杂的一个模块。CPU 重启时要将它的计数清零,工作状态下要借助 PC 实现挨个字节读取指令和数据,每操作一次,计数自动加一,同时还要实现直接跳转、调用函数,函数返回的功能,因此 PC 的构建过程比移位寄存器要复杂和困难得多。
尤其是 Up 主采用「纯手搓」——焊接的过程也会遇到一些虚焊的麻烦,找出问题并解决花费了 Up 主大量时间和精力。其中有一次一个二极管焊反了,Up 主排查了 3 天。
不过,最后的成品很优秀,上电测试也成功通过:
CPU 中还有两个关键的部分——ROM 和 RAM,不过这两个部分手搓不太现实,Up 主选择用 hm628512 来组装 ROM 和 RAM。
然后 Up 主开始构建指令译码器,用来解析 CPU 指令以运行,它也是控制器的一部分。
最后还有两个要组装的部件:运算器(ALU)和通用缓存。
至此,CPU 中寄存器、控制器、运算器等主要部件已经完备,一个手工焊接的 CPU 就基本做成了!
搓出来了,怎么运行?
由于这个 CPU 是 Up 主自己手搓的,全部是由二级管、三极管和电阻焊接而成,因此没有现成的指令集和编程语言能够使用。那这样的 CPU 怎么跑起来?回归最原始的二进制吧。
二进制在计算机工作机制中属于最底层的基础原理,对于计算机专业的同学来说并不陌生,但用二进制直接编程就不是所有人都能掌握的技能了。UP 主正是借助二进制编程让手搓的 CPU 跑了起来。
有了二进制码,怎么输入机器?Up 主自己上手「扣」代码,真 · 手敲代码。目前有三条指令,包括内存赋值指令、内存地址左移指令和跳转指令。Up 主编写了一个流水灯的程序,用于测试。
这下指令也输入了,CPU 能跑出结果吗?
出现了一些小问题,流水灯有时不能正常亮起。别担心,有 bug 是常有的事,那 debug 一下吧。
Up 主很快就找到了 bug,是「有个地方断开了」。修复之后为了让运行效果更明显,Up 主又重新写了一遍二进制代码,将 CPU 调整为跳转到 0X00FF 处运行。
再手扣一遍程序,结果是运行成功,流水灯正常亮起,完全没有问题。
组件完整,能运行程序,这个「爆肝」的手搓项目终于大功告成。
网友留言道:「冯诺依曼大呼内行」。
在完成这个 CPU 的基础原型之后,林同学下一步打算继续完善它的功能,让它可以运行更加复杂的程序。