我的小接力:Brainfuck电脑是神奇的

引言


曾几何时,当一切都变得很小而我很小的时候,我读了Wojciechowski的书“电子玩具”,渴望使其中描述的设备栩栩如生。 因此,在已经很遥远的2008年中,在几十个电磁继电器中,组装了一个能够加减的4位ALU( RCVM1-继电器数字计算机-版本1 )。 然后我想-如果我组装大量继电器并建造一台成熟的继电器计算机该怎么办? 我花了8年的时间在这里和那里慢慢组装继电器,直到达到所需的数量,我才开始创作。


让我向您介绍您的项目,以创建第二版数字中继计算机,其代号为“ BrainfuckPC”-具有Von Neumann架构的16位计算机,并提供一组Brainfuck语言的说明。 设计工作已经完成,我正在制作这个怪物。


1规格


  • 地址总线宽度:16位
  • 寻址:逐字,16位/字
  • 内存容量:64 Kiloslov(128KB)
  • 数据总线宽度:16位
  • 代码和数据的统一地址空间(冯·诺依曼体系结构)
  • 时钟频率(设计):100 Hz, 1个指令/周期
  • 指令集: Brainfuck ++
  • 继电器数(设计):792
  • 二手继电器:簧片开关,RES55(1p),RES64(1z)

详细资料已滚动


一般工作原理


考虑计算机的通用结构:



图1:通用计算机结构


中心元素是加法器,它并不简单,但是具有并行传输。 为什么需要这样做-我在下面说一些。


程序和数据存储在存储块中。 根据我们现在要读取的内容,在IP指令寄存器或AP地址寄存器中记录的地址处进行访问-在AP指定的地址处的数据或在IP地址处记录的指令。


要操作此图灵磁带(Brainfuck编程语言可以准确识别它),我们需要能够执行以下三种操作之一:


  • 更改当前数据单元格中的值,即执行添加/子操作。 在Brainfuck中,单元格中的值只能更改一个值,即 +1或-1。 但是,如果拥有成熟的加法器,那么不将长链+++++++++++++(------------)分解为一个操作AP + = N( AP- = N)会大大加快流程,这是一个罪过计算。 (也不要忘记将[-](或[+])变成* AP = 0);
  • 更改当前所选数据单元的编号。 也就是说,遍历数据存储器(AP ++,AP--);
  • 更改当前指令的编号。 首先,在每条指令之后,我们需要将IP寄存器中的值增加一。 其次,如果代码中有分支,则更改此值(默认情况下用于组织循环)。 只有一个控制标志-Z。因此,有JumpIfZero和JumpIfNotZero命令。

总的来说,我们需要能够为加法器的一个输入提供以下三个模块中的任何一个的值:AP寄存器,IP寄存器,DATA总线。 我们将通过一个临时寄存器来执行此操作,在该寄存器中,我们将保存所需的值之一,并使用16位密钥连接所需的值。


在加法器的第二个输入处,我们将提交一个数字,这些值之一应更改为正数或负数。 由于指令的宽度有限,因此只能用+ -12位数字进行更改。 但是,对于Brainfuck来说,这已经足够了(“足够每个人使用”)。
我们将从命令寄存器中获取这12位,这是很自然的,因为有些团队根本不使用加法器。 不要忘记,负数将在扩展代码中提供,并提供额外的文件。 单位转移输入(即A + invB +1)


计算结果将立即加载到我们得到的位置。 由于临时注册,我们可以轻松完成此操作。


有关视频的更多详细信息(我什至会说无聊)可以在此视频中找到:



指令集


绘制了能够实现8条基本Brainfuck指令的一般示意图后,我意识到它具有更大的潜力。 因此,我开发了一套与Brainfuck兼容的更广泛的指令,但需要将每个源BrainFuck指令编译为16位计算机指令。


指令概述


所有指令均为16位。 由几个部分组成。


  • 15、14、13位-确定指令等级
  • 位12-签名指示的签名位
  • 位11-0-包含有符号int-a的低12位。 根据第12位的值形成最高4位。

指令表


