DekatronPC: различия между версиями

Материал из DekatronPC
 
(не показано 26 промежуточных версий этого же участника)
Строка 1: Строка 1:




Строка 12: Строка 16:
[[Файл:Dekatronpc logo.jpg|справа|355px]]
[[Файл:Dekatronpc logo.jpg|справа|355px]]


== Описание ==  
==Описание==  


Компьютер на базе сверхминиатюрных вакуумных и газоразрядных ламп, процессор которого не содержит кремниевых полупроводниковых элементов.  
Компьютер на базе сверхминиатюрных вакуумных и газоразрядных ламп, процессор которого не содержит кремниевых полупроводниковых элементов.  
Строка 20: Строка 24:
Основное требование к ламповому компьютеру — чтобы инструкции в нем в точности соответствовали языку Brainfuck. Во-вторых — 99% существующих восьмибитных программ на Brainfuck должны исполняться исключительно на ламповой логике. Оставшийся 1% банально может не умещаться в ОЗУ. Максимум того, что допускается использовать в аутентичной части машины, — это германиевые диоды, да и то лишь в выпрямителях питания в схемах обвязки кубов памяти.
Основное требование к ламповому компьютеру — чтобы инструкции в нем в точности соответствовали языку Brainfuck. Во-вторых — 99% существующих восьмибитных программ на Brainfuck должны исполняться исключительно на ламповой логике. Оставшийся 1% банально может не умещаться в ОЗУ. Максимум того, что допускается использовать в аутентичной части машины, — это германиевые диоды, да и то лишь в выпрямителях питания в схемах обвязки кубов памяти.


== Подпроекты ==  
==Подпроекты==  


* [[Ламповая логика]] - Проектирование быстродействующих ламповых логических элементов
*[[Ламповая логика]] - Проектирование быстродействующих ламповых логических элементов
* [[Испытатель электронных ламп]] - Проект современного портативного испытателя вакуумных и газоразряных ламп
*[[Испытатель электронных ламп]] - Проект современного портативного испытателя вакуумных и газоразряных ламп
* [[DekatronPC эмулятор]] - Verilog-модель лампового компьютера на ПЛИС
*[[DekatronPC эмулятор]] - Verilog-модель лампового компьютера на ПЛИС


== Технические характеристики (проектные) - UPD: 19.05.2023 ==
==Технические характеристики (проектные) - UPD: 19.08.2023==


* Архитектура - с раздельной памятью данных и кода.
*Архитектура - Гарвардская, с раздельной памятью данных и кода.
* Объем памяти программ - 1МиБ, из них:
*Адресация памяти программ - 1 000 000 ячеек шириной 4 бит
** Ферритовая память - 1.5киБ
*Адресация памяти данных - 100 000 ячеек данных шириной 10 бит
** Внешняя память - до 1МиБ
*Разрядность:  
* Объем памяти данных - 29.29КиБ(30000ячеек данных). из них:
**Шины данных - 10 бит октетами в формате 8-4-2-1. диапазон счета - 0-255 (3 декатрона)
** Ферритовая память - 1 Киб
**Шина адреса данных - 20 бит, октетами в формате 8-4-2-1. диапазон счета - 0-99999 (5 декатронов)
** Внешняя память (накопитель на магнитной ленте) - до 29.29КиБ
**Шина адреса программ - 24 бит, октетами в формате 8-4-2-1. диапазон счета  - 0-999999 (6 декатронов)
* Разрядность:
*Тактовая частота - не более 1МГц - ограничение со стороны декатрона [[А110]]
** Шины данных - 10 бит октетами в формате 8-4-2-1. диапазон счета - 0-255 (3 декатрона)
**Поправочка - скорость пересчета декатрона А110 - 1МГц, однако согласно Яблонскому, импульс сброса (в данном случае - записи в декатрон) - в среднем на порядок больше импульса пересчета. Поэтому можно смело ронять тактовую частоту до 100кгц...
** Шина адреса данных - 18 бит, октетами в формате 8-4-2-1. диапазон счета - 0-29999 (5 декатронов)
*Быстродействие - до 500тыс операций в секунду. Доступна конвейеризация - пока выполняется текущая инструкция, допускается выборка новой.
** Шина адреса программ - 24 бит, октетами в формате 8-4-2-1. диапазон счета  - 0-999999 (6 декатронов)
* Тактовая частота - не более 1МГц - ограничение со стороны декатрона [[А110]]
* Быстродействие - до 500тыс операций в секунду. Доступна конвейризация - пока выполняется текущая инструкция, допускается выборка новой.
**Время выборки новой инструкции, время исполнения инструкции - уникально.
**Время выборки новой инструкции, время исполнения инструкции - уникально.
**Выборка новой инструкции - не быстрее 2 тактов. (в текущей версии кода 6)
**Выборка новой инструкции - не быстрее 2 тактов. (в текущей версии кода 3)
**Исполнение инструкций - от 1 такта - зависит от предыдущего состояния. В серии команд ++++ первый инкремент займет два такта, второй и последующие - 1 такт, но так как время выборки новой инструкции не менее 2 тактов и может производиться параллельно, то частота инкрементов будет не выше 500 тысяч в секунду на частоте 1МГц.
**Исполнение инструкций - от 1 такта - зависит от предыдущего состояния. В серии команд ++++ первый инкремент займет два такта, второй и последующие - 1 такт, но так как время выборки новой инструкции не менее 2 тактов и может производиться параллельно, то частота инкрементов будет не выше 500 тысяч в секунду на частоте 1МГц.
* Количество ламп  ~1000шт (19.05.2023 - по результатам синтеза Verilog-модели 958шт)
*Текущее Быстродействие в модели:
**Пиковое: 200тысяч операций в секунду.
**Среднее 45 тысяч операций в секунду.
*Количество ламп  ~1000шт (07.06.2023 - по результатам синтеза Verilog-модели 1244шт)
*Используемые лампы:
*Используемые лампы:
**[[6Н16Б]] - сверхминиатюрный сдвоенный триод для работы в импульсных устройствах.
**[[6Н16Б]] - сверхминиатюрный сдвоенный триод для работы в импульсных устройствах.
**[[6Ж2Б]] - сверхминиатюрный пентод для работы в импульсных устройствах. Утверждается, что может работать в режиме с двумя управляющими сетками.
**[[6Ж2Б]] - сверхминиатюрный пентод для работы в импульсных устройствах. Утверждается<ref>И.Г.Бергельсон, Н.К.дадерко, Н.В.Пароль, В.М. Петухов. Приемно-усилительные лампы повышенной надежности. Справочник. изд. "Советское радио". М. 1962</ref>, что может работать в режиме с двумя управляющими сетками.
**[[6Х7Б]] - сврехминиатюрный сдвоенный диод.
**[[6Х7Б]] - сврехминиатюрный сдвоенный диод.
**[[А110]] - сверхминиатюрный коммутаторный декатрон со скоростью счета до 1млн имп. в секунду.
**[[А110]] - сверхминиатюрный коммутаторный декатрон со скоростью счета до 1млн имп. в секунду.
* Потребляемая мощность, общая - не хуже 5кВт. Для тысячи ламп 6Н16Б рассчет составляет:  
*Потребляемая мощность, общая - не хуже 5кВт. Для тысячи ламп 6Н16Б расчет составляет:  
**на накал ламп 6.3В 0,4А/лампа (400А) - 2.5кВт
**на накал ламп 6.3В 0,4А/лампа (400А) - 2.5кВт
**анодное 150В 5мА/лампа ()- 0,75 кВт
**анодное 150В 5мА/триод (10А)- 1,5 кВт
*Общие габариты процессора : три 4U серверных блока размерами 920*420*178мм.
*Общие габариты процессора : три 4U серверных блока размерами 920*420*178мм.
*Масса ) 60кг.
*Масса 60кг.


== Архитектура ==
==Декатрон==
Декатрон — это многоэлектродная газоразрядная лампа, предназначенная для реверсивного счета импульсов. В центре находится диск анода, а вокруг него расположены тридцать электродов. Десяток катодов и две группы подкатодов — по два подкатода между каждым катодом. После подачи напряжения на декатрон между анодом и одним из катодов загорается тлеющий разряд. Подавая импульсы определенной последовательности на подкатоды и соседний катод, мы можем перемещать разряд между катодами, обеспечивая операцию инкремента или декремента. Да эта лампа просто создана для языка Brainfuck!
[[Файл:Dekatron.png|центр|безрамки|450x450пкс]]
Декатрон — это многоэлектродная газоразрядная лампа, предназначенная для реверсивного счета импульсов<ref>В.М. Липкин декатроны и их применение. госэнергоатомиздат.  1960</ref>. В центре находится диск анода, а вокруг него расположены тридцать электродов. Из них десять катодов и две группы подкатодов — по два подкатода между каждым катодом. После подачи напряжения на декатрон между анодом и одним из катодов загорается тлеющий разряд. Подавая импульсы определенной последовательности на подкатоды и соседний катод, мы можем перемещать разряд между катодами, обеспечивая операцию инкремента или декремента. У коммутаторного декатрона все выводы катодов выведены наружу, следовательно можно считывать текущее значение, а также - устанавливать разряд на необходимом катоде. Да эта лампа просто создана для языка Brainfuck!
''Тут нужно сделать ремарку, что нет ни одной схемы записи данных в декатрон по катоду. Однако схема сброса декатрона в исходное состояние есть подача импульса отрицательной полярности на нулевой катод. По образу и подобию можно подать такой импульс на любой катод и получить запись информации в декатрон. В ламповом компьютере Harwell Dekatron используется следующая схема записи данных - на схему сравнения подается сигнал с декатрона и требуемое число. После этого подается серия импульсов инкремента на декатрон до тех пор, пока на нем не окажется необходимое число. Эта схема может быть также реализована, если исходный эксперимент окажется неудачным. Благо что схема записи требуется только для счетчика данных - а это 3 декатрона из 255.''
[[Файл:Decatron reverse control.png|центр|безрамки|650x650пкс]]
Пример схемы реверсивного управление декатроном по цепи подкатодов показан в книге Яблонского Декатроны <ref>Ф.М. Яблонский, Г.М. Янкин Декатроны. 1967г</ref>. Имеется два входа - для инкремента и декремента, на которые подается импульс напряжения необходимой длительности. Так как конденсаторы C3 и C4 в обычном состоянии заряжены до 260В, при подаче сигнала на одну из ламп Л1 или Л2 левый вывод конденсатора притягивается к земле, тем самым на правом выводе формируется сигнал с уровнем порядка -200В, что является достаточным для переключения декатрона. Цепь задержки обеспечивает подачу второго импульса после первого. Схема нарисована с использованием германиевых диодов. В экспериментальной ячейке точно будут использоваться Д7Ж. В итоговом монтаже - использование допустимо, но пока под вопросом.


На базе декатрона мы можем создать простой реверсивный десятичный счетчик. Соединим нужное число таких счетчиков последовательно и получим многоразрядный счетчик, который, например, на базе трех декатронов сможет считать от 0 до 999.
==Декатронные счетчики ==
Декатронный счетчик представляет собой реверсивный многоразрядный счетчик на базе нескольких декатронных ячеек. <u>В декатронную ячейку входят - сам декатрон, усилители чтения, преобразователь позиционного кода в двоично-десятичный, училители записи, преобразователи двоично-десятичного кода в позиционный, а также усилители сигналов подкатодов и схема выдачи сигналов переноса на следующий разряд.</u>[[Файл:DekatronCounter.png|центр|безрамки|900x900пкс]]


[[Файл:Dpc core.jpg|центр|600px]]
На данной схеме показан наибольший функционал декатронного счетчика данных - с возможностью записи любого числа, чтения, органичения сверху (для реализации счета от 0 до 255). Схема переноса реализована таким образом, что количество декатронов в цепочке не влияет на время счета - все разряды переносятся одновременно если выполняется необходимое условие. В большинстве счетчиков не будет схемы записи - это самая дорогая часть по лампам.  


Один такой счетчик на базе шести декатронов будет определять номер текущей исполняемой инструкции. В дополнение к нему нам нужен счетчик глубины вложенности циклов — сумматора в будущем компьютере нет, а значит, начало текущего цикла придется искать вручную, банально перематывая счетчик инструкции назад до тех пор, пока начало нашего цикла не будет найдено. Счетчик вложенных циклов поможет корректно искать нужное начало, даже если внутри нашего цикла множество вложенных. Счетчика от 0 до 999 будет более чем достаточно: в программах на Brainfuck, написанных людьми, даже больше 20–30 уровней вложенности циклов — редкость.
Схема декатронного счетчика содержит две большие группы элементов- обязательная для любого из декатронов и необходимая схемотехнически.


Третий счетчик от 0 до 29 999 будет определять номер текущей ячейки данных. Так как у нас чистый Brainfuck, то и число ячеек в точности соответствует исходной спецификации. Декатронный счетчик можно сбросить при любых значениях.
Обязательной является:


По адресу этого счетчика происходит выборка данных из ОЗУ. Данные помещаются в четвертый счетчик, который умеет считать от 0 до 255. То есть мы загружаем в декатрон наше старое значение, делаем инкремент или декремент и выгружаем данные обратно в память.
#обвязка самого декатрона,
#усилители-формирователи управляющих импульсов, 1 лампа(?)
#трех-позиционная защелка схемы переноса 8 ламп(?)
#усилители-формирователи линии сброса в 0 и в Х (например в 5 для счетчика до 255), 1 лампа(?)  - можно вынести на отдельную плату


[[Файл:Dpc machine.jpg|600px|центр]]
Желательно уместить всю эту обвязку на одной плате.


== Набор инструкций (Актуальная версия на 18 марта 2022г.) ==
Необходимая обвязка:
Общая концепция[[Файл:Dpc insn list.jpg|600px|центр|альт=УСТАРЕЛО! Самая первая визуализация будущего набора команд.|мини|'''УСТАРЕЛО!''' Самая первая визуализация будущего набора команд. ]]


В итоге мы имеем:
# Схема преобразователя позиционного кода в двоично-десятичный - 11 ламп
#Схема усилителей-формирователей позиционных линий для любого из катодов. Два усилителя находятся в обязательной секции, поэтому остается оп 8 линий на декатрон.  Для счетчика данных требуется в общей сложности 17 линий. Можно округлить до 18 линий и разместить на 1-2 платах. Если в одну плату обязательная обвязка влезать не будет - то для счетчика данных требуется 23 линии, а для любого счетчика - от 6 до 10 линий. Исходя из этих данных нужно определиться с числом линий - однако нужно окончательно определиться со схемотехникой и определить требуемое количество ламп на одну линию.
#Схема декодера из двоично-десятичного в позиционный код. Требует по две лампы на линию. Вероятно собираться будет на базе элементов И.


