Действующий процессор на 13 микросхемах стандартной логики

a4lzx1-d19chtkqfq7lkezfdmmm.jpeg

Привет, Хабр! Для меня было просто невозможно пройти мимо этого схемотехнического чуда. Горстка деталей на небольшой двусторонней плате выполняет команды машинного языка и выводит результат в виде двоичного кода!

Действующая модель называется »TD4 CPU», является проектом с открытыми исходниками, реально работает и позволяет понять устройство и принцип работы процессора.

▍ История проекта


Автором идеи является Ику Ватанабе, написавший книгу »とりあえず動作するだけの4bitCPU (Toriaezu Dousa-suru-dakeno 4bitCPU)», что означает »4-разрядный процессор, который действует». Книга заинтересовала энтузиастов, которые усовершенствовали схему и плату.

ksevbcms48kgyf7y0ljxesq8rmg.jpeg

Мной собрана «чёрная» версия 1.3, которая на сегодняшний день является самой новой. Да, вы не ошиблись. Тут нет блокировочных конденсаторов по питанию для каждой микросхемы или группы микросхем.

khfma_fulg1pskm9yje3qeoz17y.jpeg

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

В более старых версиях платы эти конденсаторы были, по одному на каждый корпус. А ещё было гораздо больше светодиодов, индицирующих состояние регистров, выводы двух регистров на внешние устройства и менее удобный ввод информации через PLS-разъем («гребёнку»).

_jbkoc0txbr1ub-cpw-d2p_h8ou.jpeg

Постоянное запоминающее устройство — ПЗУ (ROM, read-only memory)- во всех версиях процессора выполнено на блоках по восемь микропереключателей.

Раньше возле каждого такого блока имелся свой светодиод, обозначающий текущее значение регистра счётчика команд (PC, program counter). То есть, светодиод показывал, какая команда выполняется в данный момент.

▍ Блок-схема процессора


5rgmxohvqayf3scgavmrjp0pseu.png

Процессор TD4 имеет два регистра общего назначения — A и В, а также специальные регистры — вывода (Output) и счётчик команд. Каждый регистр содержит 4 двоичных разряда, то есть, в нём может находиться одно из 16 возможных значений от 0000b = 0 до 1111b = 15.

Если вы новичок в мире цифровой схемотехники и микроконтроллеров, то вам следует запомнить, что здесь всё считается не от единицы, а от нуля. То есть, не от 1 до 16, а от 0 до 15. 16 = 10000b — это уже пятиразрядное двоичное число.


Физически каждый из 4 регистров реализован на КМОП микросхеме SN74HC161N, она же 1564ИЕ10. Это 4-разрядный двоичный счётчик с возможностью синхронной параллельной загрузки информации и асинхронного сброса.

7qp5gnspxdgrmcyyxze1o3nqoes.png

Для регистров A, B и OUT — собственно счётная функция микросхемы в процессоре TD4 перманентно отключена путём соединения входа разрешения счёта — ноги 7 — с землёй схемы. То есть, SN74HC161N используется в качестве счетверённого синхронного D-триггера с асинхронным сбросом. Иными словами, в качестве регистра-защёлки.

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

Входы данных всех четырёх регистров соединены с шиной данных, и тактируются все регистры от общего тактового генератора.

efcbbbtkgtf7yvsejhiw9gunrow.png

У регистра PC — счётчика команд — входы разрешения счёта и переноса (нога 10) — перманентно установлены в логическую единицу путём подключения к плюсу питания. Запись в этот регистр также возможна: она необходима для осуществления безусловного и условного перехода, то есть ветвления и циклов.

▍ Тактовый генератор


Генератор тактовых импульсов представляет собой самый обычный мультивибратор на микросхеме SN74HC14N, или КР1564ТЛ2. Микросхема содержит 6 инвертирующих триггеров Шмитта. Используются три из них.

x1paqai8w1mrmo5z-m4vm6v4qxq.png

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

Фильтр нижних частот, состоящий из резистора R3 и электролитического конденсатора С1, эффективно защищает цепь тактирования от помех и дребезга контактов. Триггер Шмитта U2F служит инвертирующим буфером и формирователем фронта импульса.

▍ Постоянное запоминающее устройство


xdy2ipqvobl-imyrsvzatgf0r6g.png