使用说明书操作码运作方式相当于Brainfuck内容描述
加m160X XXAP← AP + m16'+'(重复m16次)将基数添加到所选单元格的当前值
子m161X XXAP← AP-m16'-'(重复m16次)因此,它从中减去基数
ADA M162X XXAP←AP + m16'>'(重复m16次)增加地址的价值
广告m163X XXAP←AP-m16'<'(重复m16次)减小地址值。
jz m164X XX(* AP == 0)? IP←IP + m16:IP←IP'['如果当前单元格的值为零,请转到IP + m16
jz m165X XX(* AP == 0)? IP←IP-m16:IP←IP没有啦转到IP-m16,如果当前单元格的值为零
奔驰m166X XX(* AP!= 0)? IP←IP + m16:IP←IP没有啦如果当前单元格的值不为零,请转到IP + m16
奔驰m167X XX(* AP!= 0)? IP←IP-m16:IP←IP']'转到IP-m16,如果当前单元格的值不为零
和m168X XXAP← AP和m16没有啦逻辑与且为正数
和m169X XXAP← AP和m16没有啦逻辑与且为负数(其他人必须形成高4位)
或m16XXAP← AP或m16没有啦逻辑OR为正常数
或m16bX XXAP← AP或m16没有啦具有负常数的逻辑或
c0 00* AP←CIN','从控制台读取一个m8字符。 如果输入缓冲区为空,请等待。
c0 01COUT←* AP'。'将M8字符打印到控制台
压缩文件d0 01AP←0没有啦清除AP寄存器。 该命令允许组合
clr.ipd0 02IP←0没有啦清除IP寄存器。 该命令允许组合
clr.dpd0 04* AP←0'[+]'或'[-]'清除存储单元。 该命令允许组合
set.apd0 10AP←* AP没有啦将当前值写入AP寄存器
set.ipd0 20IP←* AP没有啦将当前值写入IP寄存器
get.apd1 00* AP←AP没有啦从AP寄存器读取当前值
get.ipd2 00* AP←IP没有啦从IP寄存器读取当前值
模式e1 00没有啦8位激活(1)
模式e2 00没有啦16位激活
停止f0 00没有啦停止机

  • AP-地址寄存器
  • IP-指令注册
  • * AP-当前内存位置
  • CIN-控制台输入
  • COUT-控制台输出

  1. 激活8位模式后,加法器将继续以16位模式运行。 但是,条件指令(即,测试当前存储单元的值是否等于零)变为8位。 ( AP&0x00FF == 0)? 和( AP&0x00FF!= 0)? 到目前为止,控制台的输入和输出决定始终保留8位。 到底不是以Unicode打印?

在此视频中,我详细介绍了(但很少了解)每个指令的作用以及与之对应的“操脑”指令:



并行加法器


中继计算机不仅应该是中继,还应该是快速的。 像其他任何计算机一样,我的也将是配备有时钟发生器的同步机。 自然,我不想浪费时钟周期,而是尝试将每个操作调整为一个周期-也就是说,对于同步发电机的上升沿和下降沿,我可以加载并执行新命令。 同时,希望所有命令在同一时间段内执行。


每个继电器在操作和释放时都有一定的延迟,如果使用继电器RES22,我们将花费1个常规时间单位(cu)。 等于12-15ms(参考),RES64-1.3ms(参考)。 我的车中最昂贵(也是最频繁)的操作是加法器。
就其本身而言,这是非常简单且快速的,但是“有一个警告”在于计算和传输传输信号的方法中。



图2:串行传输加法器。


最初,我计划使用顺序进位加法器。 在这种加法器中,每个随后的放电取决于当前电流的放电传输信号的状态。 结果,计算操作的持续时间将在2立方米之间波动 -N * 2 cu,其中N是位数。 结果,一个16位顺序进位加法器的最大延迟为32 cu


并行进位加法器可提供最佳性能。 它们缺乏从放电到放电的传播传播过程。 在每个类别中,同时生成输出值:



图3:并行进位加法器


构建具有所示特性的加法器的能力基于总和和传递函数的再现,该函数仅取决于项的值,而与放电在放电网格中的位置无关。 问题在于,并行传输方案本身随随后的每次放电变得更加复杂。 在这里,看看会发生什么:



图4 :(应该是LaTeX公式的形式,但不是),用于计算位的传输信号的公式。 哪里 ki=ai cdotbi-按位 hi=ai+bi-按位或


