Логические элементы и биты памяти в компьютере

Основы схемотехники

То, что компьютеры могут хранить информацию в памяти, мы давно принимаем за данность, но знаешь ли ты, как именно эта память работает? В этой статье мы поговорим о последовательностной логике, которая позволяет компьютерам хранить информацию. Какие возможности это открывает и реально ли узнать секретный ключ кодового замка, располагая только его схемой — самое время это выяснить!

В начале был Бит

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

Таблица истиности

Кто-то может сказать, что это совершенно бессмысленная схема, ведь сигнал на выходе всегда равен входу. Действительно, применяя логическое отрицание дважды, мы получаем исходное утверждение. Если ты не «белый» хакер, ты «черный». Не «не белый» — по-прежнему «белый». Это выглядит как бесполезная словесная эквилибристика, но все меняется, если в схеме выше попробовать вход замкнуть на выход.

Логические элементы и биты памяти в компьютере

Теперь, если в правой половине у нас высокий логический уровень, в левой половине всегда будет низкий (и наоборот). Иначе говоря, схема приобретает свойство бистабильности и принимает лишь одно из двух возможных состояний. Совсем как бит памяти — или переменная bool в С/С++.

Для наглядности можно собрать схему на макетной плате. Здесь подойдет любой интвертор — например, 74HC04B. Это шесть логических вентилей NOT в корпусе DIP-14 (целых три бита информации, Карл!). Впрочем, как ты уже понимаешь, одну и ту же функцию можно реализовать несколькими способами, поэтому здесь наш выбор практически неограничен.

Тут стоит упомянуть, что с теми же целями мы можем использовать и 74HC00N (четыре элемента NAND). Эта микросхема получила свой особый «нулевой» номер в серии 74хх не просто так — логическая операция ИЛИ-НЕ обладает замечательным свойством функциональной полноты. Иными словами, мы можем любой другой базовый блок (AND, OR и остальные) разложить на комбинацию блоков NAND. Аналог в отечественной микроэлектронике — 155ЛА3 и это настолько популярная микросхема у радиолюбителей, что в ее честь даже называют сайты.

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

Некоторая неопределенность

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

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

Простой RS-триггер

Внесем минимальные изменения в нашу схему и воспользуемся дополнительными входами NAND. Назовем их nR и nS (not RESETи not SET соответственно, их назначение прояснится в дальнейшем).

Логические элементы в компьютере rstrig

Оба входа могут принимать по два значения, итого предстоит разобрать четыре варианта. Начнем с базового случая nR = 1 и nS = 1. При этом на выходах Q и nQ уже есть какие-то значения. Обрати внимание, что если Q = 1, то при nS = 1 результатом операции NAND будет низкий уровень, то есть nQ = 0. И наоборот, если Q = 0, то nQ = 1 и оба выхода в нашей схеме действительно принимают противоположные значения. Другими словами, если один из входов вентиля NAND находится в состоянии логической единицы, то сигнал на выходе определяется как инверсия второго входа — в точности как с инверторами чуть ранее! Таким образом, при nR = 1 и nS = 1схема сохраняет свое старое состояние и выходы не обновляются.

Теперь рассмотрим вариант с nR = 1 и nS = 0. Так как на входе верхнего элемента NAND точно есть хотя бы один ноль, то его выход в любом случае будет равен логической единице. Значит, Q = 1 и, следовательно, nQ = 0. Аналогично, при nR = 0 и nS = 1 мы можем схожим образом вывести, что состояние схемы будет полностью противоположным (Q = 0 и nQ = 1).

Остается разобрать заключительный вариант, где оба входа равны нулю одновременно. На интуитивном уровне можно уже предполагать, что тут что-то не так. Действительно, при nR = nS = 0 результат элемента NAND не может быть положительным ни при каких возможных значениях дополнительного входа (рекомендую проверить по таблице истинности). Следовательно, Q = nQ = 0 и это единственный случай, когда наша схема «сбоит». В дальнейшим мы ее лучшим и обязательно избавимся от этого недостатка.

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

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

Практическое применение

Надеюсь, теперь принцип работы RS-триггера для тебя больше не секрет и тебе уже не терпится применить полученные знания на практике. Для этого понадобится микросхема IW4011, которая содержит четыре вентиля NAND (подойдет и любой зарубежный аналог).

Серия микросхем 4000 — это еще один прекрасный набор «строительных кирпичиков», которые раньше широко использовались при разработке устройств. В отличии от уже упоминавшегося семейства 7400, эти компоненты работают с расширенным диапазоном входных напряжений (до 15 Вольт). Следует помнить, что, хотя обе серии реализуют более-менее одинаковый набор логических схем, совместимость по выводам не гарантируется.

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

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

Но что, если нажатие на кнопку обрабатывается в прерывании? Или мы проектируем клавиатуру для геймеров и хотим получить минимальное время отклика? Да, «лишние» миллисекунды конечно не выведут тебя на первые строчки в ладдерах популярных игр, но некоторое преимущество точно обеспечат. Попробуем применить здесь RS-триггер и нарисуем такую схему.

Логические элементы в компьютере rstriguse

Мы используем два вентиля NAND, то есть только «половину» микросхемы CD4011 (К561ЛА7). Обрати внимание, это не стандартная тактовая кнопка: тут работает перекидной контакт без фиксации, так что в каждый момент времени коммутируются ровно два вывода. Приятная особенность таких кнопок в том, что при нажатии они издают слабый щелчок, похожий на звук переключателей в механической клавиатуре.

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

