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

Мой вариант тримукса для поверхностного монтажа задумывался для относительно лёгкого воспроизведения «на коленке»: плата хоть и двухсторонняя, но содержит всего 12 переходных отверстий. К слову сказать, на форуме nedopc.org пробегал вариант для сквозного монтажа без единого переходного отверстия:

Впрочем, он по-прежнему требует сверлить отверстия для выводов микросхем, так что мой вариант экономичнее :)
trimuxIO
Моя цель — не теоретизирование, но постройка вполне осязаемой железки. На данный момент я обзавёлся некоторым количеством мультиплексоров, которые испытываю на макетках. В прошлый раз все входы испытываемых схем из себя представляли джамперы на макетках, а выходы набор светодидов на той же самой макетке. Это довольно неудобно (особенно перетыкать входы), поэтому я усмотрел у Александра примерно такой дизайн одного входа-выхода:

Каждый вход-выход несёт на себе один трёхпозиционный переключатель, который по умолчанию (среднее положение) слегка подтянут к 0V. Если пин используется для индикации выхода тримукса, то переключатель должен быть оставлен в среднем положении, и тогда тримукс перетянет слабую подтяжку к 0V. Эмиттерный повторитель обеспечивает надёжную индикацию даже самых слабых сигналов.
Если же пин нужно использовать на вход, то переключатель может быть подключен либо к +5V, либо к -5V. Резистор на 150Ohm защищает схему от короткого замыкания.
Тест-плата входов-выходов несёт на себе 9 абсолютно одинаковых схем:

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

Здесь три входа: C, A, B и один выход Q.
Статическая ячейка памяти (троичный триггер с запоминанием по уровню)
Давайте подключим два мультиплексора (напоминаю, они влезают на одну платку тримукса) следующим образом:

Давайте договоримся о терминологии: тактируемые триггеры делятся на управляемые уровнем и управляемые фронтом. Сейчас мы говорим об управлении уровнем, а это означает, что при одном уровне тактового сигнала C (-1 или 1) триггер воспринимает входные сигналы (A или B, соответственно), а при другом (0) не воспринимает и остаётся в неизменном положении.
Наша схема представляет собой два мультиплексора, второй мультиплексор представляет собой просто прозрачный буфер, а первый (в зависимости от тактового сигнала C) выдаёт на вход второго либо А, либо B, либо сам выход буфера! Это означает следующее поведение: при C=-1 выход Q замыкается на вход A, при C=1 выход Q замыкается на вход B, а при C=0 выход Q поддерживается постоянным и входы A и B просто игнорируются. В тексте это может быть сумбурно, поэтому посмотрите следующее видео:
Динамическая ячейка памяти: троичный триггер с управлением фронтом
В отличие от управления уровнем, при управлении фронтом разрешение на переключение триггера даётся только в момент перепада тактового сигнала. В остальное время независимо от уровня тактового сигнала триггер не воспринимает входные сигналы и остаётся в неизменном состоянии.
Экскурс в хорошо изученную область
Давайте на минутку совершим путешествие в двоичный (бррр) мир, чтобы было чуть понятнее. В русскоязычной литературе ко всем подобным схемам применяется слово «триггер» (поправьте меня, я маску-то только нашёл). Двоичный триггер с управлением по уровню называется gated D-latch. Грубо говоря, у него есть два входа: D (данные) и E (enable). Единственный выход Q равен D если E=1, и сохраняет своё значение если E=0.

Триггер со срабатыванием по уровню (flip-flop) может быть построен из двух обычных защёлкок (gated D-latch) и одного инвертера:
Эта схема называется Master-slave edge-triggered D flip-flop.
Назад в троичный мир или терра (почти) инкогнита
Если мы хотим получить срабатывание по фронту тактирующего сигнала, мы точно так же, как и в двоичном мире, можем использовать две троичные защёлки и один эквивалент двоичного инвертера, как на этой схеме:

Наша динамическая ячейка памяти имеет два входа: C и Am; она имеет один выход Qs. В двоичном мире инвертер генерирует второй сигнал со сдвинутой фазой, который тактирует ведомую защёлку. В нашей троичной схеме тактирующий сигнал расщепляется на два: min(C,0) и max(C,0), каждый из которых тактирует свою защёлку. Для того, чтобы сигнал Am дошёл до выхода Qs, нам необходимо подряд два восходящих фронта на сигнале C:

Обратите внимание, что сразу после включения схемы до того, как сигнал С заметёт от минус единицы до единицы, выходной сигнал Qs имеет неопределённое значение. Инициализируйте свои переменные :)
К слову, обратите внимание, что и у ведущей, и у ведомой защёлок один из входов не используется. Это можно применить для быстрой инициализации памяти, но об этом в следующий раз.
Вот соответствующиее видео работы ячейки памяти с динамическим управлением:
Заключение
Мы рассмотрели два варианта ячеек памяти. Ячейка памяти с динамическим управлением — это основной элемент троичного счётчика, который мы рассмотрим в следующий раз. Потом поговорим про АЛУ и тому подобное. Разумеется, получить даже один килотрит памяти подобным образом — весьма затратное (если делать «на коленке») занятие, но поскольку у меня железяка будет предназначена для демонстрационных целей и с гораздо меньшим количеством памяти, то это не так и страшно.
Enjoy!
Поделиться с друзьями
mayorovp
У вас лишние мультиплексоры в последней схеме. Вот так не проще ли?
Тут переключение происходит при переходе C от -1 к 0. Аналогичным образом можно сделать переключение по любому варианту фронта. Также можно добавить второй входной сигнал, получив триггер-мультиплексор...
haqreu
Интересный вариант, большое спасибо. Обязательно его попробую.