Строим декоративный транзисторный компьютер — шаг 1
Недавно на хабре была статья о проектировании собственного компьютера, где автор хотел сначала строить компьютер из транзисторов, но затем решил продолжить на микросхемах 7400-серии из-за того, что на транзисторах ему это показалось слишком сложным и дорогим занятием.Похожая задача интересовала и меня последние 3 года - но от изначальной идеи строить на транзисторах я не отказался, и сейчас могу рассказать свои соображения и показать текущие наработки, а также - хочу спросить вашего мнения о том, каким на ваш взгляд должен быть _серийный_ транзисторный декоративный компьютер. Но сразу нужно заметить, что работы впереди еще на пару лет :-)
Главный вопрос - зачем все это нужно, если есть FPGA и всякие Raspberry Pi?
Ответ простой:
1) Мне интересно этим заниматься в свободное время и
2) Декоративный компьютер (декоративный - это вопрос отношения к компьютеру, а не его внешности) - он как декоративные домашние животные: мопс не отгрызет ногу грабителю, а персидский котик не победит в бою метрокрысу. Но с ними интересно играть и показывать гостям - даже если в области вычислений, охраны и охоты они сильно уступают "боевым" аналогам.
Подстановка задачи и архитектура
Какие будут у нас требования к декоративному компьютеру?- Разработка под автоматизированную сборку. Руками паять по 5000 деталей на компьютер - поседеть можно.
- Производительность - не существенна, главное чтобы 100тыс+ операций в секунду было (на уровне Радио-86РК). Даже 100тыс оп/с позволит решать очень многие задачи.
- Практика показывает, что 64 КиБ памяти - реалистичный минимальный объем памяти. В 1-4 КиБ многое не влезет, потому уменьшать шину адреса меньше 16 бит не стоит.
- Программирование - на C. Нельзя заставлять людей тратить своё свободное время на ассемблер (но если желание есть - то все карты в руки).
- В базовой модели - из транзисторов сделан только сам процессор. Память и обвязка - может быть из микросхем. Полностью транзисторный вариант возможен в будущем, но это уже будет дальнейшее развитие (со своими ограничениями - более 1-2 КиБ памяти иметь будет затруднительно)
- В процессоре - отключаемые светодиоды показывают состояние внутренних регистров (IP, аккумулятор, запись/чтение из памяти...)
- Не слишком высокая цена. Себестоимость одного транзистора с обвязкой и автоматическим монтажом - около 2 рублей, соответственно, использовать больше 1000 транзисторов не желательно для серийного продукта. Это означает, что схема должна быть проще, чем i8080 (6000 транзисторов), i4004 (2300 транзисторов), и MT15 (~3000 транзисторов), не смотря на требование 16-и битной шины адреса.
- uCLinux? Даже без виртуальной памяти, было бы очень желательно иметь 24-32 бита. Конечно, это существенно повысило бы интерес, но потребует по меньшей мере удвоения количества транзисторов (=удвоения цены). Также, с ростом разрядности - пропорционально падает и скорость последовательного компьютера.
- Аппаратная поддержка прерываний - не требуется, т.к. очень уж много за собой тянет (микрокод, аппаратный стек, и проч.), и обойтись без неё можно.
Взаимодействие с пользователем: Классическая реализация - это клавиатура + вывод на телевизор или VGA-монитор. Сделать удобную "свою" клавиатуру слишком сложно - нужно использовать стандартные PS/2 или USB. PS/2 клавиатуры уже редкость - а USB в транзисторном компьютере поддержать - будет затруднительно, без использования грязных хаков (вроде микроконтроллера).
Вероятно, оптимальным и простым решением может быть терминальный интерфейс - когда компьютер общается с внешним миром через последовательный порт (RS232), таким же образом можно загружать программы. Т.е. в простейшем случае транзисторный компьютер подключается к настольному компьютеру (или специализированному терминалу) через USB<>COM адаптер, и в любой программе-терминале (например Putty) можно с ним работать.
Также, нужна и возможность подключать внешние устройства через GPIO-пины.
Последовательный или параллельный ALU? 8 или 16 бит?: Поскольку количество транзисторов очень ограничено (<1000), придется жертвовать производительностью, и все операции проводить последовательно. Это очень сильно снижает требуемое количество транзисторов - фактически нужна логика на 1 бит и 16-и битные сдвиговые регистры. Но при тактовой частоте 1Мгц - мы будем иметь только 62тыс. операций в секунду, желательно конечно частоту иметь по-выше.
Т.к. нам в любом случае нужно иметь 16-и битную шину адреса, поддерживать 8-и битные операнды - значит существенно усложнять систему команд и увеличивать количество требуемых регистров. Потому, вероятно будет все просто - 16-и битная шина адреса, и 16-и битное машинное слово. Возможности работы с 8-и битными данными не будет, если кому нужны только 8 бит - придется поработать со сдвигами.
Архитектура процессора: Безусловно, полноценному компьютеру нужно иметь возможность писать в свою память кода. Потому, если есть возможность переложить это на внешнюю обвязку процессора - то Гарвардская архитектура (с раздельной памятью кода и данных) будет проще в реализации, и быстрее в работе. Но если обвязка процессора транзисторная - то придется использовать совместную память кода и данных. Так что тут выбор зависит от голосования в конце статьи :-)
Сам процессор - будет hard-wired (логика по работе с микрокодом, и сам микрокод - могли бы занять очень много транзисторов), неизбежно будет иметь очень простой набор инструкций (бинарная логика + add, сдвиги на 8 и 1 бит), и минимальное количество регистров (1-2) с возможностью использовать оперативную память как псевдо-регистры (как в 6502). Возможно, в простейшем случае все команды будут выполнятся по единой жесткой схеме ax = mem[imm] = mem[imm] op ax + бит условного перехода - это позволит уменьшить до минимума логику процессора, и положить максимальный объем работы на относительно быструю оперативную память.
Аппаратного стека и аппаратной обработки прерываний не будет - реализовать это можно и в софте: памяти у нас больше, чем транзисторов.
Напряжение питания: 3.3 и 5В? Большинство старых компьютеров используют 5В, а современная электроника - уже давно ориентируется на 3.3В для внешних соединений. Этот компьютер также будет использовать 3.3В - но потому, что низкоомные резисторы подтяжки будут потреблять в 2.5 раза меньше энергии - и соответственно, можно дальше уменьшить их сопротивление и увеличить скорость.
Строительные блоки транзисторного процессора
Безусловно, сделать процессор из менее чем 1000 транзисторов, пользуясь стандартными подходами к построению логических схем (даже с учетом последовательного ALU) не выйдет - и нужно применять различные схемотехнические компромиссы и ухищрения с целью уменьшения количества транзисторов.Также немаловажен вопрос скорости - и в предыдущей статье на хабре и в MT15 - тактовая частота, на которой могли работать логические блоки получилась очень низкой. Для последовательного компьютера этот вопрос становится животрепещущим.
Скорость простой логики
Как оказалось, есть несколько простых трюков, которые очень сильно ускоряют логику на биполярных транзисторах: это добавление диода Шоттки для предотвращения входа транзистора в глубокое насыщение (выход из которого очень медленный, до 200-500нс), и опционально - добавление конденсатора на 25-50 пФ параллельно резистору базы для того, чтобы быстро перезаряжать паразитные емкости схемы. Ну и конечно, как и для любых скоростных цифровых схем - нужна развязка питания керамическими конденсаторами рядом с потребителями, и длинные цифровые дорожки в некоторых случаях будут требовать терминирование.После применения этих хитростей получаем следующее (здесь обе оптимизации - в самой правой части схемы):
И работает это очень резво, на осциллограмме - 100нс/деление, фронты/задержки порядка 10нс:
Также, подбирая сопротивление резистора от базы к земле - можно управлять передаточной характеристикой логики, чтобы пороговое напряжение было примерно как у CMOS, около 3.3/2 = 1.65В. Такое изменение помимо помехоустойчивости даст еще одно важное преимущество : пологие фронты на входе - будут становится более резкими после прохождения логики. Также, если электричество нам экономить не нужно, мы можем выкинуть "верхний" транзистор, и заменить его резистором. Схема получается такая:
А передаточная характеристика:
3 цветные линии - это симуляция при разной температуре (20, 40 и 60 градусов), параметры биполярных транзисторов ощутимо плывут с температурой, и это обязательно нужно учитывать в более сложных схемах.
Более сложная логика
T-триггер - Т-триггер по тактовому сигналу изменяет своё состояние на противоположное. Может использоваться для построения параллельного счетчика инструкций, но использоваться вероятно не будет т.к. все будет работать последовательно. Принцип работы - бистабильный мультивибратор, по короткому отрицательному синхроимпульсу - переключается в противоположное состояние за счет конденсаторов параллельно резисторам R8 и R9.Схема была реализована "в железе", вместе с инверторами. Инверторы показали ожидаемую скорость (т.е. ~10-20нс фронты). Не пугайтесь качеству пайки - плата пережила множество экспериментов и вариантов транзисторов/параметров:
Полный сумматор - один из наиболее важных и сложных цифровых блоков. Каноническая реализация КМОП полного сумматора - требует 28 транзисторов:
Современные реализации с использованием transmission gate и различных хитростей - требуют 8-11 транзисторов с более жесткими требованиями к выбору транзисторов, но напрямую из дискретных транзисторов эти схемы не реализовать - нужны 4-х выводные транзисторы (а они редкость), и из-за деградации уровня логической 1 нужно высокое напряжение питания (т.к. пороговое напряжение доступных дискретных полевых транзисторов - 1.5-2 вольта против 0.5В у интегральных транзисторов).
Самый минимум, который приходилось видеть - из 6 транзисторов, с использованием конденсаторов (но надежность вызывает вопросы). Известные реализации на биполярных транзисторах - также требуют 22 транзистора.
Но можно ли обойтись всего 4 транзисторами? Я немного пораскинул мозгами, и получилось следующее:
Графики работы:
Схему для симуляции в LTspice IV можно скачать тут.
Принцип работы следующий: т.к. порядок слагаемых не имеет значения, мы их просто аналогово смешиваем, и точно подбирая пороговое напряжение сдвоенного инвертора - сразу получаем перенос. Затем вычитая на транзисторе Q3 из аналоговой суммы перенос - получаем сумму. Конечно, все это требует точного подбора уровней срабатывания, и симуляции с учетом температуры. Диоды Шоттки - для предотвращения входа транзисторов в глубокое насыщение, что резко снижает скорость работы.
Использование полевых транзисторов возможно, и обеспечивает лучшую температурную стабильность, главное чтобы у них было достаточно низкое пороговое напряжение.
Сдвиговой регистр - самая ответственная часть этого транзисторного компьютера. Классическая реализация на синхронных D-триггерах - требует чудовищного количества транзисторов на бит.
У меня получилось уместиться в 2 транзистора на бит, со следующими особенностями:
1) Регистры - основаны на конденсаторах, и если их "не двигать" - то со временем данные пропадут. Но с полевым транзистором время хранения достаточно большое.
2) Передача данных на следующую ступень - биполярным транзистором. В половине случаев он работает в обратном, нестандартном режиме - пробивное напряжение намного меньше (но 3.3В должно держать), и коэффициент усиления намного ниже прямого включения (но я надеюсь будет достаточно).
3) Каждая следующая ступень - инвертирует сигнал, это не проблема когда нужен только последовательный доступ (например в случае регистров процессора). Если же будет нужен не инвертированный параллельный выход - нужно будет добавить 8 инверторов (т.е. 16-и битный сдвиговой регистр потребует 40 транзисторов, а не 32).
4) Остается проблема с насыщением биполярного транзистора.
График работы:
С этими компактными реализациями цифровых схем - уложиться в 1000 транзисторов думаю будет вполне реально.
На этом пока все - меня же ждет впереди чудовищно много работы