结果,实现并行迁移非常昂贵。 但是,应该指出的是,下一次排放包含用于计算前一个排放的方程式(对于Nicolas Cage,应该有一个模因“可以吗?”),因此,原则上,仅针对高级排放制定转移计算方案,并从中收集其余部分就足够了,得出中间结果的结论。



图5:16位并行加法器的完整图


在图5中,前两列是加法器本身。 然后是2AND和2OR块,它们形成h和k的中间值,如图4所示。它们的存在促使我用加法和乘法逻辑运算扩展了命令列表,为此,我只需要添加几个锁存器和相应的微码。


其他所有内容都是基于4个RES64继电器的5AND块,这些块可以焊接,以便一个模块可以用作2AND + 3AND。 对于这些模块,每个逻辑“与”步骤都通过一个二极管输出,这使您可以收集中间传输信号。


估计的信号传播时间:加法器应付1 cu,这时在2AND / 2OR块的输出处生成信号,然后1 cu -通过在5AND块中相乘,二极管上的逻辑加法不会引入延迟。 好,最后一个 用于重新计算加法器。


总计3立方米 而不是32或加法器不超过4.5毫秒。


寄存器


机器中有四个16位专用寄存器。 没有RON。 只有紧密的绑定,只有硬核! 它由D触发器组成,每个D触发器是4个RES55继电器上的独立模块,其电路如下:



图6:D触发器模块的示意图。 在某个地方仍然有连接器,但是在这里并不重要,因为所有内容都已签名。


数据进入数据输入,其继电器确定同步信号的去向-复位触发器或安装触发器(对此负责的还有两个继电器,其中一个具有自锁功能)。 第四个继电器获得开关输出Q。这是一个非常有用的功能。


记忆板



图7:内存板。 电路板尺寸315x200mm


尽管存储电路本身只是模块总填充量的一小部分,但这是一个非常复杂且重要的元素。 该委员会的任务是,首先要存储程序和数据总存储量的64千斯洛伐克克朗。 它基于两个64 KB缓存芯片组装。 通过保护电路和开关输入的地址连接到计算机地址总线,并且在数据总线侧连接开关和输入缓冲器和输出驱动器的复杂系统。 为了读取和写入内存,两条线分别为W / R和Sync。 第一个选择我们将要做的事情,第二个选择实际上将要做的事情。


而且,尽管这种同步本身不存在,但存储卡自然会过自己的生活。 在渲染上,您可以看到两个16x16 LED矩阵。 该显示显示一些存储区域。 顺便说一句,是通过程序确定的VideoRAM。 询问存储芯片并控制Atmega1280微控制器的输出。


对于sim卡而言,微控制器的任务并不在那里结束。 控制台的输入和输出挂在上面。 它将输出到哪里-我还没有决定,因此,用于常规控制台的USB-Serial转换器和用于Wi-Fi的ESp8266在板上分离了。 根据后者的说法,在最紧急的计划中要有一个网页,该网页具有将计算机程序下载到内存和控制台本身的能力。 是的,MK的任务还包括将程序初始加载到RAM中,从而可以完全访问RAM,以及一个用于存储程序的1 Mbit小型EEPROM。



图8:存储卡的示意图。 未显示微控制器和框图


逻辑块


我不知道他最终会怎样。 通用计算机电路上提供了最新版本,但我不喜欢它。 我很可能会制作一个12级音序器,并借助按键将信号发送到各个块。



图9:16位块周围的所有东西都是逻辑块


建筑施工


机器的设计是模块化的机架。 KDPV清楚地显示了如何填充机器。 但首先要注意的是:


模组


计算机的基本元素是一个60x44mm模块,带有一个16针连接器,带有4个继电器,它们的线束和4个LED指示:



图10:模块的3D模型


各种类型的模块:


  1. 带传输的1位加法器-16个;
  2. 用于并行传输电路的5AND模块-32个;
  3. D触发器模块-每个寄存器64个,外加一点逻辑;
  4. 模块4x2AND_SW,用于组织闩锁。 只有4个合闸继电器。
  5. 4x2AND模块,用于组织闩锁。 4个继电器中有3个带有转换触点。 在4个继电器上没有足够的输出引脚。
  6. 该模块是一个二极管,8个二极管D226D。 组织多输入或
  7. 通用模块2AND / 2OR,允许您创建2AND-NOT,2OR-NOT,4AND,4AND-NOT,4OR,4OR-NOT以及任何组合。 基于4个带开关触点和公共点的继电器;

