Арифметико-логический блок (БА) является самым сложным и дорогим узлом любого простого процессора с микропрограммным управлением. Поскольку ЕС-1020 является младшей моделью, для которой относительно низкая цена является более важной, чем производительность, БА стал основной «жертвой» удешевления: он является однобайтовым, что значительно снизило производительность 32-разрядной машины, ведь для вычисления адреса операнда в памяти надо выполнить минимум три микрокоманды (адреса в Системе 360 являются 24-разрядными), а для выполнения обработки данных в простых операциях — минимум четыре. В реальности, как правило, необходимое число микрокоманд ещё больше из-за того, что регистры общего назначения хранятся в локальной памяти, физически являющейся частью ОЗУ, и их нужно считывать и записывать, что лишь частично может быть совмещено с обработкой данных.

Выполняемые операции

Над операндами A и B могут быть выполнены следующие 15 операций:

  • двоичные сложение и вычитание, причём вычитаемым может быть любой из операндов (т. е. могут выполняться операции A + B, A – B и B – A);

  • десятичные сложение и вычитание, последнее также в двух вариантах;

  • логические операции: И, ИЛИ, исключающее ИЛИ (в советской литературе обычно именуемое сложением по модулю два), а также И с инвертированным первым операндом (~A & B при записи в синтаксисе языка C) и ИЛИ с инвертированным вторым операндом (A | ~B);

  • операции передачи на выход значения одного из входов, именуемые А ТРАНЗИТ и В ТРАНЗИТ;

  • операции сдвига операнда B вправо и влево на один разряд, при этом выдвигаемый бит сохраняется в одном из триггеров переноса, а предыдущее значение триггера вдвигается с противоположной стороны.

Поскольку для представления двоичных целых чисел со знаком используется обычный дополнительный код, операции над ними ничем не отличаются от таковых в любой современной архитектуре и в описании не нуждаются. Заметим лишь, что для обнаружения переполнения (т. е. получения результата не с тем знаком, какой должен быть по правилам двоичной арифметики, из-за его выхода за пределы разрядной сетки) используется операция «исключающее ИЛИ» между переносами в старший и из старшего разряда.

Например, при сложении двух положительных чисел, равных 64 (01000000 в двоичной системе) должно получиться значение 128, т. е. двоичное 10000000, — но, поскольку старший бит байта является знаковым, это значение как число со знаком равно –128. В данном случае имеет место перенос в старший разряд (из первого в нулевой — напомним, что в Системе 360 разряды нумеруются слева направо), но отсутствует перенос из старшего разряда; «исключающее ИЛИ» между этими двумя переносами даст значение 1, что и служит признаком переполнения.

Двоичные умножение и деление выполняются чисто микропрограммно, чередуя сложения-вычитания и сдвиги. Подробности их реализации отсутствуют, но практически наверняка используется алгоритм, подобный, например, применяемому в аналогичных целях на микроконтроллерах ATmega, система команд которых не имеет операций умножения и деления. Основная разница будет в том, что у процессора ЕС-1020 недостаточно аппаратных регистров, чтоб одновременно хранить все байты двух операндов и результата, а также значение счётчика, поэтому ему придётся время от времени обращаться к локальной памяти.

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

В Системе 360 десятичные операции выполняются только над упакованными двоично-кодированными десятичными числами (BCD — binary coded decimal), хранящимися в памяти и имеющими переменную длину — от одного до 16 байтов включительно. Суть этой кодировки заключается в том, что в каждом байте располагаются две десятичные цифры, представленные двоичными кодами от 0000 до 1001 включительно (так называемая кодировка 8421: старший разряд полубайта имеет десятичный «вес» 8, следующий за ним — 4, и так далее). Коды 1010–1111 как цифры не используются; один из них должен находиться в младшем полубайте младшего (имеющего наибольший адрес в памяти) байта числа, кодируя его знак (если в PSW установлен режим кодирования EBCDIC, как это обычно и бывает, значения 1011 и 1101 соответствуют знаку «минус», а остальные — знаку «плюс»; сама машина формирует коды знаков 1100 для «плюса» и «1101» для минуса).

┌───┬───╥───┬───╥───┬───╥─/─╥───┬───╥───┬───╥───┬───┐
│ D │ D ║ D │ D ║ D │ D ║   ║ D │ D ║ D │ D ║ D │ S │
└───┴───╨───┴───╨───┴───╨─/─╨───┴───╨───┴───╨───┴───┘

Появление кода цифры в знаковом полубайте или кода знака в цифровом вызывает программное прерывание по особому случаю данных. В ЕС-1020 этот особый случай обнаруживается смешанным микропрограммно-аппаратным образом: коды цифр проверяются аппаратно и при обнаружении неверного кода устанавливается триггер неверных десятичных данных ТНДД, но его анализ выполняется микропрограммно; анализ кода знака является чисто микропрограммным.

Сложение и вычитание в ЕС-1020 выполняются, как несложно догадаться, побайтово. Чтобы обеспечить правильность двоично-десятичного результата сложения на двоичном сумматоре, надо, в первую очередь, обеспечить правильность распространения переноса между десятичными цифрами, т. е. между полубайтами. Для этого применяется следующий «хитрый ход».

Перед выполнением собственно сложения к каждому полубайту одного из операндов, т. е. к каждой его десятичной цифре, прибавляется значение 6 (0110), что превращает исходные коды десятичных цифр 0000–1001 в 0110–1111. Затем производится обычное двоичное сложение обоих операндов, при этом двоичные переносы из полубайтов соответствуют десятичным переносам из соответствующих цифр. Например, при сложении 9 + 1 возникает перенос в старший десятичный разряд, т. е. в следующий полубайт; в данном случае выполняется сложение двоичных кодов 1111 и 0001 либо 1001 и 0111 в зависимости от того, к какому из операндов прибавили шестёрку, а результат сложения будет равен 0000 — т. е. нулю, который и должен быть получен при сложении 9 и 1. А вот если перенос из полубайта не возник, значит, шестёрку добавляли напрасно — и её надо вычесть после выполнения сложения, что технически достигается добавлением десятичного числа 10 с игнорированием переноса из полубайта (первый раз прибавили 6, второй раз 10 — т. е. суммарное увеличение полубайта составило 16, что не изменяет его собственное значение). Скажем, если выполнялось сложение 8 и 1, т. е. двоичных кодов 1110 и 0001 либо 1000 и 0111, результатом будет 1111, а перенос отсутствует; прибавление к этому результату десятки (1010) даёт окончательный результат 1001 — т. е. 9.

Таким образом, для выполнения десятичного сложения выполняются три шага:

  • к каждому полубайту одного из операндов прибавляется код 0110; переносы из полубайтов при этом возникать не могут, так как максимальное значение каждого полубайта до этого равно 1001;

  • производится обычное двоичное сложение обоих операндов, но фиксируются переносы из каждого полубайта, а не только выходной перенос сумматора, необходимый для сложения следующей пары байтов;

  • если из какого-либо полубайта перенос отсутствует, к этому полубайту прибавляется код 1010, при этом перенос из данного полубайта игнорируется и не влияет на значение следующего полубайта.

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

