Я попытаюсь дать вам представление о том, как цифровые схемы предназначены для решения задач цифровой обработки, используя проблемы, которые вы ставите: как процессоры реализуют сложения и умножения.
Во-первых, давайте уберем прямой вопрос: как язык программирования эффективно оценивает умножения и сложения. Ответ прост, они собирают их в умножение и добавляют инструкции. Например, следующий код:
a = 1 + 1;
b = a * 20;
просто компилируется в нечто вроде:
ADD 1 1 a
MUL a 20 b
(обратите внимание, что вышеприведенная сборка предназначена для воображаемого процессора, который не существует, для простоты).
В этот момент вы понимаете, что приведенный выше ответ просто сдвигает проблему и решает ее с помощью аппаратной магии. Следующий вопрос, очевидно, состоит в том, как работает эта аппаратная магия?
Давайте сначала посмотрим на более простую проблему: сложение.
Сначала мы делаем знакомую задачу, добавляя в обычную базу 10 чисел:
17
+28
Первым шагом было бы добавить 7 и 8. Но это приводит к 15, что больше, чем одна цифра. Итак, мы несем 1:
(1)
17
+28
= 5
Теперь мы добавляем 1, 1 и 2 вместе:
17
+28
=45
Итак, из этого мы получаем следующие правила:
когда результат сложения больше, чем одна цифра, мы сохраняем младшую значащую цифру и переносим самую значимую цифру вперед
если в нашу колонку перенесена цифра, мы добавим ее вместе с числами, которые добавляем
Теперь пришло время интерпретировать приведенные выше правила в базе 2 - булевой алгебре.
Таким образом, в булевой алгебре сложение 0 и 1 вместе = 1. Добавление 0 и 0 = 0. И добавление 1 и 1 = 10, что является более чем одной цифрой, поэтому мы переносим 1 вперед.
Из этого мы можем построить таблицу истинности:
a b | sum carry
-------------------
0 0 | 0 0
0 1 | 1 0
1 0 | 1 0
1 1 | 0 1
Исходя из этого, мы можем построить две схемы / логические уравнения - одну для вывода суммы и одну для вывода переноса. Самый наивный способ - просто перечислить все входные данные. Любая таблица истинности, независимо от того, насколько большой и сложный может быть пересчитана в этой форме:
(AND inputs in first row) OR (AND of inputs in second row) OR ...
Это в основном сумма продуктов формы. Мы только смотрим на результаты, которые приводят к 1 и игнорируют 0:
sum = (NOT a AND b) OR (a AND NOT b)
Давайте заменим символы И ИЛИ и НЕ символами языка программирования, чтобы их было легче читать:
sum = (!a & b) | (a & !b)
По сути, мы преобразовали таблицу следующим образом:
a b | sum equation
-------------------
0 0 | 0
0 1 | 1 (!a & b)
1 0 | 1 (a & !b)
1 1 | 0
Это может быть непосредственно реализовано в виде схемы:
_____
a ------------| |
\ | AND |-. ____
\ ,-NOT--|_____| \ | |
\/ `--| OR |----- sum
/\ _____ ,--|____|
/ `-NOT--| | /
/ | AND |-`
b ------------|_____|
Наблюдающие читатели в этот момент заметят, что вышеприведенная логика может фактически быть реализована в виде одного шлюза - шлюза XOR, который удобно имеет поведение, требуемое нашей таблицей истинности:
_____
a ------------| |
| XOR |---- sum
b ------------|_____|
Но если ваше аппаратное обеспечение не предоставляет вам шлюз XOR, вышеприведенные шаги помогут вам определить и реализовать его в терминах И, ИЛИ и НЕ.
Способ преобразования логических элементов в реальное оборудование зависит от того, какое у вас оборудование. Они могут быть реализованы с использованием различных физических механизмов, если этот механизм обеспечивает своего рода режим переключения. Логические ворота были реализованы со всем: от струй воды или струй воздуха (жидкости) до транзисторов (электроника) и падающих шариков. Это большая тема сама по себе, поэтому я собираюсь просто замять ее и сказать, что логические элементы можно реализовать как физические устройства.
Теперь мы делаем то же самое для сигнала переноса. Поскольку существует только одно условие, когда сигнал переноса истинен, уравнение просто:
carry = a & b
Так что нести несложно:
_____
a ------------| |
| AND |---- carry
b ------------|_____|
Объединяя их вместе, мы получим так называемую половину сумматора:
_____
a ------;-----| |
| | XOR |---- sum
b --;---|-----|_____|
| | _____
| '-----| |
| | AND |---- carry
'---------|_____|
Уравнения для приведенной выше схемы, кстати, выглядит так:
sum = a ^ b
carry = a & b
Половина сумматора чего-то не хватает. Мы внедрили первое правило - если результат больше чем одна цифра, чем перенос, но мы не внедрили второе правило - если есть перенос, добавьте его вместе с числами.
Таким образом, чтобы реализовать полный сумматор, схему сложения, которая может добавлять числа, состоящие более чем из одной цифры, нам нужно определить таблицу истинности:
a b c | sum carry
---------------------
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
Уравнение для суммы теперь:
sum = (!a & !b & c) | (!a & b & !c) | (a & !b & !c) | (a & b & c)
Мы можем пройти тот же процесс, чтобы вычленить и упростить уравнение и интерпретировать его как схему и т. Д., Как мы делали выше, но я думаю, что этот ответ становится слишком длинным.
К настоящему времени вы должны понять, как устроена цифровая логика. Есть и другие приемы, которые я не упомянул, такие как карты Карно (используемые для упрощения таблиц истинности) и логические компиляторы, такие как эспрессо (чтобы вам не приходилось разлагать булевы уравнения вручную), но основное - это то, что я обрисовано в общих чертах выше:
Разложите проблему, пока вы не сможете работать на уровне одного бита (цифры).
Определите выходы, которые вы хотите, используя таблицу истинности.
Преобразуйте таблицу в логическое уравнение и упростите уравнение.
Интерпретировать уравнение как логические элементы.
Преобразуйте свою логическую схему в реальные аппаратные схемы, реализовав логические элементы.
Вот как на самом деле решаются фундаментальные (или, скорее, низкоуровневые) проблемы - множество таблиц истинности. Настоящая творческая работа состоит в том, чтобы разбить сложную задачу, такую как декодирование MP3 на битовый уровень, чтобы вы могли работать с ней с таблицами истинности.
Извините, у меня нет времени объяснять, как реализовать умножение. Вы можете попытаться разобраться в этом, выяснив правила того, как долго работает умножение, затем интерпретировать его в двоичном формате, а затем попытаться разбить его на таблицы истинности. Или вы можете прочитать Википедию: http://en.wikipedia.org/wiki/Binary_multiplier