Контроллером ПЗУ, или памяти программ, у процессора TD4 является микросхема SN74HC154N, она же 1564ИД3. Это двоичный дешифратор-демультиплексор 4×16, декодирующий содержимое регистра счётчика команд и, таким образом, определяющий, какая группа микропереключателей будет считана в данный момент.

Каждая из линий 8-разрядной шины считывания ПЗУ подтянута к плюсу питания резистором сопротивлением 10 килоом. Чтобы перевести каждую такую линию в состояние логического нуля, должны выполниться 2 условия: замкнут соответствующий микропереключатель, и счётчик команд досчитал до числа, соответствующего номеру группы микропереключателей.

rpc5cp9i22q7eejhli17p99neuo.png

Далее считываемые данные поступают на вход инвертирующего буфера-драйвера шины SN74HC540N, он же К1564АП12. Получается, что включённое положение микропереключателя соответствует логической единице на выходе буфера, то есть на шине команд D0-D7.

Слово машинного языка у процессора TD4 8-разрядное. Младший полубайт D0-D3 содержит непосредственные данные, или, что тоже самое, непосредственное значение, то есть 4-разрядное двоичное число, задаваемое при программировании.

▍ Арифметико-логическое устройство


Этот полубайт всегда поступает на входы второго операнда полного четырёхразнядного двоичного сумматора SN74HC283N, он же ЭКР1564ИМ6. Результат суммирования с выхода этой микросхемы поступает на шину данных, то есть на входы данных четырёх регистров — A, B, PC и OUT.

lvxpvqbqy4umdd1mvawapmkjdrs.png

Итак, арифметико-логическим устройством (АЛУ) в этом процессоре является сумматор. Все данные из регистров и в регистры проходят через сумматор.

На входы первого операнда сумматора могут поступать данные с регистров A, B, IN, либо логические нули. Что именно поступит на вход, определяют два корпуса SN74HC153N, или К1564КП2. Это сдвоенные мультиплексоры с четырьмя входами.

j2qwalwzraww2mqkg-jmymwmyec.png

Получается, что при 00b на управляющих входах сумматор получит содержимое регистра A, 01b — B, 10b — IN, 11 — логические нули.

irrqo6blu4n6g4oii-6ut3ow-f8.png

Регистр IN представляет собой группу из 4 микропереключателей. Когда они замкнуты, получаются логические единицы, а когда разомкнуты — нули. Содержимое регистра OUT выводится на светодиоды.

▍ Дешифратор команд


Старший полубайт машинного слова кодирует команду, то есть является кодом операции, или опкодом (opcode). Дешифратор команд собран на строенном трехвходовом логическом элементе 3И-НЕ SN74HC10N (1564ЛА4) и счетверённом двухвходовом элементе 2ИЛИ-НЕ SN74HC32N (1564ЛЛ1).

kqp3gt1sip9dk3matmweof-yvfm.png

Биты D4, D6 и D7 поступают на входы логических элементов, отвечающие за выбор регистра, куда будет записываться результат операции, а D5 — на входы B мультиплексоров SN74HC153N.

Логический элемент U11A используется в качестве инвертора, так как на двух его входах присутствует логическая единица с плюса питания, а на третьем входе бит D6.

Рассмотрим, какие регистры выбираются двоичными разрядами D7 и D6.

  • 00: логические нули на обоих входах U10C, и, соответственно, нуль на линии ¬LOAD0. Выбран регистр А. На входах U10D 0 и 1, на выходе 1. На входах U11B 1, 1 и 0, на выходе 1. На двух входах U11C логические нули, на выходе 1.
  • 01: на одном из входов U10C единица, на выходе единица. На U10D то же самое. На всех трёх входах U11B единицы, на выходе нуль. Выбран регистр B. На одном из входов U11C ноль, на выходе высокий уровень.
  • 10: высокий уровень на одном из входов U10C, соответственно, и на выходе. Единицы на обоих входах U10D, на выходе высокий логический уровень. Логические единицы на всех входах U11B, на выходе нуль. Выбран регистр OUT.
  • 11: на входах U10C 1 и 1, на выходе 1. На входах U10D 0 и 1, на выходе 1. На входах U11B 1, 0 и 1, на выходе 1. Выбран регистр PC, но при условии, что с выхода U10A придёт единица. А это произойдёт при логической единице на D4, либо если в предыдущем такте не произошло переполнения сумматора.