«Идеологически» вычитание выполняется аналогичным образом, но имеются некоторые нюансы.

Как известно, для выполнения операции двоичного вычитания второй операнд сумматора инвертируется; кроме того, инвертируется и входной перенос — этим достигается получение дополнительного кода второго операнда. Этот же приём используется и при вычитании двоично-десятичных чисел, но, поскольку полубайт может иметь 16 значений, в то время как для кодирования десятичной цифры используются лишь первые десять из них, получение дополнительного кода двоично-десятичного числа по правилам двоичного числа автоматически вносит в каждый полубайт лишнюю шестёрку; по этой причине перед выполнением вычитания добавлять её к полубайтам одного из операндов не требуется.

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

При вычитании, в отличие от сложения, может быть получен отрицательный результат в дополнительном коде (при двоично-десятичном сложении всегда получается положительный результат в прямом коде, поскольку оба исходных операнда представлены в нём; признаком переполнения, в отличие от двоичного сложения, будет перенос из старшего полубайта старшего байта результата, который некуда поместить из-за исчерпания поля памяти, отведённого под один из операндов и результат). Признаком отрицательного результата является отсутствие переноса из старшего полубайта результата (при двоичном вычитании отсутствие переноса означает наличие заёма, и наоборот, а наличие заёма говорит о том, что уменьшаемое меньше вычитаемого). В такой ситуации для получения правильного результата нужно вычесть полученный результат из нуля. Например, вычтем 46 из 35. Технически для этого мы должны сложить первый операнд с дополнительным кодом второго операнда, который получается его инверсией и добавлением входного переноса при сложении: 0011 0101 + 1011 1001 + 1 = 1110 1111, причём переносы из обоих полубайтов отсутствуют — в них возникли заёмы (5 – 6 и 3 – 4 – 1). Соответственно, сначала нужно выполнить коррекцию обоих полубайтов путём прибавления к ним 1010 с игнорированием переноса между полубайтами, что даёт в результате 1000 1001, или 89 — т. е. дополнительное до ста значение результата, равного –11. Поскольку при выполнении основного сложения перенос из старшего полубайта отсутствовал, необходимо вычесть этот результат из нуля (математически — из ста): 0000 0000 – 1000 1001 = 0000 0000 + 0111 0110 + 1 = 0111 0111. Переносы из полубайтов отсутствуют, значит, необходима коррекция: 0111 0111 + 1010 1010 = 0001 0001, т. е. десятичное значение 11.

Информации об алгоритмах выполнения десятичных умножения и деления нет. Учитывая отсутствие каких-либо аппаратных ускорителей, самым разумным представляется имитация ручного умножения или деления «в столбик» за счёт многократного сложения или вычитания. Для этого требуется довольно много памяти, и микропрограмма будет использовать как рабочую область ЛП, так и область одного из операндов и результата в ОП: Система 360 допускает появление в области результата промежуточных данных в процессе выполнения операции (их может «увидеть» канал ввода-вывода, если одновременно с выполнением «долгоиграющей» десятичной операции будет производиться передача данных из этой же области памяти на внешнее устройство — логически такая передача бессмысленна, но физически допустима), а в случае прерывания команды из-за возникновения программной ошибки (например, выхода за пределы памяти или нарушения защиты) или аппаратного сбоя поле результата может содержать произвольное значение.

Устройство и работа блока

Структурная схема БА приведена на рисунке.

Структурная схема БА, скан из [1]
Структурная схема БА, скан из [1]

БА имеет в своём составе следующие узлы.

  • УУС — узел управляющих сигналов. На него поступает содержимое полей ФУНКЦИЯ и КМЛ микрокоманды, из которых формируются сигналы, управляющие всеми остальными узлами, кроме входных регистров и УПК.

  • РА и РВ — входные регистры вместе с их мультиплексорами, осуществляющими выбор того или иного источника информации для соответствующего входа БА. Управляются полями микрокоманды А и В.

  • ИНД — узел индикации содержимого РА, РВ и выхода БА С; информация отображается на пульте управления. На работу БА этот узел не влияет.

  • КТР — узел контроля. Работа схем контроля машины будет рассмотрена в отдельной статье; на собственно выполнение операций БА этот узел не влияет.

  • УДК1 — первый узел десятичной коррекции. В операции десятичного сложения прибавляет значение 0110 к каждому полубайту операнда А, в остальных операциях пропускает операнд А без изменения.

  • УПК — узел перекосов, управляемый полем микрокоманды ДЕФОРМАЦИЯ В. Передаёт разными способами полубайты второго операнда для дальнейшей обработки.

  • УЛ — логический узел, осуществляющий ту или иную логическую операцию над выходами УДК1 и УПК.

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

  • УП — узел переносов. Формирует межразрядные и выходной переносы в операциях сложения и вычитания; используется также для сдвига.

  • УСМ |2| — узел суммирования по модулю 2, т. е. выполнения операции «исключающее ИЛИ» между выходами УЛ и УП.

  • УДК2 — второй узел десятичной коррекции. Производит прибавление 1010 к полубайтам результата десятичной операции, если из соответствующего полубайта отсутствует перенос (последние поступают на УДК2 из узла переносов).

  • ББА — байт состояния БА. Представляет собой набор триггеров, устанавливаемых по результату операции или под воздействием поля микрокоманды УСТАНОВ и отчасти влияющих на выполнение последующих операций.

В начале выполнения микрокоманды в регистры РА и РВ принимается и фиксируется подлежащая обработке информация. УУС вырабатывает необходимые управляющие сигналы, которые остаются активными до конца такта. Информация из РА и РВ проходит через узлы БА, где осуществляются преобразования, управляемые сигналами УУС, а также полями ДЕФОРМАЦИЯ В и УСТАНОВ. Результат выдаётся на выход С, откуда может быть принят в тот или иной регистр процессора в соответствии с микрооперацией поля С.

На структурной схеме не показана схема контроля правильности десятичных данных, однако она присутствует: с состав ББА входит триггер неверных десятичных данных, устанавливаемый этой схемой при попытке выполнить десятичную операцию.

Входные регистры РА и РВ

БА имеет два входа, A и B (заметим, что в данном случае, как и для обозначения выхода БА C, разработчики используют буквы латинского алфавита, хотя в остальных случаях используется кириллица). По каждому из входов поступает восемь бит информации и один контрольный разряд.

Источниками информации для входов А и В являются различные аппаратные регистры машины, выбираемые полями А и В микрокоманды. Подаваемая на эти входы информация запоминается во входных регистрах РА и РВ.

Схема занесения информации в РА приведена на рисунке.

Занесение информации в РА, скан из [1]
Занесение информации в РА, скан из [1]

Передача данных в регистр РА управляется сигналами вида РА:=РН, РА:=РЗ и т. д. — каждый сигнал соответствует определённому источнику. При приёме информации из трёхбитных регистров РМ, РГ, РП она передаётся в три младших бита РА, а пять старших обнуляются. Технически РА является регистром-защёлкой, «прозрачным» во время активности синхросигнала ТИ1З и фиксирующим своё состояние после его окончания.

