Всем привет! Продолжаю серию постов про мой компьютер на логических микросхемах. Единственный модуль процессора, оставшийся до сих пор без внимания, – это АЛУ, про него и пойдет сегодня речь.
Требования
АЛУ принимает на вход следующие сигналы:
A, B – операнды, каждый по 8 бит.
OP – код операции, 4 бита.
Cin – старый сохраненный флаг переноса, 1 бит.
Inv – флаг перемены операндов местами, 1 бит.
OE – активация выходного буфера.
Выходные сигналы:
R – результат, 8 бит.
Z – флаг нуля, 1 бит.
C – флаг переноса, 1 бит.
S – флаг знака, 1 бит.
O – флаг переполнения, 1 бит.
Никаких тактовых сигналов нет, то есть, АЛУ асинхронно: значения на выходе обновляются сразу, как только изменятся сигналы на входах.
Операции
Четыре бита кода операции дают 16 операций, куда влезает весь "джентельменский набор" арифметики и остается место еще для одной странной операции:
MOV
– копирование;ADC
,ADD
– сложение (с переносом и без);SBB
,SUB
– вычитание (с переносом и без);INC
,DEC
– инкремент и декремент;NEG
– смена знака;NOT
– инверсия бит;SHL
,SHR
,SAR
– сдвиги на один бит;AND
,OR
,XOR
– побитовые логические операции;EXP
– сохраненный флаг переноса распространяется на все биты результата.
Первая версия
Когда я начал делать процессор, я хотел не тратить сильно много времени на АЛУ и скорее получить рабочий вариант, поэтому я сделал первую версию с помощью таблиц в ПЗУ. Простейший вариант мог бы быть таким:
Все входные сигналы подаются на вход ПЗУ, а с выхода снимаются выходные. Нужно всего лишь 222 = 4М слов по 12 бит. Такой микросхемы у меня не было, поэтому надо было что-то придумывать, и я придумал вот что:
Тут используется две микросхемы по 32к слов каждая. Левая отвечает за младшие 4 бита, а правая за старшие. Зеленая и красная линии передают информацию вверх или вниз. Передача вверх (зеленая линия) нужна, например, при сложении, чтобы передать перенос с бита 3 на бит 4, а вниз (красная), соответственно, при вычитании. Чтобы не возникало осцилляций (левая микросхема передала правой, правая левой и так по кругу), эти линии пущены через логическое И со старшим битом операции. Таким образом, операции, передающие информацию "вверх" (сложение, сдвиг влево), могут быть закодированы только кодами от 0 до 7, а передающие "вниз" (вычитание, сдвиг вправо) – от 8 до 15.
Что получилось
Вторая версия
Использовать ПЗУ – это читерство, поэтому надо было делать вторую версию полностью на логических микросхемах. Общая схема АЛУ такая:
Операнды A и B подаются на мультиплексор, который меняет их местами, если на входе Inv
единица. В зависимости от кода операции один из блоков OP1-OPn активируется и подает значение на выходную шину, а остальные держат свои выходы в состоянии высокого сопротивления. В качестве выходного буфера каждого блока используется микросхема 74ACT244.
Реализация простых операций
Самая простая операция – EXP
. Нужно всего лишь подать Cin на все входы соответствующего выходного буфера.
Сдвиги (SHR
, SAR
, SHL
) тоже простые: на входы буферов подаются линии операнда со смешением на один бит в ту или другую сторону.
Для логической инверсии NOT
можно использовать микросхему 74ACT240, которая аналогична 74ACT244, но имеет инвертирующие выходы.
Побитовые логические операции могут быть выполнены на паре микросхем 74AC08 для AND
и 74AC32 для OR
(плюс буфер 74ACT244, конечно же).
Сумматор
Осталось девять операций. Восемь из них могут быть выражены при помощи сложения или вычитания:
ADD A, B = A + B
ADC A, B = A + B + c
SUB A, B = A - B
SBB A, B = A - B - c
INC A = A + 1
DEC A = A - 1
NEG A = 0 - A
MOV A, B = B + 0
Чтобы реализовать их все, универсальный сумматор должен уметь:
складывать и вычитать;
добавлять бит переноса ко второму операнду;
вместо любого из операндов подставлять ноль (нужно для
NEG
иMOV
);подставлять единицу вместо второго операнда (для
INC
иDEC
);менять порядок операндов.
Смена порядка операндов уже реализована входным мультиплексором.
Замена операнда на ноль тоже реализована входным мультиплексором: в микросхемах 74AC157, из которых он и состоит, есть вход E
, при высоком уровне на котором на выходах микросхемы будут нули.
Чтобы заменить второй операнд на единицу, можно заменить его на ноль (это мы уже умеем), а на младший бит подать единицу. Это легко сделать, пропустив младший бит через логическое ИЛИ:
Осталось сделать сумматор, который может и складывать, и вычитать. Начнем с классической схемы полного сумматора:
Полный сумматор вычисляет сумму трёх бит A + B + c
. Таблица истинности полного сумматора следующая:
A B c | R c_out
0 0 0 | 0 0
0 1 0 | 1 0
1 0 0 | 1 0
1 1 0 | 0 1
0 0 1 | 1 0
0 1 1 | 0 1
1 0 1 | 0 1
1 1 1 | 1 1
Теперь построим таблицу истинности для вычитания A - B - c
и сравним:
A B c | R c_out
0 0 0 | 0 0
0 1 0 | 1 1
1 0 0 | 1 0
1 1 0 | 0 0
0 0 1 | 1 1
0 1 1 | 0 1
1 0 1 | 0 0
1 1 1 | 1 1
Таблицы отличаются столбцом c_out
. Чтобы переделать сумматор в вычитатель, можно добавить в схему два инвертора:
Но нам нужно, чтобы можно было динамически превращать сумматор в вычитатель. Для этого инверторы надо сделать отключаемыми, а отключаемые инверторы – это XOR:
Теперь, если на входе sub
ноль, на выходе схемы будет сумма, а если единица – то разность. Осталось заметить, что эта схема вычисляет еще и исключающее ИЛИ A
и B
– последнюю нереализованную операцию АЛУ:
Дальше объединяем получившиеся ячейки в цепочку, пустив c_out
предыдущего бита на c
следующего.
Цепочка сумматоров
Итого на сумматор нужно 14 микросхем, не считая мультиплексора, буферов и того элемента ИЛИ, который подает единицу на младший бит второго операнда.
Флаги
Кроме результата арифметической операции, АЛУ должно выдавать еще и флаги, сообщающие о свойствах результата.
Флаг S (знак) – самый простой. Это просто старший бит результата.
Флаг Z (ноль) вычисляется как инверсное логическое ИЛИ всех битов результата.
Схема
Флаг C (перенос) – это выход c_out
старшего разряда сумматора в случае сложения и вычитания или "лишний" бит операнда при сдвигах.
Схема
Флаг O (переполнение) – результат исключающего ИЛИ переносов с двух старших разрядов сумматора. Подробнее почитать про флаги переноса и переполнения можно здесь.
Схема
Результат
Плата получилась не очень. Иногда всё работало хорошо, а иногда возникали какие-то высокочастотные помехи на всех линиях, включая питание, что сбивало работу всего компьютера. Сейчас у меня две версии, почему возникали помехи:
во-первых, я не поставил конденсаторы рядом с ножками питания каждой микросхемы, а просто разбросал несколько по плате;
во-вторых, серия 74ACT склонна давать наводки из-за своих резких фронтов.
Следующие платы я делал с учетом этой мудрости (на красной плате модуля регистров справа видны конденсаторы у каждой микросхемы), а АЛУ я исправил буквально методом тыка. Я запускал тестовую программу, на которой гарантированно возникали помехи, и прикладывал палец в разные части платы АЛУ. Оказалось, что если держать палец на ножке 1 U36, помехи исчезают. Всем известно, что человек – это просто большой конденсатор, поэтому я припаял между этой ножкой и землёй конденсатор на 10 пФ, что устранило проблему.
Комментарии (21)
LAutour
13.12.2021 23:40+2Оптимизации не хватает: цепи и — или меняются для однообразия на и-не — и-не.
Для flags0: почему только двух-входовые элементы?ynoxinul Автор
14.12.2021 11:00Я как-то даже не подумал, что можно так заменить. Хорошо, что такая оптимизация почти ничего не улучшает, а то было бы обидно :)
Многовходовых OR или NOR не было на маузере, а почему я NOT-AND не поставил, не помню.
LAutour
14.12.2021 11:45+2Теоретически такая оптимизация с заменой на и-не\или-не может сказаться на разводке: меньше тянуть линии для некоторых цепей, и использование части элементов для замены отдельных микросхем инверторов.
DrSmile
14.12.2021 13:02+1Вычитание делается из сложения инвертированием одного из операндов и бита переноса, т. е. всего один дополнительный элемент XOR на полный сумматор. INC/DEC тоже делаются через бит переноса.
Affdey
14.12.2021 13:41+3Круто! Помню, я в детстве делал полный сумматор на КТ361 только и диодах. Радости было))
atd
15.12.2021 11:08+174ACT ооочень требовательна к качеству питания и разводки. Если вставить 74act04 в пустую макетку и дать питание, то вы получите широкополосный глушитель радиосигналов ))
ynoxinul Автор
15.12.2021 11:38Да, я это уже позже понял. Сейчас я удивляюсь, как вообще мое АЛУ работает на этой серии.
AntonSor
Выглядит замечательно. А вы рассматривали применение специализированной микросхемы АЛУ типа 155ИП3 (74181)?
ynoxinul Автор
Нет, это тоже читерство, как и ПЗУ. А еще ее сложно найти в продаже.
Zion303
Ждём схемы на человеческих конденсаторах, а не вот это вот читерство :)))
IGR2014
Это тоже читерство. Тогда уж транзисторы вручную паять. А да, транзисторы тоже из диодов должны быть
ignat99
"Сетунь" - вместо транзисторов (или логических элементов) сборки из катушек и подобранных пар диодов. Спасибо Николай Петровичу Брусенцову и компании создателей этой ЭВМ или токово-магнитной вычислительной машины.
redsh0927
Спасибо, посмешили. Очевидно, оно и без питания работало, раз активные элементы не нужны.А, там магнитные усилители были… хитро
ignat99
Ещё там была стабильная работа во всех диапазонах температур всех климатических зон СССР. Популярная машина была. Софт был крутой. Если не путаю Форт-подобный. Закопали этот проект в угоду копирования устаревшей техники с запада.
Фамилий поднимать не буду, хотя кто в этом решении поучаствовал изестно. Это был "чистый математик".
redsh0927
Всё же транзисторам импульсно-ферритовая электроника не конкурент, несмотря на средо-устойчивость. Так что с развитием полупроводников переход неизбежен. Алсо, насколько я знаю, не Брусенцов это придумал. Ещё у немцев на фау-2 была логика на магнитных усилителях.
i_andreev
А что такое "транзисторы из диодов"?
gormih
Нет, ждём изобретения КР1858ВМ1 (он же Zilog Z80 в оригинале).
sabaca
Почему читерство, она же есть в соответствующих сериях микросхем? Кстати, купить ее не сложно. В Вольтмастере и чипдипе их продают.
atd
И в ACT ни один производитель её не делал. Можно найти в HCT, но тоже редкая штука