Мои маленькие реле: Brainfuck компьютер — это реальность


Прошел ровно год с момента прошлой публикации и я подумал что первое апреля — отличный день для ежегодного дайджеста по моим трем безумным компьютерным проектам. В тот раз проект существовал только на бумаге, теперь же — определенно стал реальностью.

Подкатом звенящие релейные блоки, самые быстрые в мире вычисления на реле(но это не точно), монтаж накруткой, вакуумные индикаторы и моргающие светодиодики.


Историческая справка


Рисунок 1: Потрепанный жизнью и мною лично томик Войцеховского «Радиоэлектронные игрушки», 1979 г.

Давным давно, когда вокруг все было большим, а я маленьким (году так в 2002-м), отец подарил мне книгу Войцеховского «Радиоэлектронные игрушки». Тогда у меня не было компьютера, а про интернет и вовсе не слышал и знакомая многим книга оказалась просто кладезью занимательных электронных приборов. Было среди них и описание электронно-вычислительной машины и схема простенькой модели на телефонных реле. Эту модель, будучи на втором курсе университета в 2008-м году, я собрал для доклада по истории компьютеров.


Рисунок 2: РЦВМ — 4-разрядное АЛУ

В то время я уже вовсю изучал просторы интернета и будучи в курсе о существовании и релейного компьютера Гарри Портера, и релейного компьютера №2 и релейного компьютера Цузе — я задумался о постройке собственного агрегата.

Для тех, кто слабо представляет что там у других, предлагаю к просмотру свой видеообзор самодельных релейных компьютеров. За год он самую малость устарел, но не перестал быть менее интересным:

В том же 2008-м, на занятиях по теоретическим основам электротехники, я определился с главным компонентом — герконовым реле. В одной из лабораторок в с удивлением наблюдал на осциллограмме, как малютка РЭС55 работала на частоте 50Гц. Это произвело на меня неизгладимое впечатление и я начал копить герконовые реле.

Прошло 10 лет….

И спустя десятилетие проект с огромной скоростью движется к релизу. С мертвой точки все сдвинулось в ноябре 2016-го, когда родилась текущая архитектура. К сожалению я решил изготовить все печатные платы самостоятельно… в результате целый квадратный метр двухстороннего текстолита превратился в черную дыру и засосал в себя несколько сотен человеко-часов свободного времени, что для наемного работника равняется примерно полугоду. С апреля по ноябрь 2к17-го практически ничего не происходило.

Инфографика

Архитектура машины соответствует машине Тьюринга. Имеется лента с данными — оперативная память на 64 килослова (16 разрядное слово). ОЗУ — микросхемы кэша от какой-то мат. платы под Intel Pentium. За аутентичностью — идите в… раздел “Аутентичность”. Микросхемная ОЗУ используется в большинстве известных мне самодельных релейных компьютеров.

Центральный элемент — 16-разрядный сумматор с параллельным переносом. Он отвечает как за вычисление номера следующей инструкции, так и работает с данными и указателем на них.
На входах сумматора висят 16-разрядный временный регистр и 12 разрядный командный регистр. 12 бит подается также и на старшие 4 бита сумматора, что дает “полноценные” 16 бит. Тут важно что сумматор правильно работает и со сложением и с вычитанием 12-битного числа.

Недостаток очевиден — за раз мы можем перепрыгнуть только на 2^12 инструкций назад, или вперед, либо изменить указатель или данные на эту величину. Первое — надо учитывать при написании программ, по второму — всегда можно повторить процедуру.

Вычитание идет в доп.коде. Параллельный перенос обеспечивает постоянную задержку вычисления — всего лишь 3 последовательно-стоящие реле. Это не более 2мс.

К выходу сумматора через защелки подключаются IP регистр и AP регистр, а также вход ОЗУ.

Вычисления

Основных операций — ровно две штуки. В одном случае мы работаем с вычислением нового значения указателя, в другом — нового значения данных.

Каждый нарастающий фронт запускается вычисление нового номера инструкции. По сути делается IP++. После вычисления, IP подается на адресный вход платы памяти и через шину данных инструкция попадает в командный регистр. Старшие 4 бита определяют будущую инструкцию, младшие 12 скорее всего не равны нулю и в будущем сумматор изменит лежащее во временном регистре число ровно на эту величину.