Помимо приёма информации из регистров, имеется ещё несколько специальных случаев. РА может хранить информацию, занесённую в него ранее — это задаётся нулевым значением в поле микрокоманды А, при декодировании которого формируется сигнал РА:=РА. Как мы можем видеть, он блокирует тактовый сигнал, что препятствует обновлению содержимого регистра.

В РА может быть также занесён нуль (сигнал РА:=0).

Ещё одним источником информации может быть поле константы, входящее в состав микрокоманды (сигнал РА:=КОНСТ). При активности этого сигнала в младшие четыре бита РА принимается информация из разрядов РМК[49:52], а в контрольный бит — из РМК[44]. А вот значение старших четырёх битов РА зависит от того, используется ли в микрокоманде короткий или длинный адрес перехода. Если задан длинный переход (бит РМК[43] равен нулю), в старшие четыре бита заносятся нули; в этом случае константа может иметь значения в пределах 00–0F. Если же используется короткий переход (РМК[43] равен единице), константа имеет значение от 00 до FF включительно, и в старшую половину РА заносятся биты РМК[45:48].

Технически управляющая часть регистра совмещается со входным мультиплексором, точней, с его последней ступенью. Сделать одноступенчатый мультиплексор для требуемого числа входов (16) невозможно из-за технических ограничений; поэтому, по всей вероятности, он является двухступенчатым и выполнен, главным образом, на микросхемах К155ЛР1, К155ЛР3 и расширителях К155ЛД1. Микросхема К155ЛР3 позволяет выбрать один из четырёх источников; каждый расширитель позволяет добавить к ней ещё один источник, причём в одном корпусе микросхемы К155ЛД1 имеется два расширителя; соответственно, одноразрядный восьмивходовый мультиплексор можно реализовать на одной К155ЛР3 и двух К155ЛД1. Один элемент микросхемы К155ЛР1 позволяет осуществить выбор одного из двух источников; внутри микросхемы имеется два элемента, причём к одному из них могут подключаться расширители.

Регистр РВ не имеет принципиальных отличий от РА. Основным отличием является намного большее количество возможных источников информации: помимо аппаратных регистров процессора в узком смысле слова, а также нуля и константы, к ним относятся регистры так называемого блока связи с внешними устройствами: РР3–РР6, РР9, РРБ. РРВ, РРГ, РРД, РКП, РРЕ, РРП. Эти регистры входят в состав каналов ввода-вывода и пульта управления, поэтому существуют в нескольких экземплярах (до четырёх). Выбор одного из них осуществляется отдельным мультиплексором, и на вход В поступает уже выбранное значение, принимаемое по сигналу РВ:=РВК, формируемому для значений поля микрокоманды В, равных 10–19, 1C и 1D (аббревиатура РВК может расшифровываться, например, как «регистр выбранного канала» — выбор конкретного канала или пульта осуществляется битами РБС[2:5], что было описано в предыдущей статье). Кроме того, на вход В можно подать содержимое байта состояния самого БА (регистр ББА), который будет описан позже.

Узел управляющих сигналов

Структурная схема УУС показана на рисунке.

Структурная схема узла управляющих сигналов, скан из [1]
Структурная схема узла управляющих сигналов, скан из [1]

В состав УУС входят: четырёхразрядный регистр прямой функции РПФ, два пятиразрядных регистра косвенной функции РКФ и РКФ ДОП, триггер режима ТРЕЖ, коммутатора кода функции и её дешифратора.

На вход РПФ подаётся поле ФУНКЦИЯ микрокоманды, т. е. содержимое разрядов РМК[9:12]; занесение кода выполняется по ТИ1. Зачем понадобился регистр для хранения кода функции, который и так хранится в РМК и не меняется до самого конца такта, литература не поясняет.

На вход старших четырёх битов РКФ информация поступает из поля КМЛ микрокоманды, т. е. из разрядов РМК[49:52]. Она принимается по тактовому импульсу ТИ2, если в поле УСТАНОВ задана микрооперация ЗКФ (занесение косвенной функции), по которой вырабатывается сигнал РКФ:=КМЛ.

Младший бит устанавливается по ТИ2, если в поле ДЕФОРМАЦИЯ В задана микрооперация ПЕРЕКОС КОСВЕННОЙ ФУНКЦИИ, и сбрасывается по ТИ2, если эта микрооперация отсутствует, а в поле УСТАНОВ задана микрооперация ЗКФ.

Регистр РКФ ДОП нужен для сохранения содержимого РКФ на время микропрограммной приостановки для обслуживания мультиплексного канала. Информация в него заносится по тактовому импульсу ХИ1, если имеется сигнал РВМ:=РАПП, вызывающий сохранение адреса микрокоманды в регистре РВМ для последующего возврата из микропрограммы обслуживания мультиплексного канала к прерванной микропрограмме центрального процессора, а триггер контроля машины ТКТРМ сброшен (т. е. если нет аппаратного сбоя — его обнаружение вызовет вход в микропрограмму обработки аппаратных ошибок независимо от наличия запросов каналов на МПРС, а в такой ситуации сохранение РКФ не требуется — он изменяется только основными микропрограммами процессора и микропрограммой обслуживания мультиплексного канала). Обратная пересылка выполняется по синхроимпульсу ТИ2 при наличии сигнала РАПП:=РВМ — он вырабатывается в последней микрокоманде микропрограммы обслуживания мультиплексного канала для возврата к прерванной микропрограмме процессора.

Триггер режима ТРЕЖ определяет, будет ли в текущем такте выполняться прямая или косвенная функция. Он устанавливается по синхроимпульсу ТИ1, когда в поле ФУНКЦИЯ указано использование косвенной функции, и сбрасывается по ТИ1 в противном случае. Его выход управляет мультиплексором функции, передающим её код на дешифратор.

Возможность использования то прямой, то косвенной функции позволяет сократить размер микропрограммы. Не надо быть большим знатоком ассемблера и цифровой схемотехники, чтобы понять, что такие машинные команды, как, например И, ИЛИ и ИСКЛЮЧАЮЩЕЕ ИЛИ, выполняются в общем и целом абсолютно одинаково — вся разница заключается исключительно в собственно операции обработки данных, а всё остальное (формирование адресов операндов, их выборка из памяти, запись результата, установка кода условия и т. д.) идентично. Поэтому микропрограммы реализации подобных команд заносят в РКФ код функции, зависящий от кода операции, которая должна быть выполнена, после чего переходят к общей микропрограмме, выполняющей все остальные действия. Нужда в косвенной функции в микропрограмме обслуживания мультиплексного канала не столь очевидна; моё предположение — она используется для увеличения или уменьшения адреса данных в процессе их приёма или передачи (в остальном алгоритм обмена данными идентичен независимо от направления изменения адреса). Косвенно это предположение подтверждается тем, что микропрограмма обслуживания селекторного канала не нуждается в использовании косвенной функции — а в нём передача данных, включая изменение адреса, выполняется чисто аппаратными средствами.