* NOP — пустая инструкция, необходимая для выравнивания циклов внутри кеш-линеек;
В ламповом компьютере требуется 4 реверсивных счетчика с общим количеством декатронов в 17 штук.
* + и - — инкремент и декремент текущей ячейки данных;
{| class="wikitable"
* < и > — изменение номера текущей ячейки;
|+Лампы по счетчикам
* [ и ] — начало и конец цикла;
!Счетчик
* . и , — печать текущего символа в консоль и ввод из консоли.
!Функционал
!Чтение
!Запись
!Управление
!Декатроны
!Диоды
!Триоды
|-
|IP Counter
|Сброс в нуль, Чтение данных, Сигнал Zero
|6
|0
|6
|6
|84
|42
|-
|AP Counter
|Сброс в нуль, Чтение данных, Сигнал Zero
|5
|0
|5
|5
|70
|35
|-
|Data Counter
|Сброс в нуль, Запись данных, чтение данных, Верхний лимит, Сигнал Zero
|3
|3
| 3
|3
|42
|108
|-
|Loop Counter
|Сброс в нуль, Сигнал Zero
|0
|0
|3
|3
|18
|15
|-
|Всего
|
| 14
|3
|17
|17
|214
|200
|}
Функционал счетчика:
*Инкремент и декремент текущего числа счетчика
** Для работы в режиме счета от 0 до 255 необходимо выставить TOP_LIMIT_MODE=1. Тогда по достижении счетчиком числа TOP_VALUE  вместо инкремента будет происходить запись 0 в счетчик. По достижении 0 и при декременте - в счетчик будет записано TOP_VALUE.
*Запись числа в счетчик со входа In, заданного в формате 8-4-2-1
*Чтение числа из счетчика на выход Out, в формате 8-4-2-1


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


Например, инструкция '''HALT''' остановит машину при завершении работы программы. Еще две инструкции — '''LOAD''' и '''STORE''' — оптимизируют работу с памятью.
*Request - наличие этого сигнала по нарастающему фронту запускает счетчик. При отсутствии сигналов Set или SetZero будет происходить счет
*Dec - выбор направления счета - в прямую сторону (лог.0) и обратную сторону (лог.1)
*SetZero - при наличии этого сигнала по нарастающему фронту Clk совершается запись нуля в счетчик
*Set - при наличии этого сигнала по нарастающему фронту Clk производится запись числа со входа In  в счетчика


=== Оптимизация доступа к памяти ===
{| class="wikitable"
Допустим, у нас есть десять инструкций +, идущих подряд. Нам придется десять раз повторить следующий набор действий:
|+Лампы по платам работы с декатроном
!Платы
!Триоды
!Диоды
|-
|Схема чтения
|2
|8
|-
|Схема записи
|29
|0
|-
|Управление, перенос
|5
|6
|}
===Экспериментальная декатронная ячейка===
[[Файл:ExperimentalDekatronModule.png|центр|безрамки|600x600пкс]]
Ячейка представляет собой блок 3U-блок на 4 платы, и реализует полную схемотехнику управления декатроном, включая чтение, запись и пересчет с переносом.


# Прочитать значение текущей ячейки и записать его в декатронный счетчик;
Блок необходим для отладки схемотехники управления декатроном, особенно схемы записи числа в счетчик.
# Выполнить операцию инкремента;
# Записать новое значение текущей ячейки из счетчика в ОЗУ.  


По факту мы девять раз просто так будем делать загрузку-выгрузку. Проще перед первым инкрементом один раз сделать явно сделать '''LOAD''' из памяти в счетчик, а после последнего явно вызвать '''STORE''' обратно из счетчика в ОЗУ. Либо ламповая логика должна понимать, какая инструкция будет идти следом за текущей и выполнять '''LOAD''' и '''STORE''' неявно, не тратя в дальнейшем время на холостые загрузки-выгрузки.
Основная плата - плата декатрона. На ней располагаются непосредственно сам декатрон, схема чтения, включающая в себя преобразователь двоичного-кода в двоично десятичный на диодах и катодные повторители-усилители. Отдельно идет катодный повторитель для сигнала нуля.


С одной стороны, неявный '''LOAD/STORE''' позволит грузить в компьютер программы, написанные на Brainfuck вообще без модификаций. С другой стороны, усложняется логика выборки инструкции, так как при чтении следующей инструкции необходимо учитывать текущее состояние флагов машины и выполнять дополнительные действия.
Также есть схема переноса. Технически это тройная защелка, имеющая два выхода, которые подсвечивают крайние положения - 0 и 9 до момента полного переключения лампы. т.е. этот блок помнит последнее состояние лампы пока идут процессы переключения.


В итоге выбрал способ неявного '''LOAD''' и '''STORE'''. За основу взят принцип data-lock.  
Выход - 30-контактный. На нем есть все линии декатрона на запись, напряжения питания. накал, а также - двоично-десятичный выход 8-4-2-1
[[Файл:Dekatron up down unit.png|центр|безрамки|952x952пкс]]
Еще две платы примерно одинаковые, их задача - преобразовать двоично-десятичный вход 8-4-2-1 в двоичный с сигналом записи - для этого требуется 4 инвертора, и 5-входовый И - на двух сдвоенных триодах, где анод-катод - это 4 линии и пятая линия - сетка. Схема, вероятно, будет изменяться - с переходом на импульсную логику.
[[Файл:Dekatron cell up down WSU.png|центр|безрамки|758x758пкс]]
К этим двум платам пока вопросы. На две платы следующие задачи:


# Pагружаем новую инструкцию
# Инверторы входных сигналов 8-4-2-1. Итого имеем 8 сигналов - прямые и инверсные, которыми можем набрать нужную комбинацию сигналов для следующего этапа:
#Текущая инструкция  '''+'''(или '''-''').  
#Пятивходовые И на двух сдвоенных триодах, где сетка - это пятый сигнал записи. Им на вход подаются сигналы набранные в нужной комбинации на первом этапе.
##Проверяем флаг '''APLock''':
#Усилители записи - 10 штук. По одному на каждый катод. И тут вопрос - либо они будут работать в статическом режиме, либо в импульсном. Первый вариант требует переход в отрицательные уровни напряжения. Второй позволяет обойтись без них, с помощью развязывающих конденсаторов формировать импульсы нужной длительности и амплитуды.
###Флаг снят. значит в счетчик данных еще не загружено значение из текущей ячейки данных. Производим операцию LOAD из текущей ячейки памяти в счетчик данных. Выставляется флаг '''APLock'''
#Усилители сигналов управления подкатодами. тут опять вопрос к режиму работы. Скорее всего я приду к импульсному варианту - он проще и по нему есть все необходимые схемы.
###Флаг стоит. Значит данные в счетчике уже загружены. Ничего не делаем
# Текущая инструкция < или >
##Проверяем флаг '''APLock'''
###Флаг снят. Ничего не делаем
###Флаг стоит. Производим операцию выгрузки текущего значения счетчика данных в ОЗУ. Снимаем флаг APLock
#Текущая инструкция - другая
##Дополнительных действий не требуется.
#Исполняем текущую инструкцию


Каждая инструкция представлена в памяти 4-х разрядным значением, соответствующим тому или иному опкоду.  
====Источники питания ячейки:====
[[Файл:DekaronCellPSU.png|центр|безрамки|600x600пкс]]
Используется четыре трансформатора - выбор из того что было в наличии. Все трансформаторы проверены на сопротивление изоляции мегаомметром на 1кВ.
*ТСШ-170 - 170Вт. предназначен для выработки основного питания +150В, а также пары накальных линий для 6С19П.
*ТН61 - общей мощностью 190Вт. Имеет 4 линии 6.3В  - 3 по 8А и 1 машина - 6.1А.  Будет обеспечивать основное питание накалов ламп, разбитых на группы по платам
*ТА48, мощностью 36Вт - питание декатрона +450В (технически сам источник будет на +350В), а также напряжение смещения -50В.
*ТА7, мощностью 15Вт - напряжение +20В.
Схемы питания берем из блоков питания осциллографов [[С1-54 (Осциллограф)|С1-54]] и [[EMG TR-4401|TR4401]]
[[Файл:Exp DPC 2.png|центр|мини|450x450пкс|
Схема стабилизатора анодного напряжения +150В, 200мА. Питается от трансформатора ТСШ170, выводы 7-8+9-10]]
[[Файл:ExpDPC cell 1.png|центр|мини|450x450пкс|
Финальная схема стабилизатора анодного напряжения декатрона +500В (работает со смещением +150В от земли)Питается от трансформатора ТА48, выводы 11-12+17-8]]


При этом, компьютер имеет дополнительные инструкции, которые предназначены для непосредственного управления машиной.
[[Файл:Exp DPC cell +20v.png|центр|мини|450x450пкс|Схема стабилизатора напряжения +20В, 30мА. Питается от трансформатора ТА7, выводы 19-20+21-22]]
[[Файл:Exp DPC cell -50v.png|центр|мини|450x450пкс|Схема стабилизатора отрицательного напряжения +50В, 30мА. Питается от трансформатора ТА48, выводы 21-22+19-20]]


Для этого, в машине имеется 1-х разрядный регистр текущего набора команд. ISAREG, который в теории расширяет число инструкций до 32 - представляя два набора инструкций:


# ISAREG=0 - Debug ISA - режим, в котором машина находится после включения. в нем доступны инструкции очистки ОЗУ, сброса состояния машины, команды загрузки данных с перфоленты
==Архитектура компьютера==
# ISAREG=1 - Brainfuck ISA - основной режим, в котором доступны 8 инструкций языка brainfuck плюс несколько дополнительных
Машина проектируется на базе четырех реверсивных многоразрядных счетчиков.  


В реальности, одни и те же инструкции могут присутствовать в разных наборах. например инструкции выбора набора инструкций присутствуют везде, таким образом, в одном наборе может быть только до 14 инструкуций по существу.
#IpCounter - (шесть декатронов) будет определять номер текущей исполняемой инструкции.
#LoopCounter - (три декатрона) для корректной перемотки циклов. сумматора в будущем компьютере нет, а значит, начало текущего цикла придется искать вручную, банально перематывая счетчик инструкции назад до тех пор, пока начало нашего цикла не будет найдено. Счетчик вложенных циклов поможет корректно искать нужное начало, даже если внутри нашего цикла множество вложенных. Счетчика от 0 до 999 будет более чем достаточно: в программах на Brainfuck, написанных людьми, даже больше 20–30 уровней вложенности циклов — редкость.
#ApCounter - (пять декатронов) Третий счетчик от 0 до 99 999 будет определять номер текущей ячейки данных. В исходном языке Brainfuck число ячеек 30000 - этот режим реализовать можно, но это будет ограничением функционала машины.
#DataCounter (три декатрона) По адресу счетчика ApCounter происходит выборка данных из ОЗУ. Данные помещаются в четвертый счетчик, который умеет считать от 0 до 255. То есть мы загружаем в декатрон наше старое значение, делаем инкремент или декремент и выгружаем данные обратно в память.


=== Debug ISA (ISAREG=0) ===
Структурно машину можно разбить на три больших блока:
 
#IpLine Block — Отвечает за выборку очередной инструкции из памяти программ.
# ApLine Block — Отвечает за исполнение инструкций касаемо данных — прогулки по памяти, изменение значения в ячейке, работа с терминалом
#MachineCtrl — Блок логики, объединяющий блоки работы с программой и данными, контролирующий работу машины и обеспечивающий связь с внешним миром.
 
Сами блоки состоят из модулей: многоразрядных реверсивных счётчиков, модулей памяти, буферов и т.п. Все эти базовые кирпичики имеют три линии управления: сигнал ЗАПРОС(Request) и флаг ГОТОВ(Ready). По сигналу ЗАПРОС, модуль счётчика, например, начнёт считать адрес новой инструкции. По сигналу ЗАПРОС, модуль памяти, например, начинает выгружать данные по новому адресу.[[Файл:DekatronPC.png|центр|безрамки|600x600пкс]]
 
====IpLine====
[[Файл:IpLine full.png|центр|безрамки|535x535пкс]]
Этот блок содержит два счётчика, модуль памяти программ и логику работы с циклами. Первый счётчик (IP Counter) на базе 6 декатронов определяет номер инструкции, которая считывается из памяти программ.
 
В дополнение к нему идёт счётчик глубины вложенности циклов (Loop Counter) — сумматора в будущем компьютере нет, а значит, начало или конец тела текущего цикла придётся искать вручную, банально шагая счётчиком инструкций назад (или вперёд) до тех пор, пока не будет найдено начало именно нашего цикла. Трёхразрядного счётчика будет более чем достаточно — в brainfuck-программах, написанных людьми, даже больше 20-30 уровней вложенности циклов — редкость.
 
Блок выборки инструкций, получив от блока логики сигнал ЗАПРОС, должен выдать следующую инструкцию на выходе. Дальнейшие действия блока зависят от текущей исполняемой инструкции. Если она не является условной — т.е. одна из +-<>., — то счётчику инструкций достаточно сделать +1, зачитать новую инструкцию из памяти программ и выдать её на выходной буфер. Делать это, кстати, можно одновременно с исполнением текущей инструкции в блоке данных. Да, тёплый ламповый конвейер — к моменту завершения текущей операции мы сможем сразу начать новую.
 
Сложности начинаются с инструкциями границ цикла. Надо обработать условную операцию и либо выполнить инструкции в теле цикла, либо нет. Вариантов тут четыре. Допустим, есть следующий код цикла, реализующий операцию MOV — Мы будем делать +1 в ячейке n+1, и -1 в ячейке n до тех пор, пока ячейка n не равна нулю.<syntaxhighlight lang="brainfuck">
[>+<-]
</syntaxhighlight>При выполнении этого цикла может быть четыре варианта действий:
 
#Мы на инструкции [ и текущая ячейка не равна нулю — нужно выполнить тело цикла.
#Мы на инструкции ] и текущая ячейка не равна нулю — нужно вернуться в начало цикла, чтобы выполнить его ещё раз.
#Мы на инструкции [ и текущая ячейка равна нулю — нужно промотать тело цикла, не выполняя его.
#Мы на инструкции ] и текущая ячейка равна нулю — выполнение цикла завершено просто идём дальше
 