由于我已经提出了一个控制逻辑块,尽管我已经拒绝了,但我不知道每种类型的模块的确切数量。 我会在路上解决的。 估计模块数量为192个。



我们采用一块150x200mm的电路板,在其上焊接32个带有16个引脚的连接器,但这并不简单,但是为了包装起来 ,将我们的模块以8x4矩阵的形式安装在其上,得到了这样一个块:



图11:块


在我的车中将有6个这样的模块-每个加法器两个模块,每个寄存器两个模块,每个逻辑两个模块。 我会在萝卜上刮擦更多的闩锁块,但如果是,则它们是平坦且焊接的


选择环绕式安装的原因是:首先,每个基板的电路虽然事先已知,但可能会发生变化并且容易出错。 其次,原则上不可能第一次正确地分离逻辑块,并且如果寄存器块的所有内容都清晰无误,并且您可能会用同步线(例如同步线)出错,那么您将不得不重做逻辑1000次。 如果逐步收集逻辑块的每个组件,将会更好。 第三,纯粹是机械因素-从物理上讲,不可能在两层板上分开这些块:) 16位轮胎在许多方向上会发散,而这些方向会反复相交。


每个单元总共包含32个模块,继电器总数为128个。 每个单元的电源为5V 2A。


电脑类


在一个大型框架上,尺寸为640x480毫米(实际上稍大一点,但是数字很漂亮),有六个继电器块和一个存储板:



图12:机器块的位置


整个计算机被插入到一个由贵重木材制成的木制框架中,该框架前后均装有玻璃。


制造业


尽管有当前日期,该项目实际上仍然存在:-)它不是处于最活跃的阶段,但仍处于制造阶段。


接力赛


我有 数量很多,但问题是存有300多种库存,超过1000种-27伏继电器和5伏RES55继电器对我来说可能还不够。 我最终无法估计灾难的规模,但是我认为在下一次我将收集这台地狱机器时,由于外部的补充,问题将消失。



图13:继电器储备。 800件继电器-新产品,在Mitsa无线电市场上成功赚到了几分钱


补货来源之一是实验室电源提供的DAC继电器板。 这些是:



图14:在无线电市场上购买的PSU型电源板(不,我不是)


印刷电路板


我决定自己做所有的印刷电路板。 我向中国人夹了300美元,四个月以来,我一直在做以下工作:用光刻胶覆盖半成品,半透明,蚀刻,用阻焊膜覆盖,显影,钻孔和铣削。



图15:各种蚀刻面板


我在板上制作板,在200x150mm板上制作9个模块。 蚀刻30块板并粘上防焊层。 我不会以任何方式开始。 我的FSR-8000的焊接面罩是蓝色的,由两个部分组成,我之前已经处理过。


并非偶然选择200x150mm的印版-我们将它们放在广播市场上的一个秘密地方,它们已经稳定销售了很多年,而我的整个设备都是为这种格式量身定制的。


一言以蔽之,我开始使用层压机涂覆光阻剂(重氮的MPF-VSC),这些只是奇迹。 胶合质量显着提高。


然后,有必要切割和钻孔这些板,为此,我什至拥有3D铣刀。



图16:3D DIY Chinese 2020CNC铣床


我只花了175美元就把它当作电子产品专用。 足以进行木板钻孔和铣削,而且我已经在寻找3D机器用的滚珠丝杠和导轨组。 准备买这么贵的东西,但是当需要它时就可以自己组装-就是这样。


:




, . ( ) Elf. , ( ). //TODO — , .


: . , . . Segmentation Fault!


, . — . leBrainfuck , .
, , Brainfuck . +-<>, [-] . , . , .


. 8 . :



— 10 . LLVM 0,9 . Intel Vtune Amplifier 120 10 .


. , 3 brainfuck-. 100 50 347 — .. , ! , , . .


, , ,



.



-6 , , . — , . — . - — 30-40 - 6 .


????777



参考文献


openSource. :


  1. https://github.com/radiolok/RelayComputer2 — .
  2. https://github.com/radiolok/RelayComputer2/blob/master/roadmap.md , .
  3. https://hackaday.io/project/18599-brainfuck-relay-computer . GT.
  4. https://github.com/radiolok/bfutils .

Source: https://habr.com/ru/post/zh-CN402629/


All Articles