Unity从零搭建一台图灵完备计算机

如果你不亲手搭建一台计算机,那就不能深刻理解计算机组成的重点

我的初步设想是这样:实体元件挂载脚本代替逻辑门和运算门,对实体进行封装组成更大的功能预制体如寄存器,然后再次封装组成更高级元件如CPU,一般来说,CPU就可以实现图灵完备了,我们以CPU为核心建立宏观的输入输出,通过经典贪吃蛇来验证机器运行。
在这一过程中,挂载脚本代替了复杂的数电原理和延迟问题,简化了一层硬件。
计算机每帧运行有可能是难点,但是AI告诉我不必担心,那就不担心了。

计算机在完备之后可以通过添加BIOS等来模拟现代计算机,并尝试支持操作系统的运行。那得在我学完操作系统之后。

基础元件

构建了加法器 减法器 移位器 比较器 逻辑运算器 时钟生成器 中断触发器 地址解码器 三态缓冲器 D触发器 多路复用器 解复用器

这12种元件足以构成完整的计算机

加法器 减法器 移位器 比较器 逻辑运算器可以组成ALU

大量D触发器可以组成寄存器组

时钟生成器 地址解码器 多路复用器 组成控制器

ALU+寄存器+控制器可组成CPU

D触发器和地址解码器组成内存

地址解码器,多路复用器,三态缓冲器是总线的主要构成

多路复用器/解复用器用于在多个数据源之间进行选择和数据路由

编写构建语言

考虑到构建是一个非常复杂的过程,并包含非常多的重复操作,为此编写一套代替实操、简化过程的编辑器语言很有必要

具体代码不放了,实际可供使用的指令语法规则如下

#注释 不编译,此行#后内容略过
#本语言按照行顺序依次执行
# 以下示例语句中存在大写的单词一般为举例名称,不属于语法,可任意修改
#指定一个工作区
workspace WorkSpaceName # 一般写在最开头,表示接下来所有内容在此WorkSpaceName(可变)工作区内进行,它的功能是转到此工作区内工作,即在unity场景中找到对应名称的对象,之后所有操作比如寻找对象或是生成对象在这个对象下工作,举例来说就是生成对象时默认生成此对象的子对象,生成位置也默认相对此对象为(0,0,0),如果没有此名称的工作区则新建一个工作区对象并挂载工作区脚本,脚本公开属性包含工作区的名称,输入输出属性,操作记录等内容;在此工作区内的所有操作按操作顺序记录下来,再次打开工作区之后进行的操作也要记录
# 举例 workspace 8bitRegister表示创建一个8位寄存器工作区,接下来的操作就可以在其中构建8位寄存器,生成的预制体也都在8bitRegister下
#打印工作区内容
read workspace WorkSpaceName # 将对应工作区内容打印在控制台,包含各种属性和操作记录
#保存工作区整体为预制体
prefab WorkSpaceName# 将WorkSpaceName对象整体保存为预制体
#只存在加法器减法器移位器比较器逻辑运算器时钟生成器中断触发器地址解码器三态缓冲器D触发器多路复用器解复用器加上导线这12类基础元件,其余预制体均为由这12类元件组成的工作区预制体
#创建预制体并命名
InitializedName = create PrefabName at (x,y,z)#在坐标(x,y,z)(可变)处生成一个名为PrefabName(可变)的预制体,重命名为InitializedName(可变),如果不写前面的“InitializedName=”表示不重命名,但是不方便指代,除非大量生成,此时则不必要重命名,其中at(x,y,z)略过默认生成在原点,生成时无论指定在何处如果与其他对象部分重叠都要求进行位置偏移 注意工作区内操作都是相对工作区父对象 无论是生成对象还是坐标
#重复操作次数
create  PrefabName * opreateNum(int)# 如create Dflip * 8 意为生成8个D触发器 
#删除对象
delete InitializedName
#批量重命名来方便批量操作
rename by PrefabName #这个操作获取工作区内所有由PrefabName预制体生成对象并依次重命名为PrefabName(i)其中i表示命名顺序,从0开始,最大为全部数量-1
# 不过unity生成对象时一般会默认进行此操作,因而主要用于批量操作时命名混乱了的特殊情况
#连线
ComponentA OutputInterfaceName -> ComponentB InputInterfaceName # 将A组件的输出接口与B组件的输入接口相连 具体做法是生成wire预制体并将 源对象 目标对象 接口名称(string)分别传入wire组件即可
#连线变体
PrefabNameA[i,n]  OutputInterfaceName -> ComponentB InputInterfaceName # 从PrefabNameA(i)到PrefabNameA(n)将输出端均与B组件输入端相连 i<n 且对象存在
ComponentA OutputInterfaceName -> PrefabNameB[i,n]  InputInterfaceName # A组件的输出端与 从PrefabNameB(i)到PrefabNameB(n)的输入端相连  i<n 且对象存在
PrefabNameA[i,n]  OutputInterfaceName -> PrefabNameB[p,q] InputInterfaceName # 从PrefabNameA(i)到PrefabNameA(n)输出端与 从PrefabNameB(p)到PrefabNameB(q)的输入端相连 n-i=q-p 且对象存在
#为工作区指定输入输出接口
input InputName = ComponentName InputInterfaceName# 指定输入接口 其中InputName是自己命名而后两者是已存在的命名
output OutputName =ComponentName OutputInterfaceName # 指定输出接口 其中OutputName是自己命名而后两者是已存在的命名
#导线在信号传递时,如果连接的对象是工作区组件,需要向下递归直到找到对应的基础元件接口然后再获取值,为此要对工作区和基础元件进行区分

此方悬停
相册 小说 Ai