Дешифратор кода операции вырабатывает серию управляющих сигналов, поступающих на остальные узлы БА; правила выработки сигналов показаны в следующей таблице.

Микрооперация

Код микрооперации

Вырабатываемые сигналы

A | B

0000

К, Л, М, И

ВЫП. КФ

0001

К, И

A – B ДЕС

0010

К, Г, Н, У, В, С, И

A – B ДВ

0011

К, Г, У, В, С, И

A ТРАНЗИТ

0100

К, Л, И

A & B

0101

К, И

B – A ДЕС

0110

К, Г, Н, Х, В, С

B – A ДВ

0111

К, Г, Х, В, С

A | ~B

1000

К, Л, Г

B ТРАНЗИТ

1001

К, М

A ^ B

1010

Л, М

~A & B

1011

М

СДВИГ B ВПРАВО

1100

Х, В, Т, И

СДВИГ B ВЛЕВО

1101

Х, В, И

A + B ДЕС

1110

Л, М, Д, Н, Х, В, И

A + B ДВ

1111

Л, М, Х, В

Комбинация сигналов К, Л, М, Г определяет операцию, выполняемую логическим узлом (УЛ).

Сигнал Д выдаётся только в операции десятичного сложения: он управляет первым десятичным корректором (УДК1), заставляя его прибавить 0110 к каждому полубайту первого операнда.

Сигнал Н выдаётся в операциях десятичного сложения и вычитания и указывает, что второй десятичный корректор (УДК2) должен при отсутствии переноса из того или иного полубайта результата условий прибавить к этому полубайту 1010. Надо полагать, этот же сигнал разрешает работу схемы контроля десятичных данных — литература об этом молчит.

Сигналы Х, Т, У управляют узлом сдвига вправо (УСД): наличие сигнала Х при отсутствии Т задаёт прямую передачу данных, одновременное наличие Х и Т — сдвиг на два разряда вправо, а наличие У — инверсию передаваемого значения. Если все три сигнала отсутствуют, на выход УСД подаются нули.

Сигнал В присутствует во всех арифметических операциях и при сдвигах. Он управляет работой байта состояния БА, разрешая приём выходного переноса в один из двух входящих в его состав триггеров переноса, и разрешает приём входного переноса в узел переносов (УП).

Сигнал С выдаётся в операциях вычитания: он инвертирует входной и выходной переносы.

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

Помимо перечисленных сигналов, дешифратор вырабатывает ещё один сигнал — П7:=ТП. Он формируется в арифметических операциях и операции сдвига влево и вызывает подачу на седьмой (младший) разряд узла переносов состояния используемого триггера переноса или значения, задаваемого полем микрокоманды УСТАНОВ.

Первый десятичный корректор (УДК1)

Первый десятичный корректор при наличии управляющего сигнала Д прибавляет значение 6 (0110) к каждому полубайту первого операнда, поступающего из регистра РА, при этом возможный перенос из младшего полубайта в старший игнорируется. На практике он возникать не должен, поскольку для этого необходимо, чтобы соответствующий полубайт содержал код 1010 или больше, что является некорректной десятичной цифрой. По сути, УДК1 — два не связанных между собой трёхразрядных сумматора, прибавляющих к числу константу.

Узел перекосов (УПК)

При выполнении прямой функции операнд B может передаваться для дальнейшей обработки различными способами, задаваемыми полем микрокоманды ДЕФОРМАЦИЯ В:

  • ПРЯМО — прямая передача содержимого РВ для дальнейшей обработки;

  • НАКРЕСТ — передача с перестановкой полубайтов;

  • МЛАДШИЕ ПРЯМО — младший полубайт передаётся обычным образом, вместо старшего полубайта передаются нули;

  • СТАРШИЕ ПРЯМО — старший полубайт передаётся обычным образом, вместо младшего полубайта передаются нули;

  • МЛАДШИЕ НАКРЕСТ — младший полубайт РВ передаётся вместо старшего полубайта для дальнейшей обработки, а вместо самого младшего полубайта передаются нули;

  • СТАРШИЕ НАКРЕСТ — старший полубайт РВ передаётся вместо младшего полубайта для дальнейшей обработки, а вместо самого старшего полубайта передаются нули;

  • ПЕРЕКОС — для дальнейшей обработки место старшего полубайта занимает младший полубайт РВ, а место младшего полубайта — содержимое буферного регистра перекоса. Старший полубайт РВ сохраняется в буфере перекоса для последующего использования. Схема передачи информации в режиме ПЕРЕКОС приведена на рисунке.

Передача информации в режиме ПЕРЕКОС, скан из [1]
Передача информации в режиме ПЕРЕКОС, скан из [1]

При выполнении косвенной функции операнд B может всегда передаваться с перекосом, для чего необходимо установить бит РКФ[4], описанный ранее (см. «Узел управляющих сигналов»). Если этот бит сброшен, способ передачи операнда B для косвенной функции определяется полем ДЕФОРМАЦИЯ B, как и для прямой функции.

Содержимое поля микрокоманды ДЕФОРМАЦИЯ B сохраняется в регистре РДЕФ по тактовому импульсу ТИ1 — точно так же, как значение поля ФУНКЦИЯ сохраняется в РПФ. Далее оно декодируется дешифратором ДШ ДЕФ, формирующим сигналы, управляющие прохождением данных через узел перекосов.

Выходом узла перекосов является 8-разрядная шина ПК[0:7] (кстати говоря, в советской литературе того времени и, надо полагать, в технической документации номера битов заключались не в квадратные, а в круглые скобки, я же в описании предпочитаю использовать более привычные в современных условиях квадратные — они, в частности, используются в языке описания аппаратуры Verilog/SystemVerilog; круглые скобки я сохраняю лишь в полных именах сигналов). На его старшую половину, т. е. в разряды ПК[0:3], может подаваться либо старшая, либо младшая половина регистра РВ, либо нули, что задаётся управляющими сигналами ПК(0-3):=РВ(0-3), ПК(0-3):=РВ(4-7) и ПК(0-3):=0 соответственно.

На младшую половину выхода узла перекосов может подаваться младшая или старшая половина регистра РВ, нули или содержимое буфера перекосов, что задаётся управляющими сигналами ПК(4-7):=РВ(4-7), ПК(4-7):=РВ(0-3), ПК(4-7):=0 и ПК(4-7):=БПК соответственно. Одновременно с последним вырабатывается сигнал БПК:=РВ(0-3), заносящий в буфер перекоса содержимое старшей половины РВ.

Сам буфер перекоса технически состоит из двух регистров. В первый из них, носящий обозначение РБПК1, информация заносится из РВ[0:3] при наличии сигнала БПК:=РВ(0-3) по тактовому импульсу ТИ4, т. е. в самом конце такта (это можно было бы делать и по ТИ3, поскольку приём информации в РВ заканчивается в первой половине такта). Если имеется сигнал БПК:=0, вырабатываемый при наличии в поле микрокоманды УСТАНОВ микрооперации СБП (сброс буфера перекоса), то производится обнуление РБПК1 (вероятно, тоже по ТИ4; какой из сигналов — БПК:=РВ(0-3) или БПК:=0 — имеет приоритет, литература не говорит, но, надо полагать, что последний: тогда обнуление буфера перекосов может выполняться одновременно с последней операцией перекоса).