Каждый спадающий фронт начинается выполнение операции.

Для операций с AP и IP регистрами последовательность действий выглядит так:

  • Через шину адреса содержимое IP(AP) регистра копируется во временный регистр;
  • Временный и командный регистры подаются на вход сумматора. Через 2мс на выходе сумматора будет готов ответ.
  • Ответ записывается в IP или AP регистр.
  • Есть некоторые особенности. Для команд AP+BIAS и AP-BIAS все именно так, для условных команд, когда делается например IP=(*AP==0?) IP+1: IP+-BIAS нам еще нужно на шину данных выгрузить текущее значение ячейки данных и снять информацию с нуль-детектора.

    Для операций AP+BIAS и AP-BIAS последовательность немного различается.

  • Через шину данных текущее значение ячейки памяти записывается во временный регистр.
  • Временный и командный регистры подаются на вход сумматора. Через 2мс на выходе сумматора будет готов ответ.
  • AP регистр продолжает подаваться на вход платы памяти. Ответ с сумматора пишется напрямую в память.
  • Вычисления всегда происходят в 16-разрядном режиме. А вот нулевой флаг условного перехода определяется как:

    Z = ((16bit?) *AP : (*AP) & 0x00FF == 0) ;
    Конструкция

    С прошлого раза ничего не изменилось.

    Модуль


    Рисунок 3: Модуль компьютера. Слева-на-право: модуль D-триггера, диодный модуль, модуль 2AND/2XOR

    В основе — небольшой модуль 40х64мм. Каждый модуль представляет собой печатную плату с 4 реле, на которых реализована простая логическая операция. Имеется разъем на 16 контактов (есть модули на 12 и 14 контактов) и до 4 светодиодов. Все размеры — строго зафиксированы.


    Рисунок 4: Модули в процессе сборки

    Например:

  • Модуль 2AND/2XOR — 2 независимых друг от друга логические операции — 2AND и 2XOR. 32 штуки используются в блоке сумматора, по два модуля на бит. Сначала были запаяны все 4 светодиода, но схемотехника модуля такова, что два реле на каждом модуле включены параллельно, и для уменьшения потребляемой блоком мощности, половина светодиодов была снята.
  • Модуль D-триггер — 64 штуки уходят на два регистровых блока. Из них 60 — триггеры без сигнала Enable.
  • Модуль диодный — просто 8 диодов на плате для реализации многовходового диодного OR. Грязный хак, но позволяет экономить как на реле (это сейчас у меня еще порядка 400 реле в запасе), так и на времени — как по сравнению с реле сигнал передается на выход такого логического элемента мгновенно.
  • Модуль 2& — Это базовый кирпичик. По сути — 4 реле с контактом на переключение для реализации абсолютно любой логической схемы. Пойдут на блоки логики в неизвестном количестве.
  • Универсальный 2AND/2OR который сделан так, что позволяет реализовать практически какую угодно логическую функцию — 4AND, 4OR, 4AND-NOT, 4OR-NOT и так далее. Тоже пойдет на блок логики в неизвестном количестве.
  • Как я сказал — потратив впустую кучу времени на изготовление самодельных печатных плат я психанул и заказал полный комплект плат у китайцев. В первую же неделю я собрал первые модули. А еще через месяц были готовы все модули для блока сумматора.


    Рисунок 5: Блок сумматора

    Блок

    32 модуля по 8 модулей в 4 ряда объединяются в функциональный блок. Всего блоков 5 (в худшем случае — 6):

  • Блок сумматора — 16-разрядный полный сумматор. Два 16-разрядных входа для чисел, 1 линия переноса нулевого разряда, Два выхода. На одном — операция суммирования, на другом — XOR между входами. Может использоваться как самостоятельная операция.
  • Блок регистров IP/AP — Два независимых 16-разрядных регистра без сигнала Enable. Выводы Q и ~Q используются напрямую и подаются через защелки куда следует. Можно было и запаять 4 реле, но ради экономии реле функционал вынесен на внешние защелки.
  • Блок регистров TMP/CMD — Регистров тут три. Один — 16-разрядный — временный регистр. Точно такой же как и IP или AP. Второй — 12-разрядный, его выход подключается ко входу сумматора через защелку. Третий — 4-разрядный, со встроенным сигналом Enable. Он используется для хранения текущей инструкции.
  • Блоки логики — 2 штуки. Либо три. Схема — до сих пор неизвестна. Предварительные расчеты показывают, что 64 модуля будет достаточно (GOTO: Плата памяти).
  • В основании каждого блока базовая плата — 200х150 мм, не имеющая разводки. Все что на ней есть — это 32 разъема и торчащие снизу квадратные пины для монтажа накруткой.


    Рисунок 6: Базовая плата и корзинка к ней

    Просто так торчащие в разъеме модули — это ненадежно. Они будут болтаться туда-сюда, смещаться от тряски и всячески снижать надежность конструкции. Для их фиксации я нарисовал и распечатал специальные корзинки с пазами. В них модули уж точно никуда не денутся — поездку на поезде до москвы и обратно они пережили без проблем.

    Корзинку можно было бы нарисовать и полегче — слоем в 0,32мм ее печатать чуть больше 10 часов. Три корзинки напечатаны PLA-пластиком, еще две — HIPS. Последний, из-за отсутствия у моего принтера кожуха, при печати ощутимо коробит.

    Можно заметить, что блок сумматора не имеет ушей для крепления. Корзинка для него была напечатана самой первой. Потом я эти уши либо доклею, либо напечатаю новую корзину.

    Рисунок 7: Блок сумматора и блок логики.

    Монтаж накруткой

    На базовой плате нас ждут 600 выводов, которые надо соединить между собой. Благо что соединять нужно не вот прям все, а лишь почти все. С другой стороны легче от этого не становится.

    Берем в руки специальный инструмент, моток провода и ножка за ножкой накручиваем схему соединений.


    Рисунок 8: Монтаж накруткой блока сумматора

    Это лишь начало работы. Ну как начало. Сначала был тихий ужас — провода лежали как попало, одни перемычки длинные, другие слишком длинные… Немного научившись делать лучше чем было, я снял большую часть перемычек и перекрутил все заново — стал натягивать перемычки струной. Так и провода не болтаются, и результат выглядит намного лучше. Старался класть так, чтобы провода не давили на углы не своих пинов. В результате — ни одного замыкания. От первой попытки остались только земляные линии.


    Рисунок 9: Монтаж накруткой блока сумматора. Итоговый результат

    В настоящий момент получается не вот прям аккуратно, но для первой платы очень даже хороший результат, я считаю. До сих пор не научился класть провод виток к витку, то ли инструмент кривой, то ли руки…

    У тов. UA3MQJ есть подробная статья по данному способу монтажа.

    Кроме блока сумматора нужен блок регистров. Вернее, два блока регистров. Еще пара месяцев — и еще 64 модуля собраны и протестированы. Осталось накрутить базовую плату.

    Как это было.

    Индикаторные модули


    Рисунок 10: Индикаторный модуль

    Текущее состояние регистров процессора надо на чем-то отображать и я решил, что вакуумные индикаторы будут в самый раз. На плате 100х100мм (ибо 10 штук такого размера можно у китайцев за 5$ заказать) разместились 6 индикаторов ИВ-6, триггеры К155ТМ8 и микроконтроллер. Индикация здесь — динамическая.

    Еще есть 16-разрядный вход для прямого считывания состояния регистра и UART-порт, для получения команд от платы памяти.

    Сейчас прошивка умеет считывать состояние 16-разрядного порта и в HEX-формате выводить его на индикатор. Всего таких модулей мне потребуется 4 штуки. Три будут выводить текущее состояние регистров — IP, AP и CMD регистра дабы иметь более удобную визуализацию текущих хранимых значений. Четвертый — будет показывать общее количество выполненных инструкций.

    Защелка


    Рисунок 11: модуль защелки

    Модуль защелки состоит из 8 реле РЭС43. Внутри — два замыкающих контакта. Слева и справа — светодиоды, отображающие текущее состояние входа и выхода.

    Размер защелки — 100х100мм. Требуемое количество — 8 штук. Две готовы, осталось собрать еще шесть.

    Плата памяти


    Рисунок 12: Плата памяти. Общий вид

    Самый огромный блок, содержащий в первую очередь две микросхемы статического ОЗУ на 64 Кбайт и схемы согласования к адресным входам и порту данных. На плате располагается микроконтроллер ATmega1280. Жизненно-важных задач у него две:

  • Загрузка программы и начальных данных в ОЗУ. Скомпилированный бинарник нужно поместить в память. Для этого будет возможность подключиться к плате памяти по UART или telnet(через Wi-Fi) и загрузить исполняемый файл. МК прочитает заголовок и разложит секции кода и данных в ОЗУ. Мне совершенно лень это делать с помощью тумблеров и кнопок — программа на brainfuck, умеющая делать что-то сложнее HelloWorld содержит тысячи инструкций. Есть в заначке пара козырей на этот счет, но о них — в другой раз.
  • Реализует команды чтения данных из консоли и записи в нее. Да-да инструкции “.” и “,” реализуются с помощью МК. Вернее, релейная логика информирует МК о том, что сейчас надо передать в консоль состояние шины данных, либо наоборот вывести на шину данных значение из консоли. По сути, МК работает преобразователем параллельного интерфейса в UART. Да, это вполне можно исполнить на какой-нибудь спец. микросхеме и я подумаю об этом.
  • До сих пор не решил что делать с 16-разрядным режимом. Конечно большинство программ написаны под 8-разрядный brainfuck и тут все просто — читаем и пишем младший байт. А в 16-разрядном режиме что делать? Выводить все слово или тоже только младший байт?

    Помимо основных, у МК есть ряд побочных задач, без которых в принципе можно обойтись, но они нацелены на удобство пользования машиной:

  • МК отвечает за вывод небольшой области памяти на светодиодную матрицу 32х16 пикс. Делает это он пока шина адреса и шина данных не занята основной логикой. Тут я не уверен, что для МК вообще найдется время на шине, так что вопрос требует проверки. Но в заголовке программы будет стартовый адрес для отображения и я попробую заставить его работать. Индикация — динамическая. За один такт выводятся сразу два столбца данных.
  • При активации в бинарнике флага защищенного режима работы памяти, в случае попытки исполнения секции данных, либо записи в секцию памяти МК сгенерирует исключение “Segmentation Fault”. Так мы можем следить за тем, чтобы программа не лезла куда не следует. Читать секцию памяти не запрещено.
  • При активации флага контроля кода, МК активирует симулятор и будет выполнять в нем те же инструкции, что и компьютер, сравнивая ожидаемый и получаемый результаты. Если результат будет отличаться, сработает исключение “Machine Error”. Это будет означать, что произошла ошибка в вычислениях и возможно один модуль начал сбоить. Либо мы слишком задрали тактовую частоту и реле уже не успевают вычислять. Как раз с помощью этого функционала я буду пытаться выжать максимум из машины — что-то должно будет контролировать корректность работы в этот период.
  • Есть еще временная, но таки жизненно-важная функция платы памяти — эмуляция блока логики, пока его нет. На плате памяти имеются линии ввода и вывода и мы можем подавать на блоки нужные сигналы. Так, подключив все управляющие линии к плате памяти и написав программу, выдающую нужные последовательности команд получится в самые короткие сроки:

  • запустить первые программы на исполнение;
  • отладить алгоритмы и схемотехнику блока логики, что увеличит шансы на его безошибочную сборку и работу впоследствии.
  • Потом, собирая нужные модули блоков логики, все функции будут постепенно переведены «в железо». Когда МК перестанет отвечать за логику — проект будет считаться завершенным.

    Аутентичность

    Проект изначально не задумывался как чисто релейный, без применения транзисторов и микросхем. С одной стороны — компьютер получается гибридный и теряет в радиационной стойкости, с другой — большинство релейных компьютеров имеют аналогичный недуг. В финальной версии машины так и будет использоваться микросхема памяти и микроконтроллер. Ферритовая память будет использована в другом, уже “Silicon-Free” проекте.

    Для компенсации эффекта неканона я обзавелся электронной печатной машинкой “Robotron S6130”


    Рисунок 13: Электронная печатная машинка ромашкового типа.

    К сожалению, машинка досталась мне в потрепанном жизнью состоянии. Она долгое время использовалась в бухгалтерии, но в итоге была брошена умирать в гордом одиночестве.

    Рекомендую к просмотру уникальный обзор этого монстра.

    Непосредственно механика в хорошем состоянии, однако сильно досталось процессорной плате, на которой стояла пара NiCd аккумуляторов Д-0,25. Они благополучно протекли и сильно залили электролитом все вокруг.

    Я хочу ее восстановить и использовать в качестве терминала ввода-вывода для компьютера.Однако помимо неисправности электронной части, машинка имеет русскую ромашку (диск с буквами) и русские клавиши. Второе — решается наклейками, первое — надо искать и тут мне пока не везет. Про то что требуется картридж с красящей лентой я вообще молчу. Хотя бы бумага у меня для нее есть..

    Если по электронике будет принято решение что она безвозвратно утрачена, то попробую найти донора, либо — разработаю новую электронную начинку. Сделать плату управления пригоршней шаговиков — не самая сложная задача. Сложнее будет перевести с немецкого мануал и понять ТЗ. Конечно, эта машина заслуживает отдельной статьи по результатам оживления. Против нее пока — приоритет выполняемых работ.

    Тесты

    Всех тех, кто дочитал до этого места — ждет награда в виде трещащих и жужжащих релейных блоков.

    Для начала — попробуем подать на вход реле меандр, через транзисторный каскад:


    Рисунок 14: Скоростное тестирование герконового реле РЭС55. Желтый сигнал — на катушке, синий — на контактах

    Так как вход осциллографа имеет некоторую емкость и после размыкания контакта реле она остается в воздухе и начинается саморазряд, мы видим обратную экспоненту. На частоте 1,7кГц! Для реле! Для одного маленького герконового реле! Обычные глохнут на 20Гц или немного выше. На номинальной частоте в 100 Гц нарастающий и спадающий фронты примерно по 600мкс. Здесь они настолько мелкие(200мкс), поскольку в катушке на момент следующего включения еще остается энергия с предыдущего.

    Подаем напряжение на блоки, на входы подрубаем переключатели от советских измерительных приборов.


    Рисунок 15: Блок сумматора и блок регистров в работе

    Оно считает! Круто.

    Так это выглядело с места событий. Сначала я хотел переделать переключатели под 16-разрядные. Подключить индикаторы и на вход и на выход, но… Не удержался.

    Ну и раз все работает, да и реле оказалось способно на безумные скорости, подаем меандр на линию переноса:

    И врубаем 500Гц. Сумматор справляется, хотя по звуку этого не скажешь. На самом деле звук чистый, но конденсаторный микрофон считает иначе. Насколько мне известно, это самый быстрый релейный сумматор в мире.

    Продолжение следует


    Рисунок 16: Проектирование каркаса компьютера

    Постепенно собираются недостающие шесть штук защелок и начинает проектироваться каркас будущей машины. На чертеже шесть блоков на случай если не хватит 64 модуля на логику. А если хватит — место под нижний центральный блок останется пустым.

    Одновременно с этим я пишу прошивку для платы памяти, дабы она могла заменить пока отсутствующий блок логики. Уже летом компьютер сможет исполнить свою первую программу.

    Три компьютера???

    Да, три. Первый — текущий BrainfuckPC. Второй — пневмонический компьютер, с кодовым названием FluidicPC.

    О третьем радиационно-стойком будущем монстре уже можно найти упоминания в интернете, но я не хочу распыляться между проектами и сначала хочу доделать текущий — анонса по нему пока не делаю.


    Рисунок 17: Комутаторные декатроны А101, А102 и А103
    Хотя по этой картинке уже можно догадаться о чем будет идти речь.

    ЗАЧЕЕЕЕМ????

    Ссылки

    Весь проект продолжает быть полностью открытым. Посему основные ссылки по проекту:

  • Репозиторий с принципиальными схемами и разводками печатных плат. Там же находятся прошивки индикаторного модуля и платы памяти
  • На этой страничке я публикую еженедельные и не очень отчеты о том что было проделано. Сейчас вы читаете статью, чуть более чем полностью состоящую из этих заметок. С переводом, комментариями и дополнениями.
  • Компилятор и эмулятор.
  • Оставить комментарий