x5ssgdrmc0puyjsyjyjvwpiwfrs.png

Сигнал переполнения сумматора запоминается синхронным D-триггером U1B микросхемы SN74НС74N (К1533ТМ2). Другой триггер U1A не используется.

На языке булевой алгебры логика работы дешифратора команд выглядит так.

¬LOAD0 = D6 | D7
¬LOAD1 = ¬D6 | D7
¬LOAD2 = ¬(¬D6 & D7)
¬LOAD3 = ¬(D6 & D7 & (¬C | D4))
SEL_A = D4 | D7
SEL_B = D5


▍ Машинный язык


Теперь рассмотрим возможные коды операций D7D6D5D4.

6forzw_fd4h3m6ytb_psx6gyjai.png

  • 0000 — первый операнд для сумматора берётся из регистра А, результат помещается в регистр А. Потому мнемокод операции ADD A, Im. Im (immediate) — это непосредственное значение, которое является вторым операндом и подаётся на входы сумматора с линий D3D2D1D0 всегда.
  • 0001 — операнд для сумматора берётся из регистра А, результат помещается в регистр B. Im должен равняться нулю. Мнемокод MOV A, B. Либо можно произвести операцию A = В + Im.


5ujhovuglu1dqakeqzgfkkwcnjo.jpeg

  • 0010 — источником является регистр IN, приёмником — регистр А. Получается IN A, либо A = IN + Im.
  • 0011 — источником являются логические нули, приёмником — регистр А. Мнемокод MOV A, Im.
  • 0100 — источник А, результат помещается в B. Мнемокод MOV B, A, либо B = A + Im.
  • 0101 — Источник и приёмник — регистр B. Мнемокод ADD B, Im.


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


  • 0110 — источник IN, приёмник B. Получается IN B, либо B = IN + Im.
  • 0111 — источник — логические нули, приёмник B. MOV B, Im.


6forzw_fd4h3m6ytb_psx6gyjai.png

  • 1000 (не задокументировано автором процессора) — источник B, приёмник OUT. OUT B или OUT = B + LM. Источник не А, потому что младший бит селектора источников берётся с выхода элемента U10B и равен логической единице, если на D4 или D7 высокий уровень Проверено, работает.
  • 1001 — OUT B или OUT = B + LM.
  • 1010 (незадокументированный автором) — источник нули, приёмник OUT. OUT Im


1011 — OUT Im.
1100 (незадокументированный автором) — источник В, приёмник PC. JZ B или JZ (B + Im). Условный переход указателя на адрес, хранящийся в регистре B, если флаг переноса не установлен. То есть, в предыдущем такте не было переполнения сумматора.
1101 (незадокументированный автором) — JZ B или JZ (B + Im).
1110 — источник нули, приёмник PC. JZ Im.
1111 — источник нули, приёмник PC. Безусловный переход. JMP Im.

Итак, мы рассмотрели всю схему процессора TD4. Здесь можно скачать файлы проекта, а здесь купить печатную плату, набор с полным комплектом компонентов, либо собранное и протестированное устройство.

▍ Важные замечания


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

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

То есть, 0101 0111, что означает ADD B, 0101b, на блоке переключателей будет выглядеть как 1110 1010. Слева непосредственное значение, справа код операции. Если этого не учесть, вам покажется, что процессор неисправный. (Мне поначалу показалось именно так).

▍ Первые программы


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

0000 ADD B, 1    0101 0001
0001 OUT B       1000 0000 ; опробуем недокументированный опкод
0010 JMP 0       1111 0000


Теперь заменим безусловный переход на условный. Цикл завершится при переполнении сумматора. Далее будем брать число из регистра IN, прибавлять к нему единицу, (снова недокументированная функция), и выводить на светодиодный дисплей, пока не наступит переполнение, то есть, пока не введём 1111.

0000 OUT B        1000 0000
0001 ADD B, 1     0101 0001
0010 JZ 0         1110 0000
0011 IN B         0110 0000
0100 OUT B, 1     1001 0001
0101 JZ 11b       1110 0011
0110 MOV B, 0     0111 0000 ; b = 0
0111 JZ B         1100 0000


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

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

hc88sbzi7apcmcvqt2icby4azas.jpeg

© Habrahabr.ru