Информация во второй регистр, РБПК2, заносится из РБПК1 по синхроимпульсу ТИ1 без каких-либо управляющих сигналов; именно из РБПК2 информация попадает на линии ПК[4:7] при наличии сигнала ПК(4-7):=БПК. Необходимость в двух регистрах вызвана тем, что они выполнены не на флип-флопах, а на триггерах-защёлках, а информация на его выходе должна оставаться неизменной на протяжении всего времени выполнения операции в БА и сохранения результата, т. е. до самого конца такта.

Зачем понадобились операции, выполняемые узлом перекосов? Достаточно очевидно, что, по крайней мере, часть из них полезна при выполнении команд десятичной арифметики. В частности, самый младший байт каждого десятичного операнда в младшем полубайте содержит код знака, а в старшем — младшую цифру операнда; соответственно, при анализе знаков надо выделить из него младший полубайт, а при выполнении собственно операции — старший. Этого можно было бы добиться обычными логическими операциями, но ценой потери времени на выполнение лишних микрокоманд, в то же время объём аппаратуры, необходимой для реализации соответствующих операций передачи, очень невелик и является приемлемым даже для машины малой производительности, где важнейшей характеристикой является её цена, а не скорость обработки данных.

Потенциально операции, выполняемые БП, полезны и при реализации сдвигов. Система команд Системы 360 предусматривает только многоразрядные сдвиги, где количество разрядов задаётся одним из операндов. В то же время БА как таковой реализует лишь одноразрядные сдвиги: для многоразрядных нужно очень много аппаратуры (широкие мультиплексоры — крайне затратная вещь в плане «железа»). Возможно, соответствующие команды выполнялись комбинированием перекосов и обычных сдвигов — на этот счёт никаких данных нет.

С уверенностью можно сказать, что аппаратура БП играет свою роль при реализации трёх специфических команд пересылки — MVN, MVZ и MVO. Как и команда обычной пересылки MVC (её аббревиатура расшифровывается как move characters — в названиях команд Системы 360 символами именуются байты, хотя во всех остальных случаях, в том числе в описаниях команд, они именуются именно байтами), они пересылают от 1 до 256 байтов памяти включительно, но, в отличие от MVC, пересылают не целые байты. Команды MVN и MVZ — ПЕРЕСЫЛКА ЦИФР и ПЕРЕСЫЛКА ЗОН соответственно — пересылают в область приёмника лишь младший или старший полубайт каждого байта источника, второй полубайт каждого байта приёмника остаётся неизменным. Названия этих команд связаны с тем, что в кодах цифр 0–9, имеющих в EBCDIC шестнадцатеричные значения F0–F9, старший полубайт содержит код зоны, а младший — код цифры. Пересылаемые данные никак не проверяются, поэтому данные команды годятся для обработки любых последовательностей байтов независимо от их значений. Любопытно, что в документации на Систему 360 эти две команды, как и MVO, относятся к командам десятичной арифметики, но реализованы в каждой «полноценной» машине, даже если собственно десятичные операции (сложение, вычитание и др.) отсутствуют. В Системе 370 они перекочевали в раздел «Команды общего назначения».

Команда MVO — ПЕРЕСЫЛКА СО СДВИГОМ (англ. move with offset) — несколько хитрее: содержимое операнда-источника помещается вплотную слева к самому младшему полубайту операнда-приёмника. По сути, происходит пересылка содержимого источника в область приёмника со сдвигом на 4 бита, т. е. на одну десятичную цифру. Эта команда предназначена, в первую очередь, для ускорения операций умножения и деления десятичных чисел на 10 или кратную 10 величину, но, в отличие от настоящих команд десятичной арифметики, никак не проверяет пересылаемые данные. Очевидно, что именно в этой команде находит своё применение микрооперация ПЕРЕКОС.

Наконец, операции УП потенциально полезны в операциях с плавающей запятой. Здесь дело в том, что в Системе 360 эти числа являются, условно говоря, не двоичными, а шестнадцатеричными: порядок числа является степенью 16, а не двойки; соответственно, при нормализации и в других подобных ситуациях мантисса сдвигается не на один бит, а сразу на четыре.

Логический узел (УЛ)

Работа логического узла применительно к одному биту может быть описана следующей формулой:

Л[n] = ( К &  ДК[n] &  ПК[n] ) |
       ( Л &  ДК[n] & ~ПК[n] ) |
       ( М & ~ДК[n] &  ПК[n] ) |
       ( Г & ~ДК[n] & ~ПК[n] )

Здесь Л[n] — n-ый разряд выхода логического узла; К, Л, М, Г — управляющие сигналы, поступающие из УУС; ДК[n] и ПК[n] — n-ые разряды выходов первого десятичного корректора и узла перекосов соответственно.

Комбинация управляющих сигналов определяет, какая именно операция будет выполняться. Скажем, в операциях сложения одновременно активны сигналы Л и М, в результате чего УЛ выполняет операцию «исключающее ИЛИ».

Узел сдвига (УСД)

Узел сдвига осуществляет передачу данных с выхода узла перекосов на вход узла переносов либо без изменения, либо с инверсией, либо со сдвигом вправо на два разряда, что управляется сигналами Х, У и Т:

  • если активен только сигнал Х, на выход передаётся входная информация в неизменном виде, что применяется в операциях сложения, вычитания вида В – А (в них инвертируется первый, а не второй операнд) и сдвига влево;

  • если активен только сигнал У, на выход передаётся инвертированная входная информация, что применяется в операциях вычитания вида А – В;

  • если одновременно активны сигналы Х и Т, производится сдвиг вправо, используемый для одноимённой операции;

  • если все три сигнала неактивны, на выход УСД подаётся нулевая информация, что используется во всех остальных операциях (логических, передачи информации и при сдвиге влево).

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

Как уже отмечалось, информация сдвигается вправо на два разряда, хотя сама операция сдвига является одноразрядной. Дело здесь в том, что в обеих операциях сдвига будет выполнен сдвиг влево на один разряд (за него отвечает узел переносов), и сдвиг на два бита вправо в узле сдвига обеспечивает вместе с ним сдвиг вправо на один бит.

Очевидно, что при сдвиге вправо на два бита на выходы УСД[2:7] передаются входные сигналы ПК[0:5].

На выход УСД[1] подаётся значение входного переноса — им будет либо содержимое одного из триггеров переносов, входящих в состав ББА, либо значение, задаваемое полем микрокоманды УСТАНОВ, о чём подробней будет сказано позже. Заметим, что в [1] относительно имени этого сигнала имеются разночтения: в одном месте говорится о сигналах П(0), а в другом — П(С). Похоже, правильным является именно второе обозначение; буква С говорит в нём о том, что этот перенос поступает в узел сдвига.