Продвинутый D-триггер

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

Как ты помнишь, ключевое неудобство в RS-триггере вызывал тот факт, что при nR = nS = 0 мы получали одинаковое состояние на прямом (Q) и, казалось бы, инверсном (nQ) выходе. Попробуем избавиться от этой проблемы. Для этого будем явно блокировать один из сигналов, если другой в этот момент активен.

Теперь состояние входа данных (D) через пару вентилей NAND подается на оба входа RS-триггера, а сигнал разрешения (E) контролирует момент времени, когда состояние правой половины схемы может меняться.

D-защелка — это почти как D-мейл, только защелка
D-защелка — это почти как D-мейл, только защелка

Можно пойти еще дальше и объединить две защелки в один триггер, который будет срабатывать только по переднему фронту тактового сигнала (переход с низкого уровня в высокий). Это наиболее универсальная схема, так как позволяет мгновенно зафиксировать состояние всех сигналов на входных линиях, а уже потом приступить к формированию результата с помощью комбинационной логики.

Практическое применение

В 4000 серии пару D-триггеров реализует микросхема CD4013 (отечественный аналог — К561ТМ2). Назначение ее выводов ты можешь увидеть на схеме ниже. Обрати внимание, что, помимо входов данных и тактового сигнала, тут выведены контакты для асинхронного сброса и установки внутреннего состояния триггера.

Асинхронность означает, что событие происходит мгновенно, не дожидаясь следующего тактового сигнала. И наоборот, обновления с линии данных происходят синхронно с изменениями на линии CLK.

Таким образом, комбинируя микросхемы CD4011 (561ЛА7) и CD4013 (561ТМ2) можно собрать схему с тактовой кнопкой и светодиодом, которая будет помнить свое состояние. Первое нажатие заставит светодиод гореть, второе нажатие его погасит. При этом нам даже не потребуется микроконтроллер и мы не напишем ни строчки кода!

Кодовый замок на регистрах

Теперь пришло время для более серьезных вещей. Я собрал на макетной плате кодовый замок на микросхемах 561 серии. Часть из них ты уже знаешь, другую часть мы разберем в процессе.

В первую очередь следует определиться с вводом. Здесь шесть кнопок для первых шести цифр 1 — 6 (больше не поместилось) и кнопка сброса. Сигнал с них подается на RS-триггеры, что помогает справиться с дребезгом контактов. Далее у нас есть четыре микросхемы К561ТМ2, это дает нам восемь бит информации о состоянии устройства.

Для удобства я сразу приведу принципиальную схему. Впрочем, ее всегда можно восстановить самостоятельно
Для удобства я сразу приведу принципиальную схему. Впрочем, ее всегда можно восстановить самостоятельно

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

Отдельного рассмотрения заслуживает пара D-триггеров U3A и U6A. У них общий тактовый сигнал, а вход данных второго зависит от выхода первого. Так как изначально все триггеры сброшены в ноль, то даже после однократного нажатия нужной кнопки выход второго не изменится и последний из триггеров будет все также заблокирован (иными словами, ноль из U3A перекочует в U6A, но глобально это ничего не меняет).

Однако, первый регистр из пары все-таки поменяет свое состояние, так как по приходу тактового сигнала на его входе данных содержится логическая единица от инверсного выхода второго. Значит, на его выходе уже будет высокий уровень и нам потребуется еще один тактовый сигнал (нажатие на кнопку), чтобы протолкнуть «единичку» во второй регистр. Таким образом, можно сделать вывод, что одну из кнопок требуется нажать два раза подряд, после чего разблокируется последний D-триггер.

Кстати, трехвходовые вентили NAND для разрешения подачи тактового сигнала на D-триггер содержатся в микросхемах К561ЛА9 (по три штучки на корпус).

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

Поэтому нам нужна возможность сброса состояния всех D-триггеров, как только превышено разрешенное количество попыток. Для этого требуется в первую очередь организовать подсчет, регистрируя нажатие любой цифры. Поэтому я взял парочку четырехвходовых вентилей NOR (К561ЛЕ6).

Логический ноль на их выходе образуется всякий раз, когда нажата какая-либо из подключенных кнопок. Объединим выходы вентилей с помощью операции И-НЕ. При этом сработает такое правило: инвертор на выходе логического элемента можно переместить на все его входы, но при этом поменяется и сам тип элемента (NOR переходит в NAND и наоборот). Таким образом, NAND на выходе можно рассматривать как NOR, а инверторы на его входах оказываются рядом с инверторами на выходах блоков NOR и взаимно аннигилируют. В результате мы получаем один большой элемент OR, что и требовалось для нашего счетчика.

Кстати, схема самого счетчика выглядит так.

Он построен на базе трех D-триггеров, так что у нас три бита и восемь возможных состояний. Инверсный выход первого блока подается на вход, так что по восходящему фронту тактового сигнала BIT0 внутреннего состояния переходит из ноля в единичку (и наоборот). При этом выход соединен с CLK следующего и каждое второе переключение приводит к изменением для BIT1.

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

Работу всей схемы можно посмотреть на видео. Успешный код активирует таймер на микросхеме КР1006ВИ1, которая демонстрирует анимацию на светодиодной шкале.

Звёзд: 1Звёзд: 2Звёзд: 3Звёзд: 4Звёзд: 5 (1 оценок, среднее: 5,00 из 5)
Загрузка...
Понравилась статья? Поделиться с друзьями:
Добавить комментарий