Архитектура ЭВМ

Логические схемы на примере двоичного сумматора

Разбить на страницы
Показывать лекцию целиком

Одноразрядный двоичный сумматор; четырехразрядный двоичный сумматор; оптимизация сумматора с целью ускорения переноса для арифметики большой разрядности; арифметико-логическое устройство (блок) процессора.

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

Одноразрядный двоичный сумматор

Сначала рассмотрим одноразрядный сумматор, который позволяет складывать два бита. Для этого сначала вспомним алгоритм сложения "в столбик", универсальный для систем исчисления с любым основанием. Этот алгоритм предписывает складывать числа, начиная с младших разрядов, причём на входе каждого разряда, помимо слагаемых, есть ещё и перенос из предыдущего, равный 0 или 1, а на выходе, помимо суммы, также равный 0 или 1 перенос в следующий разряд.

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

  • s содержит результат суммы двух слагаемых a и b и переноса из предыдущего разряда c по модулю 2:s=a \oplus b \oplus c;
  • c ' содержит значение переноса; перенос возникает при сложении двух одноразрядных двоичных чисел, когда их сумма плюс значение переноса из предыдущего разряда превышает 1: c ' =(a \wedge b) \vee (b \wedge c) \vee (c \wedge a).
  • Итак, мы имеем функцию f(a,b,c)=(a, c '). Таблица истинности для этой функции представлен в таблице 7.1. Очевидно, что так заданный одноразрядный сумматор является одним шагом для сложения многоразрядных двоичных чисел.

    Таблица истинности для одноразрядного сумматора
    a b c s c '
    0 0 0 0 0
    0 0 1 1 0
    0 1 0 1 0
    0 1 1 0 1
    1 0 0 1 0
    1 0 1 0 1
    1 1 0 0 1
    1 1 1 1 1

    Реализация одноразрядного сумматора с помощью вентилей, то есть логическая схема сумматора, представлена на рис. 1.5. Убедимся, что эта схема действительно делает то, что нужно, то есть соответствует таблице 7.1.

  • Разряд суммы s. Входы a и b схемы поступают на вход вентиля (1) "исключающее или", а его выход и вход c, в свою очередь, на вход вентиля (2) "исключающее или". Выход же вентиля (2) является одновременно и выходом схемы c. Таким образом, получаем, что s=(a \oplus b0 \oplus c = a \oplus b \oplus c, то есть на выходе s мы действительно имеем разряд суммы.
  • Перенос в следующий разряд c ' =(a \wedge b) \vee 9c \wedge (a \oplus b)). Эта формула отличается от ранее предложенной для c ', но легко убедиться, что она даёт тот же результат, причём с использованием меньшего количества вентилей. Действительно, c \wedge (a \oplus b)=c \wedge (a \vee b) \wedge \neg (a \wedge b)= \neg (a \wedge b)\wedge ((b \wedge c) \vee (c \wedge a)), следовательно, (a \wedge b) \vee (c \wedge (a \oplus b))=(a \wedge b) \vee (\neg (a \wedge b) \wedge ((b \wedge c) \vee (c \wedge a)))=(a \wedge b) \vee (b \wedge c) \vee (c \wedge a), то есть мы получаем именно то, что нам и требовалось.
  • ЧЕТЫРЕХРАЗРЯДНЫЙ ДВОИЧНЫЙ СУММАТОР

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

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

    4-разрядный сумматор, складывающий числа, состоящие из цифр a_0a_1a_2a_3 и b_0b_1b_2b_3 соответственно (младшие разряды мы записали слева), можно представить, как функцию следующего вида:

    f(a_0,a_1,a_2,a_3,b_0,b_1,b_2,b_3,c_{\to0})=(s_0,s_1,s_2,s_3,c_{3\to})

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

    Внимательные читатели могли заметить вход c_{\to0}, на который подаётся 0, и выход c_{3\to}. Они оставлены на схеме не только для поддержания надлежащей степени общности. При помощи них можно объединять четырёхразрядные сумматоры в более "длинные", подсоединяя выход переноса предыдущего ко входу переноса следующего так же, как мы соединяли одноразрядные сумматоры, получая восьмиразрядные, двенадцать разрядные, шестнадцатиразрядные и так далее. Кроме того, поскольку в современных компьютерах этот вход и выход доступны для программ (при помощи так называемого флага переноса), то пользуясь ими, можно программно реализовать длинную арифметику, то есть запрограммировать функции, которые на компьютере с 64-битной арифметикой смогут выполнять операции над целыми числами произвольной длины.

    Оптимизация сумматора с целью ускорения переноса

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

    64-битный сумматор реализуется как два 32-битных - один для младшей 32-битной секции числа, а другой - для старшей. Младшая секция, представляющая собой обычный 32-битный сумматор, складывает биты a_0, a_1, \dots, a_{31}+b_0, b_1, \dots, b_{31} и выдаёт биты суммы s_0, s_1, \dots, s_{31}, а также бит переноса c_{31 \to 32}. Старшая секция складывает с учётом переноса c_{31 \to 32} старшие биты a_{32},a_{33},\dots, a_{63}+b_{32}, b_{33}, \dots, b_{63}. Но чтобы не ждать переноса из младшей секции, старшая организована следующим образом: она состоит из двух 32-битных сумматоров, получающих на вход одни и те же слагаемые a_{32},a_{33},\dots, a_{63} и b_{32, b_{33},\dots,b_{63}, и при этом один из сумматоров всегда получает бит переноса c_{31 \to 32}=0, а другой - c_{31 \to 32}=1. Сумматоры старшей секции "запускаются" одновременно друг с другом и с сумматором младшей, и одновременно с ней заканчивают работу. К моменту окончания работы этих трёх 32-битных сумматоров (одного "младшего" и двух "старших") становится известно действительное значение переноса c_{31 \to 32}, и в итоговую сумму попадают результирующие биты лишь одного из "старших" сумматоров - того, который работал в условиях верного предположения значения входящего переноса c_{31 \to 32}.

    Описанный подход можно описать словами: "Сделай всё, что можешь, как можно скорее, часть из этого пригодится, остальное выбросим". Такая стратегия вычислений называется спекулятивной. Спекулятивность усложняет сумматор в нашем примере: она приводит к тому, что, фактически, результаты 1/3 вычислений (одного из трёх 32-разрядный сумматоров) выполняются впустую. Тем не менее она популярна, так как позволяет ускорить работу сумматора почти вдвое. Иногда сумматоры делят и на бо?льшее число секций.

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

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

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

  • как и у обычного сумматора, у АЛУ имеется два входа для первого и второго аргументов бинарных операций (например, сложения или умножения); для унарных операций (изменение знака, логическое отрицание) используется один из них;
  • как и у обычного сумматора, у АЛУ имеется выход для результата операции;
  • как и у обычного сумматора, у АЛУ имеется вход и выход переноса;
  • АЛУ также имеет управляющий вход, задающий, какую именно следующую операцию следует выполнить , то есть какой из инструментов швейцарского ножа нужно сейчас использовать.
  • В зависимости от значения на управляющем входе (4) ко входам и выходам (1-3) подключается та или иная логическая схема, входящая в состав АЛУ:

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

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

    Побитовые логические операции - это операции, которые выполняются побитово, например, побитовое отрицание двоичного числа выполняет отрицание каждого его бита, побитовая операция "и" двух чисел выполняет "и" для каждой пары соответствующих битов и т.д. Таким образом, для побитовое отрицание, получая на вход 32-битовое двоичное число a_0, a_1, \dots, a_{31}, выдает следующий результат: \neg a_0, \neg a_1, \dots, \neg a_{31}. Побитовое "и" (операция & в языке С), получая на вход два 32-битовых числа получая на вход 32-битовое двоичное число a_0, a_1, \dots, a_{31} и b_0, b_1, \dots, b_{31}, выдаёт число a_0 \wedge b_0, a_1 \wedge b_1, \dots, a_{31} \wedge b_{31}. Аналогично действуют и другие побитовые операции - "или", "исключающее или" и т.д. Поскольку, в отличие от сумматора, все биты обрабатываются независимо, проблем с задержкой переноса не возникает, и побитовые операции всегда выполняются за один такт.

    Сдвиг двоичного числа - это операция, смещающая разряды (биты) числа от младшего к старшему, дописывая справа нуль и теряя старший бит (левый сдвиг, обозначается "<<" в языке C) или от старшего к младшему, дописывая слева ноль и теряя младший бит (правый сдвиг, ">>" в языке C). Для того, чтобы сдвинуть аргумент a на 1 бит влево АЛУ присоединяет выходные биты к соответствующим входным. Сдвиг числа влево на 1 бит эквивалентен умножению на 2, но выполняется намного быстрее. Аналогично работает сдвиг вправо, и он эквивалентен делению на 2 нацело. Поскольку при сдвигах АЛУ всего лишь соединяет выходы с соответствующими входами, сдвиги, так же, как и побитовые операции, выполняются за один такт. Отметим, что современные AЛУ за один такт умеют сдвигать числа и на произвольное количество битов, а также выполнять некоторые другие разновидности сдвигающих биты операций.

    Умножение выполняется мультипликатором. Если мы вспомним алгоритм умножения "в столбик", то увидим, что он состоит из сдвигов, сложений и умножений на одноразрядное число. В случае двоичной системы умножение на одноразрядное число реализуется тривиально: поскольку одноразрядное число может быть либо 0, либо 1, то и произведение будет равно или другому множителю, или нулю. Таким образом, мультипликатор также можно изготовить в виде логической схемы. Но она получится весьма громоздкой: в ней будет уже очень много вентилей и связей между ними. Поэтому в некоторых АЛУ операция умножения выполняется не единой логической схемой, а как последовательность микроопераций (про микрооперации мы расскажем в следующих разделах) с запоминанием промежуточных результатов в специальных внутренних регистрах, используемых только в АЛУ. Чтобы лучше представить себе работу такого АЛУ, попробуйте написать программу на любом языке программирования, которая умножает два числа, пользуясь для этого лишь операциями сдвига и сложения. По аналогии с умножением, деление также можно реализовать при помощи логической схемы, но она получится ещё сложнее, поэтому деление также часто реализуется в виде последовательности микроопераций.

    Отметим, что программная реализация умножения, которую мы предлагаем выполнить читателям - отнюдь не просто "учебное" упражнение. АЛУ некоторых простых процессоров, например, Intel 8080, позволяло выполнять лишь сложение, вычитание, сдвиг и побитовые операции, а умножение для этих процессоров действительно приходилось реализовывать уже программистам.

    Вопросы

  • Что такое арифметико-логическое устройство?
  • Почему велика его роль в устройстве процессора?
  • Что такое одноразрядный сумматор?
  • Постройте таблицу истинности одноразрядного сумматора.
  • Постройте логическую схему одноразрядного сумматора.
  • Проверьте правильность работы одноразрядного сумматора при различных входных значениях a,b и c.
  • Постройте на основе нескольких 1-разрядных сумматоров один 4-разрядный сумматор.
  • Объясните, что такое многоразрядный сумматор.
  • Для чего используются сумматоры в ЭВМ?
  • Назовите узкое место многоразрядных сумматоров.
  • Опишите способ оптимизации переноса в многоразрядном сумматоре.
  • Что такое спекулятивные вычисления?
  • Что такое АЛУ и какие операции оно может выполнять?
  • Перечислите входы АЛУ.
  • Перечислите выходы АЛУ.
  • Что такое побитовые логические операции?
  • Расскажите про реализацию побитовых логических операций.
  • Что такое побитовый сдвиг?
  • Расскажите про реализацию побитового сдвига.
  • Расскажите про реализацию в АЛУ умножения.
  • Литература

  • Орлов С.А., Цилькер Б.Я. Организация ЭВМ и систем: Учебник для вузов. 2-е изд. СПб.: Питер, 2011. 688 с.
  • Харрис Д.М., Харрис С.Л. Цифровая схемотехника и архитектура компьютера. [пер. с англ.] Imagination Technologies. М.: ДМК Пресс, 2018. 792 с.
  • Таненбаум Э., Остин Т. Архитектура компьютера. 6-е изд. СПб.: Питер, 2013. 816 с.
  • Страницы:

    Одноразрядный двоичный сумматор; четырехразрядный двоичный сумматор; оптимизация сумматора с целью ускорения переноса для арифметики большой разрядности; арифметико-логическое устройство (блок) процессора.

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

    Одноразрядный двоичный сумматор

    Сначала рассмотрим одноразрядный сумматор, который позволяет складывать два бита. Для этого сначала вспомним алгоритм сложения "в столбик", универсальный для систем исчисления с любым основанием. Этот алгоритм предписывает складывать числа, начиная с младших разрядов, причём на входе каждого разряда, помимо слагаемых, есть ещё и перенос из предыдущего, равный 0 или 1, а на выходе, помимо суммы, также равный 0 или 1 перенос в следующий разряд.

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

  • s содержит результат суммы двух слагаемых a и b и переноса из предыдущего разряда c по модулю 2:s=a \oplus b \oplus c;
  • c ' содержит значение переноса; перенос возникает при сложении двух одноразрядных двоичных чисел, когда их сумма плюс значение переноса из предыдущего разряда превышает 1: c ' =(a \wedge b) \vee (b \wedge c) \vee (c \wedge a).
  • Итак, мы имеем функцию f(a,b,c)=(a, c '). Таблица истинности для этой функции представлен в таблице 7.1. Очевидно, что так заданный одноразрядный сумматор является одним шагом для сложения многоразрядных двоичных чисел.

    Таблица истинности для одноразрядного сумматора
    a b c s c '
    0 0 0 0 0
    0 0 1 1 0
    0 1 0 1 0
    0 1 1 0 1
    1 0 0 1 0
    1 0 1 0 1
    1 1 0 0 1
    1 1 1 1 1

    Реализация одноразрядного сумматора с помощью вентилей, то есть логическая схема сумматора, представлена на рис. 1.5. Убедимся, что эта схема действительно делает то, что нужно, то есть соответствует таблице 7.1.

  • Разряд суммы s. Входы a и b схемы поступают на вход вентиля (1) "исключающее или", а его выход и вход c, в свою очередь, на вход вентиля (2) "исключающее или". Выход же вентиля (2) является одновременно и выходом схемы c. Таким образом, получаем, что s=(a \oplus b0 \oplus c = a \oplus b \oplus c, то есть на выходе s мы действительно имеем разряд суммы.
  • Перенос в следующий разряд c ' =(a \wedge b) \vee 9c \wedge (a \oplus b)). Эта формула отличается от ранее предложенной для c ', но легко убедиться, что она даёт тот же результат, причём с использованием меньшего количества вентилей. Действительно, c \wedge (a \oplus b)=c \wedge (a \vee b) \wedge \neg (a \wedge b)= \neg (a \wedge b)\wedge ((b \wedge c) \vee (c \wedge a)), следовательно, (a \wedge b) \vee (c \wedge (a \oplus b))=(a \wedge b) \vee (\neg (a \wedge b) \wedge ((b \wedge c) \vee (c \wedge a)))=(a \wedge b) \vee (b \wedge c) \vee (c \wedge a), то есть мы получаем именно то, что нам и требовалось.
  • ЧЕТЫРЕХРАЗРЯДНЫЙ ДВОИЧНЫЙ СУММАТОР

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

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

    4-разрядный сумматор, складывающий числа, состоящие из цифр a_0a_1a_2a_3 и b_0b_1b_2b_3 соответственно (младшие разряды мы записали слева), можно представить, как функцию следующего вида:

    f(a_0,a_1,a_2,a_3,b_0,b_1,b_2,b_3,c_{\to0})=(s_0,s_1,s_2,s_3,c_{3\to})

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

    Внимательные читатели могли заметить вход c_{\to0}, на который подаётся 0, и выход c_{3\to}. Они оставлены на схеме не только для поддержания надлежащей степени общности. При помощи них можно объединять четырёхразрядные сумматоры в более "длинные", подсоединяя выход переноса предыдущего ко входу переноса следующего так же, как мы соединяли одноразрядные сумматоры, получая восьмиразрядные, двенадцать разрядные, шестнадцатиразрядные и так далее. Кроме того, поскольку в современных компьютерах этот вход и выход доступны для программ (при помощи так называемого флага переноса), то пользуясь ими, можно программно реализовать длинную арифметику, то есть запрограммировать функции, которые на компьютере с 64-битной арифметикой смогут выполнять операции над целыми числами произвольной длины.

    Оптимизация сумматора с целью ускорения переноса

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

    64-битный сумматор реализуется как два 32-битных - один для младшей 32-битной секции числа, а другой - для старшей. Младшая секция, представляющая собой обычный 32-битный сумматор, складывает биты a_0, a_1, \dots, a_{31}+b_0, b_1, \dots, b_{31} и выдаёт биты суммы s_0, s_1, \dots, s_{31}, а также бит переноса c_{31 \to 32}. Старшая секция складывает с учётом переноса c_{31 \to 32} старшие биты a_{32},a_{33},\dots, a_{63}+b_{32}, b_{33}, \dots, b_{63}. Но чтобы не ждать переноса из младшей секции, старшая организована следующим образом: она состоит из двух 32-битных сумматоров, получающих на вход одни и те же слагаемые a_{32},a_{33},\dots, a_{63} и b_{32, b_{33},\dots,b_{63}, и при этом один из сумматоров всегда получает бит переноса c_{31 \to 32}=0, а другой - c_{31 \to 32}=1. Сумматоры старшей секции "запускаются" одновременно друг с другом и с сумматором младшей, и одновременно с ней заканчивают работу. К моменту окончания работы этих трёх 32-битных сумматоров (одного "младшего" и двух "старших") становится известно действительное значение переноса c_{31 \to 32}, и в итоговую сумму попадают результирующие биты лишь одного из "старших" сумматоров - того, который работал в условиях верного предположения значения входящего переноса c_{31 \to 32}.

    Описанный подход можно описать словами: "Сделай всё, что можешь, как можно скорее, часть из этого пригодится, остальное выбросим". Такая стратегия вычислений называется спекулятивной. Спекулятивность усложняет сумматор в нашем примере: она приводит к тому, что, фактически, результаты 1/3 вычислений (одного из трёх 32-разрядный сумматоров) выполняются впустую. Тем не менее она популярна, так как позволяет ускорить работу сумматора почти вдвое. Иногда сумматоры делят и на бо?льшее число секций.

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

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

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

  • как и у обычного сумматора, у АЛУ имеется два входа для первого и второго аргументов бинарных операций (например, сложения или умножения); для унарных операций (изменение знака, логическое отрицание) используется один из них;
  • как и у обычного сумматора, у АЛУ имеется выход для результата операции;
  • как и у обычного сумматора, у АЛУ имеется вход и выход переноса;
  • АЛУ также имеет управляющий вход, задающий, какую именно следующую операцию следует выполнить , то есть какой из инструментов швейцарского ножа нужно сейчас использовать.
  • В зависимости от значения на управляющем входе (4) ко входам и выходам (1-3) подключается та или иная логическая схема, входящая в состав АЛУ:

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

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

    Побитовые логические операции - это операции, которые выполняются побитово, например, побитовое отрицание двоичного числа выполняет отрицание каждого его бита, побитовая операция "и" двух чисел выполняет "и" для каждой пары соответствующих битов и т.д. Таким образом, для побитовое отрицание, получая на вход 32-битовое двоичное число a_0, a_1, \dots, a_{31}, выдает следующий результат: \neg a_0, \neg a_1, \dots, \neg a_{31}. Побитовое "и" (операция & в языке С), получая на вход два 32-битовых числа получая на вход 32-битовое двоичное число a_0, a_1, \dots, a_{31} и b_0, b_1, \dots, b_{31}, выдаёт число a_0 \wedge b_0, a_1 \wedge b_1, \dots, a_{31} \wedge b_{31}. Аналогично действуют и другие побитовые операции - "или", "исключающее или" и т.д. Поскольку, в отличие от сумматора, все биты обрабатываются независимо, проблем с задержкой переноса не возникает, и побитовые операции всегда выполняются за один такт.

    Сдвиг двоичного числа - это операция, смещающая разряды (биты) числа от младшего к старшему, дописывая справа нуль и теряя старший бит (левый сдвиг, обозначается "<<" в языке C) или от старшего к младшему, дописывая слева ноль и теряя младший бит (правый сдвиг, ">>" в языке C). Для того, чтобы сдвинуть аргумент a на 1 бит влево АЛУ присоединяет выходные биты к соответствующим входным. Сдвиг числа влево на 1 бит эквивалентен умножению на 2, но выполняется намного быстрее. Аналогично работает сдвиг вправо, и он эквивалентен делению на 2 нацело. Поскольку при сдвигах АЛУ всего лишь соединяет выходы с соответствующими входами, сдвиги, так же, как и побитовые операции, выполняются за один такт. Отметим, что современные AЛУ за один такт умеют сдвигать числа и на произвольное количество битов, а также выполнять некоторые другие разновидности сдвигающих биты операций.

    Умножение выполняется мультипликатором. Если мы вспомним алгоритм умножения "в столбик", то увидим, что он состоит из сдвигов, сложений и умножений на одноразрядное число. В случае двоичной системы умножение на одноразрядное число реализуется тривиально: поскольку одноразрядное число может быть либо 0, либо 1, то и произведение будет равно или другому множителю, или нулю. Таким образом, мультипликатор также можно изготовить в виде логической схемы. Но она получится весьма громоздкой: в ней будет уже очень много вентилей и связей между ними. Поэтому в некоторых АЛУ операция умножения выполняется не единой логической схемой, а как последовательность микроопераций (про микрооперации мы расскажем в следующих разделах) с запоминанием промежуточных результатов в специальных внутренних регистрах, используемых только в АЛУ. Чтобы лучше представить себе работу такого АЛУ, попробуйте написать программу на любом языке программирования, которая умножает два числа, пользуясь для этого лишь операциями сдвига и сложения. По аналогии с умножением, деление также можно реализовать при помощи логической схемы, но она получится ещё сложнее, поэтому деление также часто реализуется в виде последовательности микроопераций.

    Отметим, что программная реализация умножения, которую мы предлагаем выполнить читателям - отнюдь не просто "учебное" упражнение. АЛУ некоторых простых процессоров, например, Intel 8080, позволяло выполнять лишь сложение, вычитание, сдвиг и побитовые операции, а умножение для этих процессоров действительно приходилось реализовывать уже программистам.

    Вопросы

  • Что такое арифметико-логическое устройство?
  • Почему велика его роль в устройстве процессора?
  • Что такое одноразрядный сумматор?
  • Постройте таблицу истинности одноразрядного сумматора.
  • Постройте логическую схему одноразрядного сумматора.
  • Проверьте правильность работы одноразрядного сумматора при различных входных значениях a,b и c.
  • Постройте на основе нескольких 1-разрядных сумматоров один 4-разрядный сумматор.
  • Объясните, что такое многоразрядный сумматор.
  • Для чего используются сумматоры в ЭВМ?
  • Назовите узкое место многоразрядных сумматоров.
  • Опишите способ оптимизации переноса в многоразрядном сумматоре.
  • Что такое спекулятивные вычисления?
  • Что такое АЛУ и какие операции оно может выполнять?
  • Перечислите входы АЛУ.
  • Перечислите выходы АЛУ.
  • Что такое побитовые логические операции?
  • Расскажите про реализацию побитовых логических операций.
  • Что такое побитовый сдвиг?
  • Расскажите про реализацию побитового сдвига.
  • Расскажите про реализацию в АЛУ умножения.
  • Литература

  • Орлов С.А., Цилькер Б.Я. Организация ЭВМ и систем: Учебник для вузов. 2-е изд. СПб.: Питер, 2011. 688 с.
  • Харрис Д.М., Харрис С.Л. Цифровая схемотехника и архитектура компьютера. [пер. с англ.] Imagination Technologies. М.: ДМК Пресс, 2018. 792 с.
  • Таненбаум Э., Остин Т. Архитектура компьютера. 6-е изд. СПб.: Питер, 2013. 816 с.
  • Вернуться к учебному плану