На выход УСД[0] при сдвиге вправо передаётся входной сигнал ПК[7], т. е. младший бит становится старшим. В узле переносов он превратится в выходной перенос, т. е. будет выдвинут за пределы разрядной сетки.

Разряд ПК[6] будет подан на узел сдвига в обход основного пути данных — он станет входным переносом и в итоге попадёт в младший разряд результата, т. е. будет сдвинут вправо на один бит, как и все остальные разряды.

Узел переносов (УП)

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

На вход УП подаются: первая полусумма, полученная в логическом узле, и исходное значение второго операнда с выхода УСД. Кроме того, на него подаётся входной перенос — значение одного из триггеров переноса из состава ББА или значение, задаваемое микрооперацией поля УСТАНОВ, что будет описано позже; сигнал входного переноса носит имя П(7), поскольку поступает в седьмой разряд. Исключением является операция сдвига вправо: в роли входного переноса в этом случае будет выступать бит ПК[6].

Технически УП состоит из двух одинаковых частей, схема одной из которых приведена на рисунке.

Узел переносов, младшая половина; скан из [1]
Узел переносов, младшая половина; скан из [1]

Выходы узла переносов носят обозначения УП(0-7), причём цифра указывает, к какому разряду суммы должен добавляться данный бит переноса. В частности, линия УП(7) — это перенос в младший разряд, технически совпадающий с сигналом П(7) — входным переносом (узел переносов просто передаёт свой вход П(7) на свой выход УП(7)). Кроме того, узел переноса формирует перенос из старшего разряда результата, но имя соответствующего сигнала нигде не упоминается. На приведённой схеме показано формирование разрядов УП(3-6), т. е. переносов из разрядов 4:7 в разряды 3:6; формирование неназванного сигнала переноса из старшего разряда и переносов УП(0-2) выполняется точно такой же схемой, меняются лишь её входные сигналы.

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

В самом низу схемы расположен элемент 2,2И-2ИЛИ-НЕ, формирующий перенос из седьмого (самого младшего) в шестой разряд — сигнал УП(6). Очевидно, что такой перенос возникает в том случае, если хотя бы два из трёх слагаемых равны единице. Тремя этими слагаемыми являются седьмой бит первого операнда РА(7), седьмой бит второго операнда РВ(7) и перенос в седьмой разряд, т. е. входной перенос П(7).

Входы нижнего элемента И обозначены как УЛ(7) и УП(7). Первый из этих сигналов — выход седьмого разряда логического узла, выполняющего при сложении операцию «исключающее ИЛИ» между седьмыми разрядами обоих операндов; он будет равен единице, если один и только один из разрядов исходных операндов равен единице. Второй из этих сигналов, как уже говорилось, — сигнал переноса в седьмой разряд, являющийся выходом, а не входом УП; логически правильней было бы обозначить его в данном случае как П(7), хотя технически это одно и то же. Таким образом, данный элемент И выдаёт на свой выход единицу, т. е. формирует перенос в шестой разряд, если имеется входной перенос в данный (седьмой) разряд и ровно один из соответствующих битов исходных операндов равен единице.

Верхний элемент И отвечает за формирование переноса, когда оба бита исходных операндов равны единице. Как можно видеть, его входами являются сигналы УСД(7) и –УЛ(7). Первый из них — седьмой разряд второго операнда, поскольку при сложении он проходит все лежащие на его пути блоки, включая узел сдвига, в неизменном виде. Второй сигнал — инверсное значение выхода логического узла, т. е. он равен единице, если оба младших бита обоих операндов либо нулевые, либо единичные. Соответственно, схема И даст на выходе единицу только для случая, когда оба бита исходных операндов единичные.

Обе схемы И объединяются схемой ИЛИ, формирующей итоговый перенос; за ней следует инвертор, поэтому на выходе мы видим инверсное значение переноса — сигнал –УП(6). Технически вся эта часть схемы собирается на половине микросхемы К155ЛР1, содержащей два элемента 2,2И-2ИЛИ-НЕ.

Обратимся теперь к следующему элементу 2,2И-2ИЛИ-НЕ, формирующему сигнал –УП(5). Очевидно, что логика формирования переноса будет абсолютно той же самой, но здесь на схеме допущены сразу две ошибки. Во-первых, на верхний элемент схемы поданы сигналы –УСД(6) и –УЛ(6), что верно ровно наполовину: первый из них должен быть без инверсии, т. е. УСД(6). Во-вторых, входным переносом в эту схему является выходной перенос, сформированный предыдущей схемой, — но он должен быть прямым, а формируется-то инверсный! Соответственно, нужен инвертор на пути этого переноса (на схеме следовало изобразить кружок на входе переноса в нижний элемент И).

В следующем элементе 2,2И-2ИЛИ-НЕ, формирующем сигнал –УП(4), опять допущена ошибка с входным переносом: подаётся инверсное, а не прямое значение сигнала; а вот вход УСД(5) показан правильно, без инверсии.

Обратимся теперь к верхней части схемы, где показано формирование сигнала –УП(3) — переноса из младшего полубайта в старший. По своей сути это — схема ускоренного переноса, формирующая перенос не последовательно (выход предыдущего разряда подаётся на вход последующего, как это было для битов УП(7-5)), а параллельно. Как видим, здесь имеется пять элементов И, каждый из которых формирует перенос при соблюдении соответствующих условий.

В самом верху расположен пятивходовый элемент И. На его верхние четыре входа подаются сигналы УЛ(4-7), т. е. младший полубайт, сформированный логическим узлом. Поскольку УЛ выполняет операцию «исключающее ИЛИ», на УЛ(4-7) будут присутствовать все единицы лишь в случае, если в каждой паре битов исходных операндов имеется лишь один единичный бит, а второй равен нулю, что разрешает сквозное распространение входного переноса. А вот нижний входной сигнал этого элемента обозначен неверно — этим сигналом является П(7), он же УП(7) (без инверсии).

Следующий, также пятивходовый элемент И обеспечивает формирование переноса, если он возникает при сложении младшей пары битов исходных операндов, а старшие три пары разрешают его распространение. Первые два его входных сигнала — это УСД(7) и –УЛ(7); первый на схеме ошибочно обозначен как инверсный. Они оба будут равны единице, если оба исходных седьмых бита равны единице (операция «исключающее ИЛИ», выполняемая в УЛ, даст на выходе УЛ(7) нуль, который при подаче на вход данного элемента И инвертируется; подача одновременно с ним УСД(7) гарантирует, что оба исходных бита единичные: сам по себе УЛ(7) будет равен нулю и в случае, если оба исходных бита нулевые). На остальные три входа поданы сигналы УЛ(4-6), разрешающие распространение переноса (в каждой паре исходных разрядов 4:6 имеется ровно по одной единице).

Остальные три элемента И действуют по тому же принципу, и в каждом из них на схеме допущены ошибки. На третий, четырёхвходовый элемент И подаются сигналы УСД(6), –УЛ(6), УЛ(5) и УЛ(4), на четвёртый — УСД(5), –УЛ(5) и УЛ(4), на последний — УСД(4) и –УЛ(4).