Их можно обобщить в два варианта развития событий:
 
*При вариантах 1 и 4 компьютер просто продолжает выполнять инструкции друг за другом.
*Варианты 2 и 3 требуют промотать тело цикла. Счётчик будет считать либо назад(для варианта 2) либо вперёд(3) в поисках ответной скобки цикла.
 
Чтобы промотать тело цикла, нужно пошагово изменять значение счётчика инструкций, делать выборку инструкции по этому адресу и Не подавая её на выходной буфер, смотреть, что же за инструкция сидит по этому адресу. Например, если мы начали с открывающей скобки [, и идём вперёд — то при нахождении закрывающей скобки] промотку можно считать завершённой. Но вот в процессе промотки мы наткнулись на ещё одну открывающую скобку [ — от вложенного цикла. Тут-то и пригодится счётчик глубины вложенностей. В самом начале промотки на нашей оригинальной открывающей скобе [ делаем ему +1 и потом будем делать +1 всякий раз, встречая открывающую скобку [, и -1 встречая закрывающую скобку ]. Как только после очередной закрывающей скобки ] значение счётчика станет равным нулю — поиск можно останавливать — цикл мы промотали. Точно так же это работает и в обратную сторону, разве что скобки меняются местами.
[[Файл:LoopLookupLogic.png|центр|безрамки|450x450пкс]]
Технически этот подход реализуется довольно просто, поэтому отсутствие сумматора и возможности одним махом перепрыгивать тело цикла, как это было в релейном компьютере — совершенно не проблема. По крайней мере, эмуляция такой логики как на C++ так и на SystemVerilog работает прекрасно.[[Файл:IpLine FSM.png|центр|мини|IpLine FSM]]
Конечный автомат линии Ip Line объединяет в себе все основные стадии работы.
 
Так как блок состоит из двух счетчиков - IP Counter и Loop Counter, основной алгоритм работы конечного автомата - работа по внешнему кольцу состояний -
 
Готов -> Запрос нового адреса -> Запрос новой инструкции.
 
Однако, есть особые случаи:
 
#Сразу после сброса машины, на выходе счетчика уже находится адрес 0. Нужно сразу зачитывать инструкцию по этому адресу без инкремента счетчика.
#Если текущие инструкции - условные переходы [ ] и { } и условие перемотки инструкций выполняется - то одновременно поднимается CountRequest на оба счетчика.
#Если после выгрузки очередной инструкции оказывается:
##что значение LoopCounter == 0 - то перемотка завершена.
##что значение LoopCounter != 0 - то выдается новый IpCounterRequest сигнал
##что выставлен сигнал HaltRq - Система останавливается до снятия сигнала. в этом случае машина либо продолжит счет, либо перейдет в состояние IDLE
 
====ApLine====
[[Файл:ApLine full.png|центр|безрамки|445x445пкс]]
Блок работы с данными также содержит два счётчика и память данных. Кроме того, тут присутствуют модули ввода и вывода данных.
 
Один счётчик(AP Counter) считающий от 0 до 29999, будет определять номер текущей ячейки данных. Для чистого brainfuck необходимо будет сделать сброс старшего счётчика в нуль после 2 и наоборот. Один декатрон легко установить в нужное значение. Сложно прогнать сигналы переноса через все разряды.
 
По адресу этого счётчика происходит выборка данных из ОЗУ в четвёртый счётчик — Data Counter. Он умеет считать от 0 до 255. т.е. мы загружаем в декатрон наше старое значение, делаем инкремент или декремент и выгружаем данные обратно в память. Или же — мы можем напечатать текущее значение в терминале, или, минуя декатронный счётчик — занести число из терминала сразу в ОЗУ. Так как в программах на brainfuck инструкции инкремента/декремента ячейки ОЗУ и значения, как правило, идут группами, то это не значит, что потребуется постоянно загружать/выгружать данные в счётчик и обратно. Этого можно избежать, добавив флаг занятости ОЗУ
 
====MachineCtrl====
Блок соединяет вместе блоки ApLine и IpLine, содержит в себе основную машину состояний, а также декодер инструкций. Предоставляет пользовательский интерфейс с оператором и внешними устройствами.
 
==Набор инструкций (UPD: 13.06.2023г.)==
Основной набор инструкций - 8 инструкций языка brainfuck. Остальные инструкции служебные, используются для управления состоянием машины.
 
Каждая инструкция представлена в памяти 4-х разрядным значением, соответствующим тому или иному опкоду. Чтобы увеличить количество инструкций используется специальный регистр ISAREG, определяющий текущий набор команд - Debug ISA и Brainfuck ISA. 
 
#ISAREG=0 - Debug ISA - режим, в котором машина находится после включения. в нем доступны инструкции очистки ОЗУ, сброса состояния машины, команды загрузки данных с перфоленты. Предполагается, что первоначальный загрузчик, после чтения программы с перфоленты переключит набор команд в Brainfuck ISA и машина начнет исполнять инструкции загруженной программы
#ISAREG=1 - Brainfuck ISA - основной режим, в котором доступны 8 инструкций языка brainfuck плюс несколько дополнительных.
 
Часть инструкций присутствует в обоих наборах - NOP, HALT, ISA0, ISA1
 
===Debug ISA (ISAREG=0)===


{| class="wikitable"
{| class="wikitable"
|-
|-
! Символ !! Опкод !! Brainfuck !! название !! описание
!Символ !!Опкод!!Brainfuck!! название!!описание
|-
|-
| N || 0x0   ||         ||NOP || No operation - Must be in both ISA set
| N||0x0|| || NOP||No operation - Must be in both ISA set
|-
|-
|   H|| 0x1   ||         ||HALT|| Must be in both ISA set
|H||0x1|| ||HALT||Must be in both ISA set
|-
|-
|   || 0x2   ||         || ||
|\a ||0x2|| ||BELL||Ring the bell
|-
|-
|   || 0x3   ||         || ||
| || 0x3|| || ||UNDEFINED
|-
|-
| || 0x4 || || ||
| E||0x4 || || EOT|| End Of Transmission
|-
|-
| ||0x5   || || ||
| S||0x5 || ||SOT||Start Of Transmission - To load Data from Punch/Mangetic Tape
|-
|-
| { || 0x6   ||         ||LABEG || Если текущий адрес равен нулю - пропустить тело цикла
|{||0x6|| || LABEG ||Если текущий адрес равен нулю - пропустить тело цикла  
|-
|-
| } || 0x7   ||         ||LAEND || Если текущий адрес не равен нулю - выполнить итерацию цикла  
| }||0x7|| || LAEND||Если текущий адрес не равен нулю - выполнить итерацию цикла
|-
|-
| L || 0x8   ||         ||CLRL || Сбросить счетчик глубины вложенностей циклов
|L||0x8|| ||CLRL||Сбросить счетчик глубины вложенностей циклов  
|-
|-
| I || 0x9   ||         ||CLRI || Сбросить счетчик инструкций
|I||0x9 || ||CLRI||Сбросить счетчик инструкций  
|-
|-
| 0 || 0xA   ||         ||CLRD || Сбросить счетчик данных
|0||0xA || || CLRD || Сбросить счетчик данных
|-
|-
| A || 0xB   ||         || CLRA   || Сбросить счетчик адреса (Что делать с флагом захвата?)
|A|| 0xB|| ||CLRA||Сбросить счетчик адреса (Что делать с флагом захвата?)
|-
|-
|   || 0xC   ||         ||||  
|R||0xC|| ||HRST||Hard Reset
|-
|-
| R || 0xD   ||         ||RST|| Hard reset
| r||0xD || ||SRST||Soft reset
|-
|-
| D || 0xE   ||         ||ISA2|| Set ISAREG=0 - Debug ISA
|D||0xE|| ||ISA0||Set ISAREG=0 - Debug ISA  
|-
|-
| B || 0xF   ||         ||ISA3|| Set ISAREG=1 - Brainfuck ISA  
|B|| 0xF|| ||ISA1|| Set ISAREG=1 - Brainfuck ISA
|}
|}


=== Загрузчик ===
===Brainfuck ISA (ISAREG=1)===
 
загрузчик - код, который будет выполняться сразу после включения машины и подачи тактирования. Расположен по нулевому адресу в памяти.
Bootloder is the code, which is performed after reset vector. In placed on the instruction address 0x00000;
 
==== Очистка памяти ====
 
После включения или перезагрузки, в ОЗУ данных может быть мусор. По правилам brainfuck - все ячейки должны изначально иметь нулевое состояние, в С такой код выглядит следующим образом:
 
<syntaxhighlight lang="c">
  for (i = 0; i < 30000; ++i)
  {
    Memory[i] = 0;
  }
</syntaxhighlight>
 
В формате инструкций компьютера DekatronPC, начальный код загрузчика выглядит так:
 
<syntaxhighlight lang="c">
  A0> //Установка счетчика адреса в нуль, Обнуление текущей ячейки данных и выбор следующей
  {  // Пока текущее значение счетчика адреса не равно нулю:
    0 >//Обнуление текущей ячейки данных и выбор следующей
  }
  B //Выбор Brainfuck ISA
</syntaxhighlight>
 
=== PunchTape ISA (ISAREG=0) (в составе Debug ISA) ===
 
Предназначен для загрузки данных с перфоленты в память программ. Как именно это сделать - пока не понятно. Так как загрузчик использует счетчик инструкций и часть памяти программ для себя. Следовательно, необходимо реализовать возможность использования счетчика адреса в этих целях. Однако, счетчик адреса не в состоянии покрыть ведь диапазон памяти программ.
 
Второй вариант - использовать счетчик адреса загрузчиком. Но тогда не получится очистить память данных от мусора.
 
Третий вариант наиболее предпочтителен - использовать аппаратный способ загрузки - когда синхросигнал с перфоленты будет инкрементировать значение счетчика инструкций, а другой сигнал - подавать сигнал записи в память. Таким образом можно инструкцией запустить этот процесс и дальше аппаратные средства сделают все самостоятельно.


=== Brainfuck ISA (ISAREG=1) ===
Помимо восьми основных brainfuck-инструкций имеет еще 6 дополнительных. Особое внимание стоит уделить инструкциям CLRML, LOAD, STORE


Помимо восьми основных brainfuck-инструкций имеет еще 8 дополнительных. Особое внимание стоит уделить инструкциям CLRML, LOAD, STORE
Они могут быть использованы для копирования данных в памяти. Счетчик данных может быть использован как временный регистр.
 
Они могут быть использованы для копирования данных в памяти. счетчик данных может быть использован как временный регистр.


Допустим, нужно скопировать данные из ячейки А в ячейку Б.
Допустим, нужно скопировать данные из ячейки А в ячейку Б.


# Счетчик адреса устанавливается на ячейку А
#Счетчик адреса устанавливается на ячейку А
# Дается команда LOAD - данные загружаются из памяти в счетчик данных
#Дается команда LOAD - данные загружаются из памяти в счетчик данных. MemLock не изменяется.
# Стирается флаг памяти - CLRML. Возможно имеет смысл команду LOAD делать без поднятия флага, тогда эта операция будет не нужна
##Если далее идут команды +- - произойдет повторная загрузка данных с учтановкой MemLock плюс выполнится инструкция +-
# Счетчик адреса устанавливается на ячейку Б
##Если далее идут команды ., -обмен данными будет осуществляться непосредственно с ОЗУ
# Дается команда STORE. значение из счетчика данных выгружается в ячейку памяти Б  
#Счетчик адреса устанавливается на ячейку Б
#Дается команда STORE. Значение из счетчика данных выгружается в ячейку памяти Б


{| class="wikitable"
{| class="wikitable"
|-
|-
! Символ !! Опкод !! Brainfuck !! название !! описание
!Символ!!Опкод!!Brainfuck!!название!!описание
|-
|-
| N || 0x0   ||         ||NOP || Пустая инструкция
|N||0x0|| ||NOP ||Пустая инструкция
|-
|-
| H || 0x1   ||         ||HALT || Останов машины
|H||0x1 || ||HALT||Останов машины
|-
|-
| + || '''0x2'''   ||     '''+'''     ||INC || Increment of Current data cell
| +||'''0x2'''|| '''+'''||INC||Increment of Current data cell
|-
|-
| - || '''0x3'''   ||     '''-'''     ||DEC || Decrement of current data cell
| -||'''0x3'''||'''-'''||DEC||Decrement of current data cell
|-
|-
| > || '''0x4'''   ||     '''>'''     ||AINC || Increment of address pointer
|>||'''0x4'''||'''>'''||AINC|| Increment of address pointer
|-
|-
| < || '''0x5'''   ||     '''<'''     ||ADEC || Decrement of address pointer
|<||'''0x5'''|| '''<'''||ADEC||Decrement of address pointer  
|-
|-
| [ || '''0x6'''   ||     '''['''     ||LBEG || If current data cell equal zero, skip the loop
| [||'''0x6'''||'''['''||LBEG||If current data cell equal zero, skip the loop  
|-
|-
| ] || '''0x7'''   ||     ''']'''     ||LEND|| If current data cell not equal zero, repeat loop iteration
|]||'''0x7'''||''']'''||LEND||If current data cell not equal zero, repeat loop iteration
|-
|-
| . || '''0x8'''   ||     '''.'''     ||COUT|| Print current symbol to the terminal
| .||'''0x8'''||'''.'''||COUT||Print current symbol to the terminal  
|-
|-
| , || '''0x9'''   ||     ''','''     ||CIN || Read symbol from the terminal (Blocked acces - Program halted while no symbol)
| ,||'''0x9'''|| ''','''||CIN ||Read symbol from the terminal (Blocked acces - Program halted while no symbol)
|-
|-
| 0 || 0xA   ||         '''[-]'''||CLRD || Basic brainfuck optimization: Write zero to current Data Cell  
|0||0xA||'''[-]'''||CLRD||Basic brainfuck optimization: Write zero to current Data Cell
|-
|-
| M || 0xB   ||         ||CLRML|| Clear memory lock
|M|| 0xB|| ||CLRML||Clear memory lock
|-
|-
| G || 0xC   ||         ||LOAD|| Explicit Load from current memory cell to Data Counter
| G||0xC || ||LOAD|| Explicit Load from current memory cell to Data Counter, MemLock not affected
|-
|-
| S || 0xD   ||         ||STORE|| Explicit Store from Data Counter to current memory cell
|P||0xD|| ||STORE || Explicit Store from Data Counter to current memory cell, MemLock not affected
|-
|-
| D || 0xE   ||         ||ISA2|| Set ISAREG=0 - Debug ISA
|D||0xE|| ||ISA0||Set ISAREG=0 - Debug ISA
|-
|-
| B || 0xF   ||         ||ISA3|| Set ISAREG=1 - Brainfuck ISA  
|B||0xF|| ||ISA1 ||Set ISAREG=1 - Brainfuck ISA
|}
|}


=== Формат записи на магнитную ленту ===
===Начальный загрузчик (bootloader) ===
 
Загрузчик - код, который будет выполняться сразу после включения машины и подачи тактирования.
 
Одной из идей является установка IpCounter в 999900 - и последние 100 инструкций занять начальным загрузчиком.
 
Для этого блок MachineCtrl предоставляет два вида сброса машины.
 
====Hard Reset====
Этот тип сброса очищает все возможные флаги и устанавливает адрес IpCounter на начало загрузчика. Если тумблер на панели разрешает работу загрузчика автоматически - пускает его. В противном случае будет ждать кнопки Run.<syntaxhighlight lang="verilog">
ApCounter <= 0;
DataCounter <= 0;
LoopCounter <= 0;
MemLock <= 0;
RamDataReady <= 0;
IpCounter <= 20'h999900;
//User switch to run bootloader after Hard Reset
if (RunBootloader)
    MachineState <= RUN;
else
    MachineState <= HALT;
</syntaxhighlight>
 
====Soft Reset====
Этот тип сброса очищает все возможные флаги и устанавливает все счетчики в нуль. Отличие в том, что после Hard Reset стартует загрузчик, после Soft Reset - загруженная программа. Если тумблер на панели разрешает работу компьютера автоматически - пускает его. В противном случае будет ждать кнопки Run.<syntaxhighlight lang="verilog">
ApCounter <= 0;
DataCounter <= 0;
LoopCounter <= 0;
MemLock <= 0;
RamDataReady <= 0;
IpCounter <= 0;
//User switch to run program after Soft Reset
if (RunBootloader)
    MachineState <= FETCH;
else
    MachineState <= HALT;
</syntaxhighlight>
 
====Очистка памяти====


Если использовать кассетный или бобинный магнитофон (типа ламповой коменты или яузы) для хранения программ и их последующего ввода в память машины, можно использовать [https://ru.wikipedia.org/wiki/DTMF DTMF]-сигналы, когда двумя синусоидами кодируется до 16 символов. Так как программа пишется 4-х битовыми пачками, так что в одном сигнале сразу будет готовая инструкция. По завершении записи на ленте формируется прерывистый сигнал 0x01(HALT)
После включения или перезагрузки, в ОЗУ данных может быть мусор. По правилам brainfuck - все ячейки должны изначально иметь нулевое состояние, в С такой код выглядит следующим образом:
 
<syntaxhighlight lang="c">
  for (i = 0; i < 30000; ++i)
  {
    Memory[i] = 0;
  }
</syntaxhighlight>
 
В формате инструкций компьютера DekatronPC, начальный код загрузчика выглядит так:
 
<syntaxhighlight lang="c">
  A0> //Установка счетчика адреса в нуль, Обнуление текущей ячейки данных и выбор следующей
  {  // Пока текущее значение счетчика адреса не равно нулю:
    0 >//Обнуление текущей ячейки данных и выбор следующей
  }
</syntaxhighlight>
 
===Программирование машины===
[[Файл:DekatronPC program load.png|центр|безрамки|450x450пкс]]В наборе инструкций есть две специальные - SOT(StartOfTransmission) и EOT(EndOfTransmission). Первая должна располагаться по адресу 999999h, ее выполнение осуществляет инкремент счетчика программ и переключает FSM машины в режим разгрузки программы. Имеется два интерфейса для входных данных:
 
#Один принимает ASCII символы, например со считывателя перфолент, накопителя на магнитной ленте, печатной машинки Consul 260.
#Второй принимает непосредственно 4-х битовые опкоды инструкций. Либо с первого интерфейса через конвертер, либо с других устройств, например со считывателя с магитной кассеты, или считывателя перфолент в опкодах.
 
На уровне OpCode производится самостоятельное переключение между наборами Debug/Brainfuck
 
По синхроимпульсу проверяется условие (CurrentInsn != EOT)  и производится запись опкода в текущую ячейку памяти программ и последующий инкремент счетчика программ. Если условие не выполняется - т.е. текущая инструкция EOT - то автоматически вызывается Soft Reset машины. ЭВМ готова для выполнения загруженной программы.
 
====Инструкции для работы со считывателем перфолент (в составе Debug ISA)====
Предназначен для загрузки данных с перфоленты в память программ.


== Декатронные счетчики==
Текущая идея следующая: использовать аппаратный способ загрузки - когда синхросигнал с перфоленты будет инкрементировать значение счетчика инструкций, а другой сигнал - подавать сигнал записи в память. Таким образом можно инструкцией запустить этот процесс и дальше аппаратные средства сделают все самостоятельно.  
Декатронный счетчик представляет собой реверсивный многоразрядный счетчик на базе нескольких декатронов.


В ламповом компьютере требуется 4 таких счетчика с общим количеством декатронов в 17 штук.
Специальная инструкция StartOf Transmission сбрасывает счетчик IpCounter в нуль и переключает машину в режим счета-записи по внешнему синхроимпульсу. т.е.<syntaxhighlight lang="verilog">
initial begin
    IpCounter <= 0;
MachineState <= COUNTER;
end


Функционал счетчика:
always @(posedge WriteSync) begin
IRAM.Write(IpCounter.value, Insn);
IpCounter <= Ipcounter + 1;
if (Insn == EOT)//Tape is loaded
    MachineState <= SOFT_RESET;
end
</syntaxhighlight>


* Инкремент и декремент текущего числа счетчика
====Формат записи на магнитную ленту ====
** Для работы в режиме счета от 0 до 255 необходимо выставить TOP_LIMIT_MODE=1. Тогда по достижении счетчиком числа TOP_VALUE  вместо инкремента будет происходить запись 0 в счетчик. По достижении 0 и при декременте - в счетчик будет записано TOP_VALUE.
Если использовать кассетный или бобинный магнитофон (типа ламповой коменты или яузы) для хранения программ и их последующего ввода в память машины, можно использовать [https://ru.wikipedia.org/wiki/DTMF DTMF]-сигналы, когда двумя синусоидами кодируется до 16 символов. Так как программа пишется 4-х битовыми пачками, так что в одном сигнале сразу будет готовая инструкция.  По завершении записи на ленте формируется прерывистый сигнал 0x01(HALT)
* Запись числа в счетчик со входа In, заданного в формате 8-4-2-1
* Чтение числа из счетчика на выход Out, в формате 8-4-2-1


Все счетчики работают синхронно от сигнала тактирования и имеют следующие входы управления
===Оптимизация доступа к памяти===
Допустим, код на bf выгладит следующим образом:<syntaxhighlight lang="brainfuck">
>>>>>+++++<<<<<
</syntaxhighlight>В наивном режиме выполнения произведется следующий алгоритм:<syntaxhighlight lang="cpp">
for (i = 0; i < 5; i++){
    ApCounter.Inc();
    DataCounter.Store(Ram.Load(ApCounter));
}
for (i = 0; i < 5; i++){
    DataCounter.Inc();
    Ram.Store(ApCounter, DataCounter.Load);
}
for (i = 0; i < 5; i++){
    ApCounter.Dec();
    DataCounter.Store(Ram.Load(ApCounter));
}
</syntaxhighlight>Таким образом помимо 15 операций со счетчиками будет 15 операций работы с памятью, совершенно бесполезных. По факту мы девять раз просто так будем делать загрузку-выгрузку. Проще перед первым инкрементом данных один раз сделать  сделать '''LOAD''' из памяти в счетчик, а после последнего вызвать '''STORE''' обратно из счетчика в ОЗУ.  За основу взят принцип Memlock.<syntaxhighlight lang="cpp" line="1">
insn = DPC.fetch(IpCounter);
if (((insn == "+")|(insn=="-"))& !MemLock){
    DataCounter.Store(Ram.Load(ApCounter));
    MemLock = true;
}
if (((insn == "<")|(insn==">"))& MemLock){
    Ram.Store(ApCounter, DataCounter.Load());
    MemLock = false;
}
DPC.exec(insn);
</syntaxhighlight>Тогда код на bf будет выполняться следующим образом: <syntaxhighlight lang="cpp">
for (i = 0; i < 5; i++){
    ApCounter.Inc();
}
DataCounter.Store(Ram.Load(ApCounter));
for (i = 0; i < 5; i++){
    DataCounter.Inc();
}
Ram.Store(ApCounter, DataCounter.Load);
for (i = 0; i < 5; i++){
    ApCounter.Dec();
}
</syntaxhighlight>Итого осталось 15 операций со счетчиками и только две операции работы с ОЗУ.


* Dec - выбор направления счета - в прямую сторону (лог.0) и обратную сторону (лог.1)
==Конструктив машины==
* Count - при наличии этого сигнала по нарастающему фронту Clk  совершается операция инкремента(Dec=0) и декремента(Dec=1) счетчика
* SetZero - при наличии этого сигнала по нарастающему фронту Clk совершается запись нуля в счетчик
* Set - при наличии этого сигнала по нарастающему фронту Clk производится запись числа со входа In  в счетчика


===Модуль===
Модуль представляет собой печатную плату размером 140х140мм с краевым разъемом 3х36 пин либо разъемом ГРПМШ-31. На плате располагаются непосредственно лампы, и схемы обвязки. Несколько видов базовых плат, реализует всю возможную схемотехнику. Платы на базе краевого разъема в приоритете. Предлагается заблокировать один ряд пинов для создания ключа - так не получится платы одного типа воткнуть в разъем для другого типа плат
{| class="wikitable"
{| class="wikitable"
|+Лампы по платам работы с декатроном
|
!Платы
!Триоды
!Диоды
|-
|Схема чтения
|2
|8
|-
|-
|Схема записи
|[[Файл:DekatronPC module.png|300пкс]]||[[Файл:Dekatronpc module 140x200.png|300пкс]]
|29
|0
|-
|-
|Управление, перенос
| Модуль 140х140мм с краевым разъемом 2х36пин. || Первое поколение плат. Модуль 140х200мм с разъемами ГРПМШ-31
|5
|6
|}
{| class="wikitable"
|+Лампы по счетчикам
!Счетчик
!Функционал
!Чтение
!Запись
!Управление
!Декатроны
!Диоды
!Триоды
|-
|IP Counter
|Сброс в нуль, Чтение данных, Zero
|6
|0
|6
|6
|84
|42
|-
|AP Counter
|Сброс в нуль, Чтение данных, Zero
|5
|0
|5
|5
|70
|35
|-
|Data Counter
|Сброс в нуль, запись данных, чтение данных, Zero
|3
|3
|3
|3
|42
|108
|-
|Loop Counter
|Сброс в нуль, Zero
|0
|0
|3
|3
|18
|15
|-
|Всего
|
|14
|3
|17
|17
|214
|200
|}
|}


=== Экспериментальная декатронная ячейка ===
===Блок===
Ячейка представляет собой блок 3U-блок на 4 платы, и реализует полную схемотехнику управления декатроном, включая чтение, запись и пересчет с переносом.
Блок представляет собой полноценный узел машины - IpLine, ApLine или MachineCtrl. Возможно в дальнейшем понадобится увеличить количество блоков.
[[Файл:DekatronPC block.png|центр|безрамки|450x450пкс]]
За передней панелью блока скрывается источник питания, на базе одного торроидального трансформатора и выпрямителей вокруг него. Далее идет ряд вентиляторов, затем - три ряда плат модулей, стоящих с шагом 24мм для логики или 36мм для плат с декатронами. Три ряда плат, с шагом 24мм для логики и 36мм для плат с декатронами. Теоретическая вместимость каждого блока 768 ламп.
[[Файл:DekatronPCblock1.png|центр|безрамки|780x780пкс]]
Платы располагаются ближе к задней стороне чтобы все провода между модулями а также к задним разъемам были минимальной длины. На самом блоке располагаются разъемы для модулей, а в подвале сформирована область для соединения модулей между собой. Подобная схема использовалась в ЭВМ [[wikipedia:Bendix_G-15|Bendix G15]]А посмотреть ее воочию, можно у [https://www.youtube.com/watch?v=-RGp-bsYf34&ab_channel=UsagiElectric Usagi в видеоролике]Скорее всего все соединения будут производиться пайкой, А схема подключения - браться их yosys
[[Файл:DPC Back wiring.png|центр|безрамки|771x771пкс]]


Блок необходим для отладки схемотехники управления декатроном, особенно схемы записи числа в счетчик.
=== Питание ===
Каждый блок питает себя сам. Изначально идея была поместить в каждый блок только накальные трансформаторы типа ТН61. Однако для полной загрузки блока нужно 4-5 трансформаторов и в ряд они не лезут, а в иной компоновке - съедают слишком много места.  Таким образом требуются заказные торроидальные многообмоточные трансформаторы - которые будут выдавать все необходимые напряжения питания.  При этом если накала на весь блок нужно порядка 300А. Лучшим вариантом на данный момент я считаю сделать 6 накальных обмоток по 50А каждая - по две обмотки на ряд.


Основная плата - плата декатрона. На ней располагаются непосредственно сам декатрон, схема чтения, включающая в себя преобразователь двоичного-кода в двоично десятичный на диодах и катодные повторители-усилители. Отдельно идет катодный повторитель для сигнала нуля.
В РФ изготовлением трансформаторов занимаются [http://www.torel.ru/ ТОРЭЛ] и [https://tula-transformator.ru/trans_t.html Тульский завод трансформаторов]. ТОРЭЛ запросил 33к за трансформатор, в тульский завод я ТЗ еще не отправлял - нужно окончательно определиться с начинкой блоков и количеством ламп в каждом из них, а также по необходимым напряжениям питания.  


Также есть схема переноса. Технически это тройная защелка, имеющая два выхода, которые подсвечивают крайние положения - 0 и 9 до момента полного переключения лампы. т.е. этот блок помнит последнее состояние лампы пока идут процессы переключения.
Считается, что входное напряжение стабильно по ГОСТ (+-10%). Анодное напряжение не стабилизируется, накальное не стабилизируется. Маломощные напряжения смещения снабжаются линейными стабилизаторами на базе 6С19П<ref>К.Б. Мазель  Стабилизаторы напряжения и тока. госэнергоатомиздат 1955</ref>.


Выход - 30-контактный. На нем есть все линии декатрона на запись, напряжения питания. накал, а также - двоично-десятичный выход 8-4-2-1
====Охлаждение====
[[Файл:Dekatron up down unit.png|центр|безрамки|952x952пкс]]
В блоке установлены мощные 120мм вентиляторы NMB 4710PS-23T-B20 с питанием от 220В для отведения тепла. Мощность 9Вт, 1900об/мин, производительность 1.4м^3/мин при создаваемом давлении 23.5Па.
Еще две платы примерно одинаковые, их задача - преобразовать двоично-десятичный вход 8-4-2-1 в двоичный с сигналом записи - для этого требуется 4 инвертора, и 5-входовый И - на двух сдвоенных триодах, где анод-катод - это 4 линии и пятая линия - сетка.
[[Файл:Dekatron cell up down WSU.png|центр|безрамки|758x758пкс]]
К этим двум платам пока вопросы. На две платы следующие задачи:


# Инверторы входных сигналов 8-4-2-1. Итого имеем 8 сигналов - прямые и инверсные, которыми можем набрать нужную комбинацию сигналов для следующего этапа:
Измерение декатронной ячейки анемометром показывает скорость воздуха 2.4м/с, что при трех вентиляторах дает производительность 5.8м^3/мин, а на один - 1.9м^3/мин - что плюс-минус корректно. В час 350м^3. Для охлаждения лампы ГУ-5 с рассеиваемой мощностью 3.5кВт достаточным является охлаждение в 400м^3/час. Так что должно хватить.
# Пятивходовые И на двух сдвоенных триодах, где сетка - это пятый сигнал записи. Им на вход подаются сигналы набранные в нужной комбинации на первом этапе.
# Усилители записи - 10 штук. По одному на каждый катод. И тут вопрос - либо они будут работать в статическом режиме, либо в импульсном. Первый вариант требует переход в отрицательные уровни напряжения. Второй позволяет обойтись без них, с помощью развязывающих конденсаторов формировать импульсы нужной длительности и амплитуды.
# Усилители сигналов управления подкатодами. тут опять вопрос к режиму работы. Скорее всего я приду к импульсному варианту - он проще и по нему есть все необходимые схемы.


==== Источники питания: ====
В принципе, 4U серверные корпуса способны выделять 2-3кВт тепла и при наличии активного охлаждения они не перегреваются. Требуется модель openFoam и натурные эксперименты для измерения характеристик нагрева:


* ТСШ-170 - предназначен для выработки основного питания +150В, а также пары накальных линий для 6С19П. Трансформатор проверен на сопротивление изоляции.
#Измерить поток воздуха и создаваемое давление от используемых вентиляторов
* ТН61 - общей мощностью 190Вт. Имеет 4 линии 6.3В  - 3 по 8А и 1 машина - 6.1А.  Будет обеспечивать основное питание накалов ламп, разбитых на группы по смещениям.
#Загрузить 3D модель блока с платами с лампами в openFoam и просчитать потоки воздуха
* ТА48, мощностью 36Вт - питание декатрона +500В (технически сам источник будет на +350В), а также напряжение смещения -50В.
#Подать питание на сверхминиатюрку и обеспечить на ней необходимое тепловыделение, нарисовать график нагрева в закрытом пространстве
*ТА, мощностью 15Вт
##То же, но при наличии активного обдува.
Схемы питания берем из блоков питания осциллографов [[С1-54 (Осциллограф)|С1-54]] и [[EMG TR-4401|TR4401]]


==== Модули декатронного счетчика ====
===Стойка===
Схема декатронного счетчика содержит две большие группы элементов- обязательная для любого из декатронов и необходимая схемотехнически.
[[Файл:DekatronPCrack.png|центр|безрамки|462x462пкс]]


Обязательной является:
==Дорожная карта проекта==


# обвязка самого декатрона,  
Сейчас у меня собрано все железо, нужное для начала экспериментов, в том числе полторы тысячи сверхминиатюрных ламп - 6Н16Б, 6Х7Б и 6Ж2Б. Продолжается долгий и интересный процесс проектирования и сборки будущей машины.
# усилители-формирователи управляющих испульсов, 1 лампа(?)
# трех-позиционная защелка схемы переноса 8 ламп(?)
# усилители-формирователи линии сброса в 0 и в Х (например в 5 для счетчика до 255), 1 лампа(?) - можно вынести на отдельную плату


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


Необходимая обвязка:
Теперь о главном -


# Схема преобразователя позиционного кода в двоично-десятичный - 11 ламп
Два мелких ребенка сильно замедляют продвижение по проекту.
# Схема усилителей-формирователей позиционных линий для любого из катодов. Два усилителя находятся в обязательной секции, поэтому остается оп 8 линий на декатрон.  Для счетчика данных требуется в общей сложности 17 линий. Можно округлить до 18 линий и разместить на 1-2 платах. Если в одну плату обязательная обвязка влезать не будет - то для счетчика данных требуется 23 линии, а для любого счетчика - от 6 до 10 линий. Исходя из этих данных нужно определиться с числом линий - однако нужно окончательно определиться со схемотехникой и определить требуемое количество ламп на одну линию.
# Схема декодера из двоично-десятичного в позиционный код. Требует по две лампы на линию. Вероятно собираться будет на базе элементов И.


== IpLine ==
=== Стадия 1: Проектирование (UPD: 25.06.2023) <= Вы находитесь здесь ===
[[Файл:IpLine FSM.png|центр|мини|IpLine FSM]]
Самая важная стадия проекта - разработка принципиальной схемы машины. Необходимо закрыть все этапы прежде чем двигаться дальше.
Конечный автомат линии Ip Line объединяет в себе все основные стадии работы.


Так как блок состоит из двух счетчиков - IP Counter и Loop Counter, основной алгоритм работы конечного автомата - работа по внешнему кольцу состояний -  
====Этап 1.1: Верификационная программная модель C++ (UPD: 25.06.2023)====
Описание: При этом поведение модели такое же как будет в железе - 4 счетчика - для верификации алгоритма исполнения программ на brainfuck только на счетчиках.  .


Готов -> Запрос нового адреса -> Запрос новой инструкции.
Задачи:


Однако, есть особые случаи:
* Высокоуровневая программная симуляция поведения мышины
* Верификационная модель для эмулятора


# Сразу после сброса машины, на выходе счетчика уже находится адрес 0. Нужно сразу зачитывать инструкцию по этому адресу без инкремента счетчика.
Прогресс:
# Если текущие инструкции - условные переходы [ ] и { } и условие перемотки инструкций выполняется - то одновременно поднимается CountRequest на оба счетчика.
# Если после выгрузки очередной инструкции оказывается:
## что значение LoopCounter == 0 - то перемотка завершена.
## что значение LoopCounter != 0 - то выдается новый IpCounteRequest сигнал
## что выставлен сигнал HaltRq - Система останавливается до снятия сигнала. в этом случае машина либо продолжит счет, либо перейдет в состояние IDLE


== DekatronPC Challenge==
* Создан [https://github.com/radiolok/bfutils/tree/master/dpcrun программный эмулятор на языке C++] Модель поддерживает только 8 базовых инструкций языка Brainfuck и требует незначительной доработки для дополнения остальными инструкциями.
* На данный момент модель подключена  к Verilator<ref>https://www.veripool.org/verilator/</ref> и обеспечивает пошаговое сравнение Verilog-модели с C++ моделью


Сейчас у меня собрано все железо, нужное для начала экспериментов, в том числе полторы тысячи сверхминиатюрных ламп - 6Н16Б, 6Х7Б и 6Ж2БПродолжается долгий и интересный процесс проектирования и сборки будущей машины. В отличие от релейного компьютера с его монолитной конструкцией, здесь конструкция блочная.
==== Этап 1.2: Виртуальный эмулятор лампового компьютера (UPD: 25.06.2023)<ref>Д. Томас. Логическое проектирование и верификация систем в SystemVerilog</ref><ref>А.Ю. Романов. Ю.В.Панчул. Цифровой синтез. Практический курс. ДМК 2020</ref><ref>Харрис и Харрис. Цифровая схемотехника и архитектура компьютера. ДМК.  2017</ref><ref>Й. Янсен. Курс цифровой электроники в 4-х частях. изд Мир1987</ref> ====
Архитектура машины [https://github.com/radiolok/dekatronpc/tree/master/vhdl/DekatronPC реализуется]на языке Verilog. На данный момент модель уже умеет исполнять программу Hello World! Идет активная переработка исходного кода. Также, на базе Verilator создано окружение виртуального эмулятора - он позволяет отлаживать прошивку Эмулятора без физического доступа к железу, в виде C++ приложения, в котором код Эмулятора пишется на языке Verilog.


==== Этап 1: Верификационная программная модель C++ (UPD: 19.05.2023) ====
Задачи:  
Создан [https://github.com/radiolok/bfutils/tree/master/dpcrun программный эмулятор на языке C++]. При этом поведение модели такое же как будет в железе - 4 счетчика - для верификации алгоритма исполнения программ на brainfuck только на счетчиках. Модель поддерживает только 8 базовых инструкций языка Brainfuck и требует доработки для дополнения остальными инструкциями. В итоге модель должна стать блоком для верификации дизайна на Verilog.


Завершением этапа будет программный код, поддерживающий расширенный набор инструкций описанный выше.
* Программная эмуляция схемотехники будущей машины 
* Синтез принципиальной логической схемы лампового компьютера - с помощью yosys и библиотеки элементов 
* Временной анализ (на основании экспериментальных данных со второй стадии проекта) 
* Анализ энергопотребления 


==== Этап 2: FPGA-Эмулятор лампового компьютера (UPD: 22.05.2023) ====
Прогресс:
Архитектура машины [https://github.com/radiolok/dekatronpc/tree/master/vhdl/DekatronPC реализуется]на языке Verilog. А также изготавливается [[DekatronPC эмулятор|эмулятор лампового компьютера на базе ПЛИС]]. На данный момент модель уже умеет исполнять программу Hello World! Идет активная переработка исходного кода. Также, на базе Verilator создано окружение виртуального эмулятора - он позволяет отлаживать прошивку Эмулятора без физического доступа к железу, в виде C++ приложения, в котором код Эмулятора пишется на языке Verilog.


Прогресс:  
* [https://github.com/radiolok/dekatronpc/tree/master/vhdl Verilog-модель] поддерживает все 8 инструкций brainfuck, а также несколько других. 
* Виртуальный эмулятор доступный для запуска кем угодно 


Verilog-модель поддерживает 7 инструкций brainfuck - кроме CIN. Не проходит тест с вычислением числа Pi - Вероятно какие-то проблемы с вложенными циклами. 
Тестирование:


Надо сделать еще один тест для вложенных циклов, а также подключить C++ модель для пошагового выполнения и сравнения двух результатов.
* Ведется в среде Verilator и позволяет провести функциональную эмуляцию схемотехники будущей машины
 
Тестирование:
{| class="wikitable"
{| class="wikitable"
|+
|+
Строка 435: Строка 608:
|PASSED
|PASSED
|-
|-
|Counter
|Counter  
|PASSED
|PASSED
|-
|-
|IpLine - LoopTest
|IpLine - LoopTest  
|PASSED
|PASSED
|-
|-
|Hello World
|ApLine
|PASSED
|-
|Hello World  
|PASSED
|PASSED
|-
|-
|Pi
|Pi
|FAILED
|PASSED
|-
|-
|
| ROT13
|
|PASSED
|}
|}
В завершении этапа будет синтезируемый код на языке Verilog, работающий на FPGA-эмуляторе и позволяюющий запускать любые программы языка brainfuck


==== Этап 3: Экспериментальная декатронная ячейка (UPD: 19.05.2023) ====
=== Стадия 2: Прототипирование(UPD: 25.06.2023) ===
Параллельно, ведется третий этап - изготовление экспериментальной декатронной ячейки, задача которой - отладка схемотехники управления декатроном - чтение, запись, счет.  
Следующая стадия - изготовление отдельных элементов компьютера - для проверки корректности работы схем, измерения режимов работы и т.п.


==== Этап 4: Сборка в железе ====
====Этап 2.1: FPGA-Эмулятор лампового компьютера (UPD: 07.06.2023)====
[[Файл:DPC FPGA EMULATOR.png|центр|безрамки|450x450пкс]]
[[DekatronPC эмулятор|эмулятор лампового компьютера на базе ПЛИС]]. имеет две основные задачи
 
* Физическая визуализация эмулятора
* Эмуляция (Замещение) еще несуществующих/несобранных блоков будуей ЭВМ
 
На данный момент сам эмулятор собран, в нем находится старая демонстрационная прошивка. По завершении этапа 1.2 - прошивка обновится и эмулятор будет вести себя как настоящий ламповый компьютер.
 
Сзади компьютер оснащен разъемами для подключения блоков. Проектно поддерживается 128 входов и 128 выходов. Практически число может быть другим.
 
====Этап 2.2: Экспериментальная декатронная ячейка (UPD: 19.05.2023)====
Параллельно, ведется изготовление экспериментальной декатронной ячейки, задача которой - отладка схемотехники управления декатроном - чтение, запись, счет. Ее описание - выше.
 
==== Этап 2.3: Разработка модулей ламповой логики ====
Результатом данного этапа будут платы - прототипы модулей ламповой логики. <ref>А.М. Бонч-Бруевич. Применение электронных ламп в экспериментальной физике. изд-е 4. М. 1956</ref><ref>Handbook of electronic control circuits. By Jonh Markus. London 1959</ref>С них можно будет снять мерки для временного анализа и анализа энергопотребления.
 
==== Этап 2.4: Разработка источников питания ====
 
=== Стадия 3: Сборка блоков машины ===
На этом этапом будет последовательное создание блоков машины в железе и их подключение к Эмулятору. Получается, что блоки можно будет использовать для реальных вычислений по ходу строительства компьютера. Потом, замещая один за другим эмулируемые блоки реальным железом, мы полностью избавимся от ПЛИС, и ламповый компьютер станет полностью самостоятельным. Проект будет считаться завершенным, когда от ПЛИС в системе не останется и следа.
На этом этапом будет последовательное создание блоков машины в железе и их подключение к Эмулятору. Получается, что блоки можно будет использовать для реальных вычислений по ходу строительства компьютера. Потом, замещая один за другим эмулируемые блоки реальным железом, мы полностью избавимся от ПЛИС, и ламповый компьютер станет полностью самостоятельным. Проект будет считаться завершенным, когда от ПЛИС в системе не останется и следа.


==Часто-задаваемые вопросы и ответы==
==== Этап 3.1 Разработка корпуса ====
*''Зачем?''
На данном этапе необходимо будет довести разработку корпуса машины до стадии отправки чертежей на производство.
**Затем.
 
* ''Почему brainfuck? Может быть лучше взять более практичный урезанный ассемблер?''
==== Этап 3.2. Изготовление корпуса ====
**brainfuck - и есть урезанный ассемблер. Ламповая машина в любом случае будет в миллион раз медленнее современных компьютеров и проект является видом инженерного искусства. А раз так - то реализовывать надо наиболее безумный вариант. Тем более что декатрон - основа машины - позволяет реализовать brainfuck и ничего более.
Корпус сам по себе будет состоять из сотни частей, требуется изготовить их все и  
*''Питание?''
 
**Каждый блок будет оснащен своим собственным источником накального напряжения. Основной источник накального - трансформаторы ТН60 и ТН61.
==== Этап 3.3 Сборка модулей ====
**Напряжения смещения а также напряжение питания декатронов - анодные трансформаторы ТА и ТПП подходящей мощности и напряжений. Все напряжения смещения будут оборудованы стабилизаторами выходного напряжения. Эти напряжения подаются через пускатель по команде общего блока управления - после прогрева ламп.
Изготовление и распайка модулей ламповой логики с проверкой тестеров всех ламп, с проверкой модулей на тестере модулей и т.п.
**Основное анодное напряжение - некоторые блоки будут получать от собственных силовых трансформаторов типа ТС160, ТС170, ТС270 - это трансформаторы от ламповых телевизоров. а также от трансформаторов типа ТА подходящей мощности. Стабилизаторов напряжения на выходе не будет предусмотрено. Анодное на схему будет подаваться через пускатель по команде общего блока управления после подачи накального напряжения и прогрева ламп, подачи напряжений смещения, анодного декатронов.
**Предусмотрен общий стабилизатор напряжения на базе автотрансформатора. От него будут питаться все остальные блоки.


==Общий прогресс==
====Этап 3.4: Монтаж схемотехники машины====
Совершается одновременно с этапом 3.3 - по мере сборки модулей производится ошиновка разъемов вкупе с эмулятором производится верификация корректной работы прибора
 
==Бюджет проекта (UPD: 17.01.2024)==
{| class="wikitable"
|+План/Факт расходов на проект.
!Наименование
!Стоимость, тыс. руб
!Примечание
|-
|Лампы, декатроны, панельки
|90
|
|-
|Прочее
|93
|
|-
|'''Всего израсходовано'''
|'''198'''
|'''Учтенных расходов'''
|-
|Трансформатор питания, 3шт
|100
|
|-
|Корпус
|50
|
|-
|Электронные компоненты
|50
|
|-
|План
|377
|
|}


==Видеоматериалы==
==Видеоматериалы==
Строка 483: Строка 712:


*Статья на [https://xakep.ru/2019/09/19/brainfuckpc/ Xakep.ru]
*Статья на [https://xakep.ru/2019/09/19/brainfuckpc/ Xakep.ru]
<references />

Текущая версия на 17:22, 21 августа 2024


Dekatronpc logo.jpg

Описание

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

Ламповый компьютер DekatronPC предназначен для выполнения программ, написанных яна языке программирования brainfuck. Это значит, что основу набора инструкций составляет восемь инструкций языка brainfuck: +-<>.,[]

Основное требование к ламповому компьютеру — чтобы инструкции в нем в точности соответствовали языку Brainfuck. Во-вторых — 99% существующих восьмибитных программ на Brainfuck должны исполняться исключительно на ламповой логике. Оставшийся 1% банально может не умещаться в ОЗУ. Максимум того, что допускается использовать в аутентичной части машины, — это германиевые диоды, да и то лишь в выпрямителях питания в схемах обвязки кубов памяти.

Подпроекты

Технические характеристики (проектные) - UPD: 19.08.2023

  • Архитектура - Гарвардская, с раздельной памятью данных и кода.
  • Адресация памяти программ - 1 000 000 ячеек шириной 4 бит
  • Адресация памяти данных - 100 000 ячеек данных шириной 10 бит
  • Разрядность:
    • Шины данных - 10 бит октетами в формате 8-4-2-1. диапазон счета - 0-255 (3 декатрона)
    • Шина адреса данных - 20 бит, октетами в формате 8-4-2-1. диапазон счета - 0-99999 (5 декатронов)
    • Шина адреса программ - 24 бит, октетами в формате 8-4-2-1. диапазон счета - 0-999999 (6 декатронов)
  • Тактовая частота - не более 1МГц - ограничение со стороны декатрона А110
    • Поправочка - скорость пересчета декатрона А110 - 1МГц, однако согласно Яблонскому, импульс сброса (в данном случае - записи в декатрон) - в среднем на порядок больше импульса пересчета. Поэтому можно смело ронять тактовую частоту до 100кгц...
  • Быстродействие - до 500тыс операций в секунду. Доступна конвейеризация - пока выполняется текущая инструкция, допускается выборка новой.
    • Время выборки новой инструкции, время исполнения инструкции - уникально.
    • Выборка новой инструкции - не быстрее 2 тактов. (в текущей версии кода 3)
    • Исполнение инструкций - от 1 такта - зависит от предыдущего состояния. В серии команд ++++ первый инкремент займет два такта, второй и последующие - 1 такт, но так как время выборки новой инструкции не менее 2 тактов и может производиться параллельно, то частота инкрементов будет не выше 500 тысяч в секунду на частоте 1МГц.
  • Текущее Быстродействие в модели:
    • Пиковое: 200тысяч операций в секунду.
    • Среднее 45 тысяч операций в секунду.
  • Количество ламп ~1000шт (07.06.2023 - по результатам синтеза Verilog-модели 1244шт)
  • Используемые лампы:
    • 6Н16Б - сверхминиатюрный сдвоенный триод для работы в импульсных устройствах.
    • 6Ж2Б - сверхминиатюрный пентод для работы в импульсных устройствах. Утверждается[1], что может работать в режиме с двумя управляющими сетками.
    • 6Х7Б - сврехминиатюрный сдвоенный диод.
    • А110 - сверхминиатюрный коммутаторный декатрон со скоростью счета до 1млн имп. в секунду.
  • Потребляемая мощность, общая - не хуже 5кВт. Для тысячи ламп 6Н16Б расчет составляет:
    • на накал ламп 6.3В 0,4А/лампа (400А) - 2.5кВт
    • анодное 150В 5мА/триод (10А)- 1,5 кВт
  • Общие габариты процессора : три 4U серверных блока размерами 920*420*178мм.
  • Масса 60кг.

Декатрон

Dekatron.png

Декатрон — это многоэлектродная газоразрядная лампа, предназначенная для реверсивного счета импульсов[2]. В центре находится диск анода, а вокруг него расположены тридцать электродов. Из них десять катодов и две группы подкатодов — по два подкатода между каждым катодом. После подачи напряжения на декатрон между анодом и одним из катодов загорается тлеющий разряд. Подавая импульсы определенной последовательности на подкатоды и соседний катод, мы можем перемещать разряд между катодами, обеспечивая операцию инкремента или декремента. У коммутаторного декатрона все выводы катодов выведены наружу, следовательно можно считывать текущее значение, а также - устанавливать разряд на необходимом катоде. Да эта лампа просто создана для языка Brainfuck! Тут нужно сделать ремарку, что нет ни одной схемы записи данных в декатрон по катоду. Однако схема сброса декатрона в исходное состояние есть подача импульса отрицательной полярности на нулевой катод. По образу и подобию можно подать такой импульс на любой катод и получить запись информации в декатрон. В ламповом компьютере Harwell Dekatron используется следующая схема записи данных - на схему сравнения подается сигнал с декатрона и требуемое число. После этого подается серия импульсов инкремента на декатрон до тех пор, пока на нем не окажется необходимое число. Эта схема может быть также реализована, если исходный эксперимент окажется неудачным. Благо что схема записи требуется только для счетчика данных - а это 3 декатрона из 255.

Decatron reverse control.png

Пример схемы реверсивного управление декатроном по цепи подкатодов показан в книге Яблонского Декатроны [3]. Имеется два входа - для инкремента и декремента, на которые подается импульс напряжения необходимой длительности. Так как конденсаторы C3 и C4 в обычном состоянии заряжены до 260В, при подаче сигнала на одну из ламп Л1 или Л2 левый вывод конденсатора притягивается к земле, тем самым на правом выводе формируется сигнал с уровнем порядка -200В, что является достаточным для переключения декатрона. Цепь задержки обеспечивает подачу второго импульса после первого. Схема нарисована с использованием германиевых диодов. В экспериментальной ячейке точно будут использоваться Д7Ж. В итоговом монтаже - использование допустимо, но пока под вопросом.

Декатронные счетчики

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

DekatronCounter.png

На данной схеме показан наибольший функционал декатронного счетчика данных - с возможностью записи любого числа, чтения, органичения сверху (для реализации счета от 0 до 255). Схема переноса реализована таким образом, что количество декатронов в цепочке не влияет на время счета - все разряды переносятся одновременно если выполняется необходимое условие. В большинстве счетчиков не будет схемы записи - это самая дорогая часть по лампам.

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

Обязательной является:

  1. обвязка самого декатрона,
  2. усилители-формирователи управляющих импульсов, 1 лампа(?)
  3. трех-позиционная защелка схемы переноса 8 ламп(?)
  4. усилители-формирователи линии сброса в 0 и в Х (например в 5 для счетчика до 255), 1 лампа(?) - можно вынести на отдельную плату

Желательно уместить всю эту обвязку на одной плате.

Необходимая обвязка:

  1. Схема преобразователя позиционного кода в двоично-десятичный - 11 ламп
  2. Схема усилителей-формирователей позиционных линий для любого из катодов. Два усилителя находятся в обязательной секции, поэтому остается оп 8 линий на декатрон. Для счетчика данных требуется в общей сложности 17 линий. Можно округлить до 18 линий и разместить на 1-2 платах. Если в одну плату обязательная обвязка влезать не будет - то для счетчика данных требуется 23 линии, а для любого счетчика - от 6 до 10 линий. Исходя из этих данных нужно определиться с числом линий - однако нужно окончательно определиться со схемотехникой и определить требуемое количество ламп на одну линию.
  3. Схема декодера из двоично-десятичного в позиционный код. Требует по две лампы на линию. Вероятно собираться будет на базе элементов И.

В ламповом компьютере требуется 4 реверсивных счетчика с общим количеством декатронов в 17 штук.

Лампы по счетчикам
Счетчик Функционал Чтение Запись Управление Декатроны Диоды Триоды
IP Counter Сброс в нуль, Чтение данных, Сигнал Zero 6 0 6 6 84 42
AP Counter Сброс в нуль, Чтение данных, Сигнал Zero 5 0 5 5 70 35
Data Counter Сброс в нуль, Запись данных, чтение данных, Верхний лимит, Сигнал Zero 3 3 3 3 42 108
Loop Counter Сброс в нуль, Сигнал Zero 0 0 3 3 18 15
Всего 14 3 17 17 214 200

Функционал счетчика:

  • Инкремент и декремент текущего числа счетчика
    • Для работы в режиме счета от 0 до 255 необходимо выставить TOP_LIMIT_MODE=1. Тогда по достижении счетчиком числа TOP_VALUE  вместо инкремента будет происходить запись 0 в счетчик. По достижении 0 и при декременте - в счетчик будет записано TOP_VALUE.
  • Запись числа в счетчик со входа In, заданного в формате 8-4-2-1
  • Чтение числа из счетчика на выход Out, в формате 8-4-2-1

Все счетчики работают синхронно от сигнала тактирования и имеют следующие входы управления

  • Request - наличие этого сигнала по нарастающему фронту запускает счетчик. При отсутствии сигналов Set или SetZero будет происходить счет
  • Dec - выбор направления счета - в прямую сторону (лог.0) и обратную сторону (лог.1)
  • SetZero - при наличии этого сигнала по нарастающему фронту Clk совершается запись нуля в счетчик
  • Set - при наличии этого сигнала по нарастающему фронту Clk производится запись числа со входа In в счетчика
Лампы по платам работы с декатроном
Платы Триоды Диоды
Схема чтения 2 8
Схема записи 29 0
Управление, перенос 5 6

Экспериментальная декатронная ячейка

ExperimentalDekatronModule.png

Ячейка представляет собой блок 3U-блок на 4 платы, и реализует полную схемотехнику управления декатроном, включая чтение, запись и пересчет с переносом.

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

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

Также есть схема переноса. Технически это тройная защелка, имеющая два выхода, которые подсвечивают крайние положения - 0 и 9 до момента полного переключения лампы. т.е. этот блок помнит последнее состояние лампы пока идут процессы переключения.

Выход - 30-контактный. На нем есть все линии декатрона на запись, напряжения питания. накал, а также - двоично-десятичный выход 8-4-2-1

Dekatron up down unit.png

Еще две платы примерно одинаковые, их задача - преобразовать двоично-десятичный вход 8-4-2-1 в двоичный с сигналом записи - для этого требуется 4 инвертора, и 5-входовый И - на двух сдвоенных триодах, где анод-катод - это 4 линии и пятая линия - сетка. Схема, вероятно, будет изменяться - с переходом на импульсную логику.

Dekatron cell up down WSU.png

К этим двум платам пока вопросы. На две платы следующие задачи:

  1. Инверторы входных сигналов 8-4-2-1. Итого имеем 8 сигналов - прямые и инверсные, которыми можем набрать нужную комбинацию сигналов для следующего этапа:
  2. Пятивходовые И на двух сдвоенных триодах, где сетка - это пятый сигнал записи. Им на вход подаются сигналы набранные в нужной комбинации на первом этапе.
  3. Усилители записи - 10 штук. По одному на каждый катод. И тут вопрос - либо они будут работать в статическом режиме, либо в импульсном. Первый вариант требует переход в отрицательные уровни напряжения. Второй позволяет обойтись без них, с помощью развязывающих конденсаторов формировать импульсы нужной длительности и амплитуды.
  4. Усилители сигналов управления подкатодами. тут опять вопрос к режиму работы. Скорее всего я приду к импульсному варианту - он проще и по нему есть все необходимые схемы.

Источники питания ячейки:

DekaronCellPSU.png

Используется четыре трансформатора - выбор из того что было в наличии. Все трансформаторы проверены на сопротивление изоляции мегаомметром на 1кВ.

  • ТСШ-170 - 170Вт. предназначен для выработки основного питания +150В, а также пары накальных линий для 6С19П.
  • ТН61 - общей мощностью 190Вт. Имеет 4 линии 6.3В - 3 по 8А и 1 машина - 6.1А. Будет обеспечивать основное питание накалов ламп, разбитых на группы по платам
  • ТА48, мощностью 36Вт - питание декатрона +450В (технически сам источник будет на +350В), а также напряжение смещения -50В.
  • ТА7, мощностью 15Вт - напряжение +20В.

Схемы питания берем из блоков питания осциллографов С1-54 и TR4401

Схема стабилизатора анодного напряжения +150В, 200мА. Питается от трансформатора ТСШ170, выводы 7-8+9-10
Финальная схема стабилизатора анодного напряжения декатрона +500В (работает со смещением +150В от земли)Питается от трансформатора ТА48, выводы 11-12+17-8
Схема стабилизатора напряжения +20В, 30мА. Питается от трансформатора ТА7, выводы 19-20+21-22
Схема стабилизатора отрицательного напряжения +50В, 30мА. Питается от трансформатора ТА48, выводы 21-22+19-20


Архитектура компьютера

Машина проектируется на базе четырех реверсивных многоразрядных счетчиков.

  1. IpCounter - (шесть декатронов) будет определять номер текущей исполняемой инструкции.
  2. LoopCounter - (три декатрона) для корректной перемотки циклов. сумматора в будущем компьютере нет, а значит, начало текущего цикла придется искать вручную, банально перематывая счетчик инструкции назад до тех пор, пока начало нашего цикла не будет найдено. Счетчик вложенных циклов поможет корректно искать нужное начало, даже если внутри нашего цикла множество вложенных. Счетчика от 0 до 999 будет более чем достаточно: в программах на Brainfuck, написанных людьми, даже больше 20–30 уровней вложенности циклов — редкость.
  3. ApCounter - (пять декатронов) Третий счетчик от 0 до 99 999 будет определять номер текущей ячейки данных. В исходном языке Brainfuck число ячеек 30000 - этот режим реализовать можно, но это будет ограничением функционала машины.
  4. DataCounter (три декатрона) По адресу счетчика ApCounter происходит выборка данных из ОЗУ. Данные помещаются в четвертый счетчик, который умеет считать от 0 до 255. То есть мы загружаем в декатрон наше старое значение, делаем инкремент или декремент и выгружаем данные обратно в память.

Структурно машину можно разбить на три больших блока:

  1. IpLine Block — Отвечает за выборку очередной инструкции из памяти программ.
  2. ApLine Block — Отвечает за исполнение инструкций касаемо данных — прогулки по памяти, изменение значения в ячейке, работа с терминалом
  3. MachineCtrl — Блок логики, объединяющий блоки работы с программой и данными, контролирующий работу машины и обеспечивающий связь с внешним миром.

Сами блоки состоят из модулей: многоразрядных реверсивных счётчиков, модулей памяти, буферов и т.п. Все эти базовые кирпичики имеют три линии управления: сигнал ЗАПРОС(Request) и флаг ГОТОВ(Ready). По сигналу ЗАПРОС, модуль счётчика, например, начнёт считать адрес новой инструкции. По сигналу ЗАПРОС, модуль памяти, например, начинает выгружать данные по новому адресу.

DekatronPC.png

IpLine

IpLine full.png

Этот блок содержит два счётчика, модуль памяти программ и логику работы с циклами. Первый счётчик (IP Counter) на базе 6 декатронов определяет номер инструкции, которая считывается из памяти программ.

В дополнение к нему идёт счётчик глубины вложенности циклов (Loop Counter) — сумматора в будущем компьютере нет, а значит, начало или конец тела текущего цикла придётся искать вручную, банально шагая счётчиком инструкций назад (или вперёд) до тех пор, пока не будет найдено начало именно нашего цикла. Трёхразрядного счётчика будет более чем достаточно — в brainfuck-программах, написанных людьми, даже больше 20-30 уровней вложенности циклов — редкость.

Блок выборки инструкций, получив от блока логики сигнал ЗАПРОС, должен выдать следующую инструкцию на выходе. Дальнейшие действия блока зависят от текущей исполняемой инструкции. Если она не является условной — т.е. одна из +-<>., — то счётчику инструкций достаточно сделать +1, зачитать новую инструкцию из памяти программ и выдать её на выходной буфер. Делать это, кстати, можно одновременно с исполнением текущей инструкции в блоке данных. Да, тёплый ламповый конвейер — к моменту завершения текущей операции мы сможем сразу начать новую.

Сложности начинаются с инструкциями границ цикла. Надо обработать условную операцию и либо выполнить инструкции в теле цикла, либо нет. Вариантов тут четыре. Допустим, есть следующий код цикла, реализующий операцию MOV — Мы будем делать +1 в ячейке n+1, и -1 в ячейке n до тех пор, пока ячейка n не равна нулю.

[>+<-]

При выполнении этого цикла может быть четыре варианта действий:

  1. Мы на инструкции [ и текущая ячейка не равна нулю — нужно выполнить тело цикла.
  2. Мы на инструкции ] и текущая ячейка не равна нулю — нужно вернуться в начало цикла, чтобы выполнить его ещё раз.
  3. Мы на инструкции [ и текущая ячейка равна нулю — нужно промотать тело цикла, не выполняя его.
  4. Мы на инструкции ] и текущая ячейка равна нулю — выполнение цикла завершено просто идём дальше

Их можно обобщить в два варианта развития событий:

  • При вариантах 1 и 4 компьютер просто продолжает выполнять инструкции друг за другом.
  • Варианты 2 и 3 требуют промотать тело цикла. Счётчик будет считать либо назад(для варианта 2) либо вперёд(3) в поисках ответной скобки цикла.

Чтобы промотать тело цикла, нужно пошагово изменять значение счётчика инструкций, делать выборку инструкции по этому адресу и Не подавая её на выходной буфер, смотреть, что же за инструкция сидит по этому адресу. Например, если мы начали с открывающей скобки [, и идём вперёд — то при нахождении закрывающей скобки] промотку можно считать завершённой. Но вот в процессе промотки мы наткнулись на ещё одну открывающую скобку [ — от вложенного цикла. Тут-то и пригодится счётчик глубины вложенностей. В самом начале промотки на нашей оригинальной открывающей скобе [ делаем ему +1 и потом будем делать +1 всякий раз, встречая открывающую скобку [, и -1 встречая закрывающую скобку ]. Как только после очередной закрывающей скобки ] значение счётчика станет равным нулю — поиск можно останавливать — цикл мы промотали. Точно так же это работает и в обратную сторону, разве что скобки меняются местами.

LoopLookupLogic.png

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

IpLine FSM

Конечный автомат линии Ip Line объединяет в себе все основные стадии работы.

Так как блок состоит из двух счетчиков - IP Counter и Loop Counter, основной алгоритм работы конечного автомата - работа по внешнему кольцу состояний -

Готов -> Запрос нового адреса -> Запрос новой инструкции.

Однако, есть особые случаи:

  1. Сразу после сброса машины, на выходе счетчика уже находится адрес 0. Нужно сразу зачитывать инструкцию по этому адресу без инкремента счетчика.
  2. Если текущие инструкции - условные переходы [ ] и { } и условие перемотки инструкций выполняется - то одновременно поднимается CountRequest на оба счетчика.
  3. Если после выгрузки очередной инструкции оказывается:
    1. что значение LoopCounter == 0 - то перемотка завершена.
    2. что значение LoopCounter != 0 - то выдается новый IpCounterRequest сигнал
    3. что выставлен сигнал HaltRq - Система останавливается до снятия сигнала. в этом случае машина либо продолжит счет, либо перейдет в состояние IDLE

ApLine

ApLine full.png

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

Один счётчик(AP Counter) считающий от 0 до 29999, будет определять номер текущей ячейки данных. Для чистого brainfuck необходимо будет сделать сброс старшего счётчика в нуль после 2 и наоборот. Один декатрон легко установить в нужное значение. Сложно прогнать сигналы переноса через все разряды.

По адресу этого счётчика происходит выборка данных из ОЗУ в четвёртый счётчик — Data Counter. Он умеет считать от 0 до 255. т.е. мы загружаем в декатрон наше старое значение, делаем инкремент или декремент и выгружаем данные обратно в память. Или же — мы можем напечатать текущее значение в терминале, или, минуя декатронный счётчик — занести число из терминала сразу в ОЗУ. Так как в программах на brainfuck инструкции инкремента/декремента ячейки ОЗУ и значения, как правило, идут группами, то это не значит, что потребуется постоянно загружать/выгружать данные в счётчик и обратно. Этого можно избежать, добавив флаг занятости ОЗУ

MachineCtrl

Блок соединяет вместе блоки ApLine и IpLine, содержит в себе основную машину состояний, а также декодер инструкций. Предоставляет пользовательский интерфейс с оператором и внешними устройствами.

Набор инструкций (UPD: 13.06.2023г.)

Основной набор инструкций - 8 инструкций языка brainfuck. Остальные инструкции служебные, используются для управления состоянием машины.

Каждая инструкция представлена в памяти 4-х разрядным значением, соответствующим тому или иному опкоду. Чтобы увеличить количество инструкций используется специальный регистр ISAREG, определяющий текущий набор команд - Debug ISA и Brainfuck ISA.

  1. ISAREG=0 - Debug ISA - режим, в котором машина находится после включения. в нем доступны инструкции очистки ОЗУ, сброса состояния машины, команды загрузки данных с перфоленты. Предполагается, что первоначальный загрузчик, после чтения программы с перфоленты переключит набор команд в Brainfuck ISA и машина начнет исполнять инструкции загруженной программы
  2. ISAREG=1 - Brainfuck ISA - основной режим, в котором доступны 8 инструкций языка brainfuck плюс несколько дополнительных.

Часть инструкций присутствует в обоих наборах - NOP, HALT, ISA0, ISA1

Debug ISA (ISAREG=0)

Символ Опкод Brainfuck название описание
N 0x0 NOP No operation - Must be in both ISA set
H 0x1 HALT Must be in both ISA set
\a 0x2 BELL Ring the bell
0x3 UNDEFINED
E 0x4 EOT End Of Transmission
S 0x5 SOT Start Of Transmission - To load Data from Punch/Mangetic Tape
{ 0x6 LABEG Если текущий адрес равен нулю - пропустить тело цикла
} 0x7 LAEND Если текущий адрес не равен нулю - выполнить итерацию цикла
L 0x8 CLRL Сбросить счетчик глубины вложенностей циклов
I 0x9 CLRI Сбросить счетчик инструкций
0 0xA CLRD Сбросить счетчик данных
A 0xB CLRA Сбросить счетчик адреса (Что делать с флагом захвата?)
R 0xC HRST Hard Reset
r 0xD SRST Soft reset
D 0xE ISA0 Set ISAREG=0 - Debug ISA
B 0xF ISA1 Set ISAREG=1 - Brainfuck ISA

Brainfuck ISA (ISAREG=1)

Помимо восьми основных brainfuck-инструкций имеет еще 6 дополнительных. Особое внимание стоит уделить инструкциям CLRML, LOAD, STORE

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

Допустим, нужно скопировать данные из ячейки А в ячейку Б.

  1. Счетчик адреса устанавливается на ячейку А
  2. Дается команда LOAD - данные загружаются из памяти в счетчик данных. MemLock не изменяется.
    1. Если далее идут команды +- - произойдет повторная загрузка данных с учтановкой MemLock плюс выполнится инструкция +-
    2. Если далее идут команды ., -обмен данными будет осуществляться непосредственно с ОЗУ
  3. Счетчик адреса устанавливается на ячейку Б
  4. Дается команда STORE. Значение из счетчика данных выгружается в ячейку памяти Б
Символ Опкод Brainfuck название описание
N 0x0 NOP Пустая инструкция
H 0x1 HALT Останов машины
+ 0x2 + INC Increment of Current data cell
- 0x3 - DEC Decrement of current data cell
> 0x4 > AINC Increment of address pointer
< 0x5 < ADEC Decrement of address pointer
[ 0x6 [ LBEG If current data cell equal zero, skip the loop
] 0x7 ] LEND If current data cell not equal zero, repeat loop iteration
. 0x8 . COUT Print current symbol to the terminal
, 0x9 , CIN Read symbol from the terminal (Blocked acces - Program halted while no symbol)
0 0xA [-] CLRD Basic brainfuck optimization: Write zero to current Data Cell
M 0xB CLRML Clear memory lock
G 0xC LOAD Explicit Load from current memory cell to Data Counter, MemLock not affected
P 0xD STORE Explicit Store from Data Counter to current memory cell, MemLock not affected
D 0xE ISA0 Set ISAREG=0 - Debug ISA
B 0xF ISA1 Set ISAREG=1 - Brainfuck ISA

Начальный загрузчик (bootloader)

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

Одной из идей является установка IpCounter в 999900 - и последние 100 инструкций занять начальным загрузчиком.

Для этого блок MachineCtrl предоставляет два вида сброса машины.

Hard Reset

Этот тип сброса очищает все возможные флаги и устанавливает адрес IpCounter на начало загрузчика. Если тумблер на панели разрешает работу загрузчика автоматически - пускает его. В противном случае будет ждать кнопки Run.

ApCounter <= 0;
DataCounter <= 0;
LoopCounter <= 0;
MemLock <= 0;
RamDataReady <= 0;
IpCounter <= 20'h999900;
//User switch to run bootloader after Hard Reset
if (RunBootloader)
    MachineState <= RUN;
else
    MachineState <= HALT;

Soft Reset

Этот тип сброса очищает все возможные флаги и устанавливает все счетчики в нуль. Отличие в том, что после Hard Reset стартует загрузчик, после Soft Reset - загруженная программа. Если тумблер на панели разрешает работу компьютера автоматически - пускает его. В противном случае будет ждать кнопки Run.

ApCounter <= 0;
DataCounter <= 0;
LoopCounter <= 0;
MemLock <= 0;
RamDataReady <= 0;
IpCounter <= 0;
//User switch to run program after Soft Reset
if (RunBootloader)
    MachineState <= FETCH;
else
    MachineState <= HALT;

Очистка памяти

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

  for (i = 0; i < 30000; ++i)
  {
    Memory[i] = 0;
  }

В формате инструкций компьютера DekatronPC, начальный код загрузчика выглядит так:

  A0> //Установка счетчика адреса в нуль, Обнуление текущей ячейки данных и выбор следующей
  {   // Пока текущее значение счетчика адреса не равно нулю:
    0 >//Обнуление текущей ячейки данных и выбор следующей
  }

Программирование машины

DekatronPC program load.png

В наборе инструкций есть две специальные - SOT(StartOfTransmission) и EOT(EndOfTransmission). Первая должна располагаться по адресу 999999h, ее выполнение осуществляет инкремент счетчика программ и переключает FSM машины в режим разгрузки программы. Имеется два интерфейса для входных данных:

  1. Один принимает ASCII символы, например со считывателя перфолент, накопителя на магнитной ленте, печатной машинки Consul 260.
  2. Второй принимает непосредственно 4-х битовые опкоды инструкций. Либо с первого интерфейса через конвертер, либо с других устройств, например со считывателя с магитной кассеты, или считывателя перфолент в опкодах.

На уровне OpCode производится самостоятельное переключение между наборами Debug/Brainfuck

По синхроимпульсу проверяется условие (CurrentInsn != EOT) и производится запись опкода в текущую ячейку памяти программ и последующий инкремент счетчика программ. Если условие не выполняется - т.е. текущая инструкция EOT - то автоматически вызывается Soft Reset машины. ЭВМ готова для выполнения загруженной программы.

Инструкции для работы со считывателем перфолент (в составе Debug ISA)

Предназначен для загрузки данных с перфоленты в память программ.

Текущая идея следующая: использовать аппаратный способ загрузки - когда синхросигнал с перфоленты будет инкрементировать значение счетчика инструкций, а другой сигнал - подавать сигнал записи в память. Таким образом можно инструкцией запустить этот процесс и дальше аппаратные средства сделают все самостоятельно.

Специальная инструкция StartOf Transmission сбрасывает счетчик IpCounter в нуль и переключает машину в режим счета-записи по внешнему синхроимпульсу. т.е.

initial begin
    IpCounter <= 0;
	MachineState <= COUNTER;
end

always @(posedge WriteSync) begin
	IRAM.Write(IpCounter.value, Insn);
	IpCounter <= Ipcounter + 1;
	if (Insn == EOT)//Tape is loaded
	    MachineState <= SOFT_RESET;	
end

Формат записи на магнитную ленту

Если использовать кассетный или бобинный магнитофон (типа ламповой коменты или яузы) для хранения программ и их последующего ввода в память машины, можно использовать DTMF-сигналы, когда двумя синусоидами кодируется до 16 символов. Так как программа пишется 4-х битовыми пачками, так что в одном сигнале сразу будет готовая инструкция. По завершении записи на ленте формируется прерывистый сигнал 0x01(HALT)

Оптимизация доступа к памяти

Допустим, код на bf выгладит следующим образом:

>>>>>+++++<<<<<

В наивном режиме выполнения произведется следующий алгоритм:

for (i = 0; i < 5; i++){
    ApCounter.Inc();
    DataCounter.Store(Ram.Load(ApCounter));
}
for (i = 0; i < 5; i++){
    DataCounter.Inc();
    Ram.Store(ApCounter, DataCounter.Load);
}
for (i = 0; i < 5; i++){
    ApCounter.Dec();
    DataCounter.Store(Ram.Load(ApCounter));
}

Таким образом помимо 15 операций со счетчиками будет 15 операций работы с памятью, совершенно бесполезных. По факту мы девять раз просто так будем делать загрузку-выгрузку. Проще перед первым инкрементом данных один раз сделать сделать LOAD из памяти в счетчик, а после последнего вызвать STORE обратно из счетчика в ОЗУ. За основу взят принцип Memlock.

insn = DPC.fetch(IpCounter);
if (((insn == "+")|(insn=="-"))& !MemLock){
    DataCounter.Store(Ram.Load(ApCounter));
    MemLock = true;
}
if (((insn == "<")|(insn==">"))& MemLock){
    Ram.Store(ApCounter, DataCounter.Load());
    MemLock = false;
}
DPC.exec(insn);

Тогда код на bf будет выполняться следующим образом:

for (i = 0; i < 5; i++){
    ApCounter.Inc();
}
DataCounter.Store(Ram.Load(ApCounter));
for (i = 0; i < 5; i++){
    DataCounter.Inc();
}
Ram.Store(ApCounter, DataCounter.Load);
for (i = 0; i < 5; i++){
    ApCounter.Dec();
}

Итого осталось 15 операций со счетчиками и только две операции работы с ОЗУ.

Конструктив машины

Модуль

Модуль представляет собой печатную плату размером 140х140мм с краевым разъемом 3х36 пин либо разъемом ГРПМШ-31. На плате располагаются непосредственно лампы, и схемы обвязки. Несколько видов базовых плат, реализует всю возможную схемотехнику. Платы на базе краевого разъема в приоритете. Предлагается заблокировать один ряд пинов для создания ключа - так не получится платы одного типа воткнуть в разъем для другого типа плат

DekatronPC module.png Dekatronpc module 140x200.png
Модуль 140х140мм с краевым разъемом 2х36пин. Первое поколение плат. Модуль 140х200мм с разъемами ГРПМШ-31

Блок

Блок представляет собой полноценный узел машины - IpLine, ApLine или MachineCtrl. Возможно в дальнейшем понадобится увеличить количество блоков.

DekatronPC block.png

За передней панелью блока скрывается источник питания, на базе одного торроидального трансформатора и выпрямителей вокруг него. Далее идет ряд вентиляторов, затем - три ряда плат модулей, стоящих с шагом 24мм для логики или 36мм для плат с декатронами. Три ряда плат, с шагом 24мм для логики и 36мм для плат с декатронами. Теоретическая вместимость каждого блока 768 ламп.

DekatronPCblock1.png

Платы располагаются ближе к задней стороне чтобы все провода между модулями а также к задним разъемам были минимальной длины. На самом блоке располагаются разъемы для модулей, а в подвале сформирована область для соединения модулей между собой. Подобная схема использовалась в ЭВМ Bendix G15А посмотреть ее воочию, можно у Usagi в видеороликеСкорее всего все соединения будут производиться пайкой, А схема подключения - браться их yosys

DPC Back wiring.png

Питание

Каждый блок питает себя сам. Изначально идея была поместить в каждый блок только накальные трансформаторы типа ТН61. Однако для полной загрузки блока нужно 4-5 трансформаторов и в ряд они не лезут, а в иной компоновке - съедают слишком много места. Таким образом требуются заказные торроидальные многообмоточные трансформаторы - которые будут выдавать все необходимые напряжения питания. При этом если накала на весь блок нужно порядка 300А. Лучшим вариантом на данный момент я считаю сделать 6 накальных обмоток по 50А каждая - по две обмотки на ряд.

В РФ изготовлением трансформаторов занимаются ТОРЭЛ и Тульский завод трансформаторов. ТОРЭЛ запросил 33к за трансформатор, в тульский завод я ТЗ еще не отправлял - нужно окончательно определиться с начинкой блоков и количеством ламп в каждом из них, а также по необходимым напряжениям питания.

Считается, что входное напряжение стабильно по ГОСТ (+-10%). Анодное напряжение не стабилизируется, накальное не стабилизируется. Маломощные напряжения смещения снабжаются линейными стабилизаторами на базе 6С19П[4].

Охлаждение

В блоке установлены мощные 120мм вентиляторы NMB 4710PS-23T-B20 с питанием от 220В для отведения тепла. Мощность 9Вт, 1900об/мин, производительность 1.4м^3/мин при создаваемом давлении 23.5Па.

Измерение декатронной ячейки анемометром показывает скорость воздуха 2.4м/с, что при трех вентиляторах дает производительность 5.8м^3/мин, а на один - 1.9м^3/мин - что плюс-минус корректно. В час 350м^3. Для охлаждения лампы ГУ-5 с рассеиваемой мощностью 3.5кВт достаточным является охлаждение в 400м^3/час. Так что должно хватить.

В принципе, 4U серверные корпуса способны выделять 2-3кВт тепла и при наличии активного охлаждения они не перегреваются. Требуется модель openFoam и натурные эксперименты для измерения характеристик нагрева:

  1. Измерить поток воздуха и создаваемое давление от используемых вентиляторов
  2. Загрузить 3D модель блока с платами с лампами в openFoam и просчитать потоки воздуха
  3. Подать питание на сверхминиатюрку и обеспечить на ней необходимое тепловыделение, нарисовать график нагрева в закрытом пространстве
    1. То же, но при наличии активного обдува.

Стойка

DekatronPCrack.png

Дорожная карта проекта

Сейчас у меня собрано все железо, нужное для начала экспериментов, в том числе полторы тысячи сверхминиатюрных ламп - 6Н16Б, 6Х7Б и 6Ж2Б. Продолжается долгий и интересный процесс проектирования и сборки будущей машины.

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

Теперь о главном -

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

Стадия 1: Проектирование (UPD: 25.06.2023) <= Вы находитесь здесь

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

Этап 1.1: Верификационная программная модель C++ (UPD: 25.06.2023)

Описание: При этом поведение модели такое же как будет в железе - 4 счетчика - для верификации алгоритма исполнения программ на brainfuck только на счетчиках. .

Задачи:

  • Высокоуровневая программная симуляция поведения мышины
  • Верификационная модель для эмулятора

Прогресс:

  • Создан программный эмулятор на языке C++ Модель поддерживает только 8 базовых инструкций языка Brainfuck и требует незначительной доработки для дополнения остальными инструкциями.
  • На данный момент модель подключена к Verilator[5] и обеспечивает пошаговое сравнение Verilog-модели с C++ моделью

Этап 1.2: Виртуальный эмулятор лампового компьютера (UPD: 25.06.2023)[6][7][8][9]

Архитектура машины реализуетсяна языке Verilog. На данный момент модель уже умеет исполнять программу Hello World! Идет активная переработка исходного кода. Также, на базе Verilator создано окружение виртуального эмулятора - он позволяет отлаживать прошивку Эмулятора без физического доступа к железу, в виде C++ приложения, в котором код Эмулятора пишется на языке Verilog.

Задачи:

  • Программная эмуляция схемотехники будущей машины
  • Синтез принципиальной логической схемы лампового компьютера - с помощью yosys и библиотеки элементов
  • Временной анализ (на основании экспериментальных данных со второй стадии проекта)
  • Анализ энергопотребления

Прогресс:

  • Verilog-модель поддерживает все 8 инструкций brainfuck, а также несколько других.
  • Виртуальный эмулятор доступный для запуска кем угодно

Тестирование:

  • Ведется в среде Verilator и позволяет провести функциональную эмуляцию схемотехники будущей машины
Тест Состояние
Dekatron PASSED
Counter PASSED
IpLine - LoopTest PASSED
ApLine PASSED
Hello World PASSED
Pi PASSED
ROT13 PASSED

Стадия 2: Прототипирование(UPD: 25.06.2023)

Следующая стадия - изготовление отдельных элементов компьютера - для проверки корректности работы схем, измерения режимов работы и т.п.

Этап 2.1: FPGA-Эмулятор лампового компьютера (UPD: 07.06.2023)

DPC FPGA EMULATOR.png

эмулятор лампового компьютера на базе ПЛИС. имеет две основные задачи

  • Физическая визуализация эмулятора
  • Эмуляция (Замещение) еще несуществующих/несобранных блоков будуей ЭВМ

На данный момент сам эмулятор собран, в нем находится старая демонстрационная прошивка. По завершении этапа 1.2 - прошивка обновится и эмулятор будет вести себя как настоящий ламповый компьютер.

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

Этап 2.2: Экспериментальная декатронная ячейка (UPD: 19.05.2023)

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

Этап 2.3: Разработка модулей ламповой логики

Результатом данного этапа будут платы - прототипы модулей ламповой логики. [10][11]С них можно будет снять мерки для временного анализа и анализа энергопотребления.

Этап 2.4: Разработка источников питания

Стадия 3: Сборка блоков машины

На этом этапом будет последовательное создание блоков машины в железе и их подключение к Эмулятору. Получается, что блоки можно будет использовать для реальных вычислений по ходу строительства компьютера. Потом, замещая один за другим эмулируемые блоки реальным железом, мы полностью избавимся от ПЛИС, и ламповый компьютер станет полностью самостоятельным. Проект будет считаться завершенным, когда от ПЛИС в системе не останется и следа.

Этап 3.1 Разработка корпуса

На данном этапе необходимо будет довести разработку корпуса машины до стадии отправки чертежей на производство.

Этап 3.2. Изготовление корпуса

Корпус сам по себе будет состоять из сотни частей, требуется изготовить их все и

Этап 3.3 Сборка модулей

Изготовление и распайка модулей ламповой логики с проверкой тестеров всех ламп, с проверкой модулей на тестере модулей и т.п.

Этап 3.4: Монтаж схемотехники машины

Совершается одновременно с этапом 3.3 - по мере сборки модулей производится ошиновка разъемов вкупе с эмулятором производится верификация корректной работы прибора

Бюджет проекта (UPD: 17.01.2024)

План/Факт расходов на проект.
Наименование Стоимость, тыс. руб Примечание
Лампы, декатроны, панельки 90
Прочее 93
Всего израсходовано 198 Учтенных расходов
Трансформатор питания, 3шт 100
Корпус 50
Электронные компоненты 50
План 377

Видеоматериалы

Ссылки

  1. И.Г.Бергельсон, Н.К.дадерко, Н.В.Пароль, В.М. Петухов. Приемно-усилительные лампы повышенной надежности. Справочник. изд. "Советское радио". М. 1962
  2. В.М. Липкин декатроны и их применение. госэнергоатомиздат. 1960
  3. Ф.М. Яблонский, Г.М. Янкин Декатроны. 1967г
  4. К.Б. Мазель Стабилизаторы напряжения и тока. госэнергоатомиздат 1955
  5. https://www.veripool.org/verilator/
  6. Д. Томас. Логическое проектирование и верификация систем в SystemVerilog
  7. А.Ю. Романов. Ю.В.Панчул. Цифровой синтез. Практический курс. ДМК 2020
  8. Харрис и Харрис. Цифровая схемотехника и архитектура компьютера. ДМК. 2017
  9. Й. Янсен. Курс цифровой электроники в 4-х частях. изд Мир. 1987
  10. А.М. Бонч-Бруевич. Применение электронных ламп в экспериментальной физике. изд-е 4. М. 1956
  11. Handbook of electronic control circuits. By Jonh Markus. London 1959