Как стать автором
Обновить

АЛУ на логических микросхемах

Время на прочтение4 мин
Количество просмотров17K

Всем привет! Продолжаю серию постов про мой компьютер на логических микросхемах. Единственный модуль процессора, оставшийся до сих пор без внимания, – это АЛУ, про него и пойдет сегодня речь.

Требования

АЛУ принимает на вход следующие сигналы:

  • 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 пФ, что устранило проблему.

Теги:
Хабы:
+77
Комментарии39

Публикации