Здравствуйте, мои дорогие подписчики и читатели моего непопулярного блога! Решил вас "подогреть" ещё одной темой. Кому-то она покажется скучной, непонятной, кому-то давно "перетёртой" и давно "разжёванной". Но кому-то, надеюсь, покажется интересной и полезной. Кого-то заинтересует пошевелить извилинами, вспомнить математику. Кого-то подвигнет к повторению или созданию какого-то своего творения цифровой техники.
В наш век цифры каждый "мужчин" либо "женщин" обязан собрать свой калькулятор! :) Или , минимум, понимать, как оно всё работает. Итак, я решил собрать калькулятор и поведать об этом миру!
Три кита цифровой логики.
Вся цифровая техника, построенная на бинарной логике (будь то процессор, микроконтроллеры, статическая память и т.д.) базируется на трёх ключевых элементах: ИЛИ, НЕ, И. Дизъюнкция, инверсия, конъюнкция. На них строятся другие элементы, как то: элемент Исключающее ИЛИ , различные триггеры , сумматоры и т.п. Исключение лишь ячейка памяти DDR, в которой нет логических элементов - значение хранится зарядом конденсатора на одном транзисторе. Необходимый контроллер, для такого вида памяти, регулярно перезаписывает значение.
Стандартные схематические обозначения, отечественные и зарубежные, ключевых и вторичных элементов логики:
Элементы И-НЕ, ИЛИ-НЕ можно реализовать как отдельные элементы с добавлением на выход инвертора НЕ. Но это в физической реальности отнимет больше транзисторов для реализации. Поэтому элементы с включённым в себя отрицанием тоже представляются ключевыми. Буфер из себя не представляет какой-либо логики. Что на входе, то и на выходе. Но иногда применяется в реальных схемах, где нужно согласовывать уровни сигнала. Элемент Исключающее ИЛИ, XOR, - уже составной элемент. Таблицы истинности каждого элемента я тут публиковать не буду. При желании можно всё без труда найти по запросу в поисковике или составить самому.
Что такое сумматор и как он работает?
В основе любого ядра процессора лежит АЛУ - арифметико-логическое устройство. Сумматор - ключевой элемент АЛУ. На нём реализуют не только сложение, но и вычитание, деление, умножение, возведение в степень и т.д. Практически все математические операции производятся на сумматоре! Сумматор складывает в столбик, если кто не знал. :)
Ниже представлены схемы полусумматора, полного сумматора и его элементов. Можно воспользовавшись таблицами истинности всё посчитать и понять логику работы устройства в целом! Она целиком повторяет школьное сложение в столбик с переносом.
С чего всё началось...
Попался мне на глаза ролик одного блогера , где он на макетной плате собирает 8-мибитный сумматор на биполярных транзисторах. Всё толково, всё логично и всё работает.
Однако у меня "подгорело" от реализации его схемы. Куча лишних элементов, инверторов, транзисторов. На один бит израсходовано 25 транзисторов. Вот ЕГО схема реализации ключевого элемента сумматора:
Реализация двойного инвертирования и плюс ещё добавление ненужного элемента на бит переноса. Вход на элемент ИЛИ-НЕ затем инвертируется НЕ. Ниже элемент И-НЕ без инвертирования. Объединяет выходы этих сигналов опять И-НЕ, после которого вновь стоит инверсия НЕ. Ещё ниже вообще целиком лишний элемент для вывода бита переноса.
На входе: А = 0101 , B=0011. На выходе: Sym=0110, Carry=0001
Блок-схема полного сумматора:
Два полусумматора с входами чисел А, B и входом бита переноса предыдущего сумматора. Выходы - сумма и бит переноса на следующий сумматор.
Выходы бита переноса двух полусумматоров приходят на элемент ИЛИ, и уже с него снимается один сигнал бита переноса. По его стилистике написания схем элемент ИЛИ у него тоже построен на 3-х транзисторах. По моей схеме, см. рисунок ниже, элемент ИЛИ изображён верхним левым элементом на двух транзисторах.
Не долго думая, я прямо по скриншоту в гимпе перерисовал его схему. У меня получилось вот что:
Элемент ИЛИ-НЕ с последующей инверсией заменён на ИЛИ. Выходной элемент на И. Нижний дубль элемента И-НЕ убран, к верхнему просто добавлен инвертор НЕ, с которого снимается бит переноса. Таблицы истинности и оригинальной, и переработанной схемы идентичны!
Не сложно посчитать, что при такой реализации на 1 бит требуется уже не 25, а 16 транзисторов!
Решил я дальше дополнить его схему, научить сумматор не только складывать, но и вычитать. Велосипед изобретать тут заново не надо, в памяти всплыл фрагмент реализации добавлением элемента Исключающее ИЛИ в схему полного сумматора. Порывшись в интернете, нашёл блок-схему этой реализации:
Элемент Исключающее ИЛИ - это схема полусумматора, см. предыдущее изображение, только без отвода бита переноса.
Плюс ещё 6 транзисторов. Итого: 22 транзистора на 1 бит. Что всё равно меньше, чем на изначальной схеме блогера.
Представление числа.
Добавление функции вычитания в сумматор заставляет затронуть тему представления числа в двоичной логике. А именно: как представлены отрицательные числа в двоичной логике и как работает Исключающее ИЛИ в этой схеме.
Вычитание в сложении можно представить легко. Нужно к положительному числу прибавить отрицательное: 5-3 = 5+(-3) = 2. Стало быть, нужно одно число сделать отрицательным. В языке Си есть понятия чисел со знаком и без знака.
- INT(от integer) - целое число со знаком.
- UINT(unsigned integer) - целое число без знака.
Современные "калькуляторы" работают с байтом минимум. Один байт равен 8-ми битам. В один байт можно поместить 254 положительных числа UINT и ноль, а вот INT'ов положительных вместится только 127. Точнее от 0 до 127. Остальной диапазон значений отведён под отрицательные числа. От -1 до -128. Старший бит, или старшие биты, отрицательного числа всегда единицы. Из 8 бит один бит минимум отводится для представления знака числа. Если старший бит, биты, нули, то число положительное, если единицы - отрицательное.
Для представления отрицательного числа используется так называемый "обратный код", что, по сути, является инверсией всего числа, и "добавочный код" - прибавление к получившемуся числу единицы.
Наглядный пример. Как из положительного числа 7 получить отрицательное:
Число 7 в двоичном представлении 1 байта, это 0000 0111. Инвертируем это число, применим "обратный код":
Получили число -8. Вместо нулей стоят единицы и наоборот, где были единицы стоят нули - 1111 1000. Теперь прибавим к -8 единицу. Применим "добавочный код":
После применения "обратного кода", инверсии, и "добавочного кода", прибавления единицы, получилось число -7 = 1111 1001.
Разбирая работу схемы 4-х битного сумматора с Исключающим ИЛИ можно сделать вывод, что если на линию SUB подать логическую единицу, то число B будет инвертировано перед входом на сумматор. А также подключение крайнего входа бита переноса к этой линии даёт прибавление единицы. Т.е. схема реализует сразу и "обратный код", и "добавочный код". При подаче на линию SUB нуля происходит обычное сложение A+B. При подаче единицы получается A-B. А, точнее A+(-B). Что и требовалось получить.
Переход к реализации.
Порывшись у себя в закромах, обнаружил, что у меня есть только 3 биполярных транзистора в корпусе TO-92. В голове уже назрела идея применительно именно к этому корпусу. Можно купить штук 100. Но зачем, подумал я, вспомнив, что у меня в закромах лежит ещё куча плат от старых телевизоров да ещё 4 штуки на помойку стоят, за ненадобностью? Вооружившись феном , пинцетом и тисками, начал потрошить свои закрома :) Сдул 91 штуку, плюс 3 что были. 25 PNP и 69 NPN только. Но это не беда, решил я, на 4 бита хватает с запасом. По расчёту надо 88 штук транзисторов. До кучи насдувал ещё сопротивлений, которых больше, чем транзисторов на 1/3 надо. Переключателей у меня нет, и в телевизорах тоже. Зато на одной плате мне попалась на глаза микросхемка сдвигового регистра 8-мибитного в DIP-14 корпусе. Отлично! Три кнопки на ввод значений, и никаких переключателей не надо. Ещё одна кнопка на переключение режимов "сложение-вычитание". Ещё нашёл обрезки светодиодных лент от ламп, тоже пригодятся, насдувал светодиодов с них. В сарае остались обрезки кленовых щитов от всяких поделок деревянных. Подобрал себе дощечку кленовую под breadboard. Дословно - хлебная доска. Эти обрезки вполне от реальных хлебных досок могли быть - ирония судьбы или всё по феншую у меня? :) Материалы с чем предстоит работать:
Нарисовал я набросок своей идеи, которую предстоит "выпилить". Четыре кнопочки, индикаторы операций сложения, вычитания. Индикаторы слагаемых чисел A и B. Индикатор результата с отдельным , пятым битом переноса.
Распилил я досочку:
В ArtCAM'е создал несколько проектов для ЧПУ и отнёс на обработку в сарай:
Получилось замечательно!
Вырезал цилиндры под световоды из оргстекла , вклеил на них светодиоды. Усадил на темоклей первые три ряда транзисторов. Начал распаивать используя медный провод от витой пары:
Распаял эти три ряда, проверил: вроде, всё работает. Залил сверху термоклеем, для пущей надёжности. На следующий день начал распаивать ещё ряд и внезапно понял, что я допустил несколько ошибок!
- По невнимательности, первую проверку проводил на не готовых полусумматорах. Это первая моя ошибка. По три элемента, на фото, это два элемента от полусумматора и один элемент ИЛИ. Как я проверял вечером, сам не понял. Но наутро выяснилось, что работает всё не так, как надо.
- Вторая ошибка - это то, что я ещё всё залил термоклеем сверху. "Смывать" эти сопли - занятие ещё то :)
- Третья ошибка, которую я выяснил уже в процессе попыток исправления, вообще "детская". Вспомнил, что PNP совсем не то, что NPN. :) Просто поменял местами коллекторы с эмиттерами, и всё. Даже не задумался о том, что PNP это инверсия NPN.
- Четвёртая ошибка, что не нарисовал подробную схему, делать решил всё налету или из головы. А это, как оказалось, не совсем удобно, особенно когда несколько часов голову ломаешь-думаешь, откуда-куда - что ты вчера разводил.
Косяки были во всём. Захотелось плюнуть на всё, выкинуть всё на помойку. Или начать заново делать, так как термоклей... отломанные ножки транзисторов... отбивали дальнейшую охоту исправлять эти косяки. Но также получил приятный бонус к пониманию. Количество транзисторов можно смело уменьшить ещё на 8 штук. Убрав по одному ненужному элементу в схеме. Но об этом во второй части.
Продолжение следует....