Узел суммирования по модулю 2 (УСМ |2|)

УСМ |2| — это просто набор элементов «исключающее ИЛИ», на входы которых подаются сигналы с логического узла и узла переносов. Он завершает суммирование и вычитание операндов, а в остальных случаях на один из его входов подаются нули, поэтому он просто передаёт дальше сигналы со своего второго входа: в операциях сдвига полезная информация поступает с узла переносов, а в логических операциях — с УЛ.

Второй десятичный корректор (УДК2)

УДК2 является последним каскадом обработки информации в БА. На его вход подаётся результат операции узла суммирования по модулю 2, к каждому полубайту которого при наличии управляющего сигнала Н (формируется для всех десятичных операций) прибавляется значение 1010, если из этого полубайта не было переноса. Значения переносов поступают с узла переносов (сигнал УП(3) для переноса из младшего полубайта и не называемый в литературе сигнал для переноса из старшего полубайта).

Результат работы УДК2 выдаётся на выход БА — шину С. Помимо собственно информационных разрядов С(0-7), производится формирование контрольного бита С(К) и уплотнённого разряда С(5) УПЛ, получаемого операцией «или» между разрядами С(0-5): он заносится в пятый бит регистров РМ, РГ и РП, описанных в предыдущей статье.

Байт состояния БА (ББА)

Байт состояния БА содержит восемь триггеров, отражающих результат выполнения операции в БА; кроме того, он отвечает за формирование входного переноса, подаваемого на вход узла переноса и узла сдвига вправо (соответственно сигналы П(7) и П(С)). Триггеры ББА могут анализироваться соответствующими микрооперациями полей УСЛ0 и УСЛ1, определяя дальнейший ход микропрограммы.

Содержимое всего ББА может быть подано на вход В БА с целью его передачи операцией В ТРАНЗИТ на выход БА и последующей записи в локальную память — этим обеспечивается сохранение содержимого ББА на время микропрограммной приостановки для обслуживания каналов. Естественно, может быть выполнена и обратная операция: прочитанное из ЛП значение подаётся на вход А БА, задаётся функция А ТРАНЗИТ, а в поле УСТАНОВ указывается микрооперация ИГН, и в итоге значение из РА заносится в ББА вместо обычного обновления состояния триггеров ББА по результату операции. В дальнейшем такая загрузка ББА упоминаться не будет, и речь пойдёт только о «нормальной» работе с его триггерами.

В состав ББА входят следующие триггеры.

  • ТЗН, он же разряд ББА[0] — триггер знака. Информация в него принимается в конце каждого такта из старшего разряда результата, т. е. с линии С(0).

  • ТРКФ (ББА[1]) — триггер результата косвенной функции. Устанавливается при выполнении любой косвенной функции, если её результат не равен нулю; получение нулевого результата не изменяет состояние триггера. Для обнуления ТРКФ требуется выполнить микрооперацию 0РКФ или ГАШ поля УСТАНОВ. Благодаря такому подходу обеспечивается формирование признака нуля при обработке многобайтовых величин: триггер сбрасывается перед обработкой первого байта и проверяется после обработки последнего.

  • ТРПФ (ББА[2]) — триггер результата прямой функции. Действует точно так же, как ТРКФ, но сбрасывается микрооперациями 0РПФ или ГАШ, а устанавливается получением ненулевого результата в прямой функции.

  • ТПКФ (ББА[3]) — триггер переноса косвенной функции; о переносах будет сказано ниже.

  • ТППФ (ББА[4]) — триггер переноса прямой функции.

  • ТПЕР (ББА[5]) — триггер переполнения. Изменяет своё состояние при выполнении операций сложения, вычитания и сдвига влево: устанавливается, если переносы в старший и из старшего разряда не совпадают (что и является признаком переполнения), и сбрасывается в противном случае. При выполнении других операций не изменяется. Может быть сброшен микрооперацией ГАШ.

  • ТНДД (ББА[6]) — триггер неверных десятичных данных. Устанавливается в операциях десятичного сложения и вычитания, если в каком-либо из полубайтов операндов присутствует нецифровой код, т. е комбинация 1010–1111; сбрасывается микрооперацией ГАШ. Из литературы не ясна точка контроля значения операндов; для первого операнда ей, очевидно, является выход РА, а вот для второго более разумным выглядит контроль на выходе узла перекосов, а не на выходе РВ.

  • ТЧЕТ (ББА[7]) — триггер чётности. Изменяется в конце каждого такта, сохраняя значение младшего бита результата (состояние выхода С(7)).

Теперь о переносах. Изменение состояния ТППФ происходит в следующих случаях:

  • при выполнении прямой операции сложения, вычитания или сдвига, если при этом в поле УСТАНОВ не задана микрооперация ИГН — она блокирует изменение состояния триггера переноса;

  • при выполнении любой другой операции, если в поле УСТАНОВ задана одна из микроопераций ГАШ, 0ППФ или 1ППФ.

В случае изменения состояния ТППФ при выполнении операции вычитания выходной перенос, сформированный узлом переносов, перед занесением в ТППФ инвертируется; при выполнении операций сложения и сдвига принимается прямое значение переноса. Если в микрокоманде, содержащей микрооперацию ГАШ, 0ППФ или 1ППФ, одновременно задана прямая операция сложения, вычитания или сдвига, в ТППФ будет принят перенос, сформированный в результате операции, а не задаваемый одной из этих микроопераций.

Занесение в ТПКФ выполняется точно так же, но при выполнении косвенной операции сложения вычитания или сдвига, а также по микрооперациям ГАШ, 0ПКФ и 1ПКФ.

Формирование входного переноса для прямой арифметической или сдвиговой операции осуществляется по следующим правилам:

  • если в поле УСТАНОВ задана микрооперация ИГН, ГАШ или 0ППФ, перенос будет равен нулю;

  • если в поле УСТАНОВ задана микрооперация 1ППФ, перенос будет равен единице;

  • в остальных случаях перенос будет равен состоянию триггера ТППФ на момент начала операции.

Правила формирования входного переноса в косвенных операциях такие же с заменой «прямых» триггера и микроопераций на «косвенные».

Сформированное по этим правилам значение переноса при выполнении операций сложения подаётся на вход узла переносов (сигнал П(7)) в неизменном виде, а при выполнении операций вычитания — в инверсном. В операциях сдвига сформированный входной перенос подаётся на вход узла сдвига (сигнал П(С)).

Таким образом, микрооперации ГАШ, ИГН, 0ПКФ/0ППФ и 1ПКФ/1ППФ позволяют явным образом указать значение входного переноса (до его инверсии в случае операции вычитания) вместо использования содержимого соответствующего триггера, при этом не препятствуя сохранению в триггере выходного переноса этой же микрокоманды. Благодаря такому подходу несколько упрощается написание микропрограмм обработки многобайтовых величин, поскольку в большинстве случаев можно обойтись без предварительной установки или сброса триггера: в первой из микрокоманд необходимое значение переноса указывается одной из этих микроопераций, а в последующих они не используются, и перенос задаётся состоянием триггера, установленным предшествующей арифметической или сдвиговой операцией.

Технически сформированное значение входного переноса по тактовому сигналу ТИ1З сохраняется в специальном триггере входного переноса ТП — сигналы П(7) и П(С) поступают именно с него. Когда именно изменяется состояние самих триггеров переноса, литература не сообщает. Можно предположить, что занесение в них значений, задаваемых микрооперацией поля УСТАНОВ, выполняется по ТИ3, а приём выходного переноса в операциях сложения, вычитания и сдвига — по ТИ4; в таком случае выполнение указанных операций «перебивает» занесение, выполняемое по полю УСТАНОВ, без использования дополнительной логики.

Выполнение операций в БА

По общему алгоритму и использованию функциональных узлов все операции можно разделить на три группы:

  • логические операции и операции передачи данных;

  • арифметические операции;

  • операции сдвига.

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

Для выполнения операций первой группы используется только логический узел, функция которого зависит от вида операции. На входы УЛ поступает информация из РА (через первый десятичный корректор, который в этих операциях просто передаёт информацию в неизменном виде) и из РВ. Результат операции УЛ поступает на один из входов узла сложения по модулю 2, а на второй его вход подаётся нулевая информация, сформированная на выходе узла сдвига вправо и прошедшая через узел переносов (на него подаётся также нулевой входной перенос). Благодаря этому УСМ |2| передаёт без изменения информацию со своего первого входа, то есть поступившую от УЛ, на свой выход, и далее она через второй десятичный корректор поступает, не претерпевая изменений, на выход БА.

На следующем рисунке показан путь данных через узлы БА при выполнении операций A | B, A | ~B и А ТРАНЗИТ над операндами 0111 1110 и 0110 1010.

Путь данных при выполнении логических операций, скан из [1]
Путь данных при выполнении логических операций, скан из [1]

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

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

В операциях вычитания логический узел выполняет операцию «эквивалентность»: на его выходе формируется единица, если оба входа равны, что соответствует выполнению операции «исключающее или» между прямым значением уменьшаемого и инверсным значением вычитаемого. В случае, если вычитаемым является второй операнд, он при прохождении через узел сдвига вправо инвертируется; если вычитаемым является первый операнд, узел сдвига вправо передаёт второй операнд без изменений. Узел переносов опять формирует межразрядные переносы, но на его вход поступает инверсное значение входного переноса, а формируемый им выходной перенос перед запоминанием в соответствующем триггере тоже инвертируется. УСМ |2| обычным образом выполняет второе полусуммирование, давая окончательный двоичный результат.

Следующие два рисунка иллюстрируют выполнение двоичных и десятичных арифметических операций над операндами 0111 1110 и 0110 1010.

Путь данных при выполнении двоичных операций A+B, A–B и B–A, скан из [1]
Путь данных при выполнении двоичных операций A+B, A–B и B–A, скан из [1]
Путь данных при выполнении десятичных операций A+B, A–B и B–A, скан из [1]
Путь данных при выполнении десятичных операций A+B, A–B и B–A, скан из [1]

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

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

Далее сформированные межразрядные переносы, т.е. сдвинутый операнд В со вдвинутым в него входным переносом, подаётся на второй вход узла суммирования по модулю 2; на первый его вход поступают нули с выхода УЛ. Как следствие, выход узла переносов в неизменном виде передаётся на выход БА.

Описанный процесс показан на следующем рисунке.

Путь данных при сдвиге влево, скан из [1]
Путь данных при сдвиге влево, скан из [1]

Операция сдвига вправо отличается тем, что в узле сдвига операнд В сдвигается на два разряда вправо, причём в него вставляется входной перенос, а разряд B[6] подаётся на вход узла переносов в качестве входного переноса. Путь данных в этих узлах показан на следующем рисунке.

Путь данных в узлах сдвига и переноса при сдвиге вправо, скан из [1]
Путь данных в узлах сдвига и переноса при сдвиге вправо, скан из [1]

Заключение

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

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

Именно по этой причине арифметико-логический блок процессора ЭВМ ЕС-1020 построен «в глубину»: обрабатываемые данные проходят один за другим несколько функциональных узлов, совместная работа которых и обеспечивает выполнение требуемой операции. Такая реализация позволяет в очень значительной степени сократить объём аппаратуры по сравнению с формированием результата максимально «плоской» схемой, что является критичным для машины малой производительности. В то же время такое решение само по себе не является главным «тормозом» этой модели: если обратиться к временной диаграмме работы процессора, можно увидеть, что собственно выполнение операции в БА занимает меньше половины длительности такта. Таким образом, к недостаткам следует отнести не малую скорость работы БА, а откровенное недоиспользование его возможностей, — впрочем, это ожидаемо для первой серийной машины данной архитектуры. В своей следующей модели, ЕС-1022, разработчики учли этот недостаток, что позволило резко (в 4–6 раз) поднять производительность при не слишком большом росте аппаратных затрат — но это тема для отдельной серии публикаций.

Литература

  1. В. В. Пржиялковский и др. Процессор ЭВМ ЕС-1020. Под общей редакцией А. М. Ларионова. — М., "Статистика", 1975.

Комментарии (8)


  1. rutenis
    12.06.2023 12:45
    +2

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

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


    1. SIISII Автор
      12.06.2023 12:45

      Угу, в "Принципах работы Системы 360" это достаточно подробно расписано.


  1. checkpoint
    12.06.2023 12:45

    А нет ли информации на какой именно логике строился блок арифметики ЕС-1020 ? Использовались ли микросхемы К155ИП3 или все было на дискретной логике ? Я немного игрался с SN74181N (К155ИП3) и мне видится, что почти весь функционал описанного БА (кроме двоично-десятичного) хорошо укладывается на эту микросхему. Год выпуска у микросхемы и ЭВМ - начало 70-х.


    1. SIISII Автор
      12.06.2023 12:45

      В самом начале цикла я писал об этом: всего несколько самых ранних микросхем 155-й серии, до К155ИП3 было далеко, как до Луны (она была освоена для производства ЕС-1033, что произошло лишь через несколько лет).


  1. EntityFX
    12.06.2023 12:45
    +1

    155ЛА3
    155ЛА3

    Имеется несколько отсканированных книжек по ЕС, делюсь с вами: https://disk.yandex.ru/d/mDAyZso5gmYfxQ


    1. SIISII Автор
      12.06.2023 12:45
      +1

      Спасибо. У меня они все в бумажном виде есть, но кому-то может быть интересно почитать.

      Пы.Сы. А ТЭЗ от какой-то периферии, похоже: сами машины, где использовались ТЭЗы такого (1-го) типа в середине 1980-х уже не выпускались.


      1. EntityFX
        12.06.2023 12:45

        Напишите о 1033 и 1045. 1033 считают вообще оригинальной машиной.


        1. SIISII Автор
          12.06.2023 12:45

          Если доживу. Правда, о 1045 особо писать нечего: чем сложней машина, тем тоньше книжка по ней :) Наиболее подробно описана как раз ЕС-1020, 1022 уже хуже.