Самодельный процессор из транзисторов. Тема: Собрал комп полностью своими руками. Начинаем проект в FPGA

Никому не известный инженер Стив Чемберлин (Steve Chamberlin) решил изменить общепринятое мнение о том, что процессор своими руками создать невозможно. Точнее, процессор достаточно сложного ПК, который смог бы дублировать функции 8-битных вычислительных устройств, получивших распространение в начале 80-х. Вначале это было небольшой проект, который со временем вырос в нечто большее. Сейчас BMOW 1 представляет собой полноценный ПК на основе самодельного процессора, который запускает программы, имеет клавиатуру, VGA-видео, аудио-систему. Программная среда для BMOW 1 - Basic.

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

Стив поставил перед собой несколько целей, все из которых были выполнены:

Создать процессор из простых элементов, были использованы чипы 7400 серии, без компонентов серий 6502, Z-80 и т.д.;

Свести сложность аппаратной части к минимуму;

Компьютер должен был запускать «реальные» программы, не являясь чисто «игрушкой»;

Процессор должен стать элементом системы полноценного ПК;

Система должна быть достаточно быстрой для интерактивного запуска и работы программ.

Сама идея возникла у Стива в ноябре 2007, а к реализации инженер приступил в феврале 2008 года. В апреле 2008 система BMOW 1 запустилась в первый раз, чему наш создатель был несказанно рад. Постепенно были добавлены VGA-видео, аудио-система, BASIC, бутлоадер, который позволял взаимодействовать с подключенным ПК. Через некоторое время BMOW 1 стал достаточно сложным, чтобы обеспечивать работу непростых программ. Основные работы по созданию BMOW 1 были завершены в феврале 2009 года, ПК дорабатывался до настоящего времени.

Вот некоторые подробности о конфигурации устройства:

Текущая частота работы процессора около 2 МГц. Процессор может быть «разогнан» до 3 МГц (теоретически, пока не проверено);

512 КБ RAM, 512 КБ ROM;

Потребление энергии 10 Ватт, 2А при 5В;

Картинка на «выходе» имеет разрешение 512*480, два цвета, или же 128*240 - 256 цветов;

Аудио - трехканальный звуковой генератор;

Обычная клавиатура с PS\2-коннектором;

Дополнительный дисплей для вывода текста, 24*2 символа;

1250 проволочных проводника, т.е. около 2500 соединений;

Другие подробности - на

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

Главный вопрос - зачем все это нужно, если есть FPGA и всякие Raspberry Pi?

Ответ простой:
1) Мне интересно этим заниматься в свободное время и
2) Декоративный компьютер (декоративный - это вопрос отношения к компьютеру, а не его внешности) - он как декоративные домашние животные: мопс не отгрызет ногу грабителю, а персидский котик не победит в бою метрокрысу. Но с ними интересно играть и показывать гостям - даже если в области вычислений, охраны и охоты они сильно уступают «боевым» аналогам.

Подстановка задачи и архитектура

Какие будут у нас требования к декоративному компьютеру?

Но можно ли обойтись всего 4 транзисторами? Я немного пораскинул мозгами, и получилось следующее:

Графики работы:


Схему для симуляции в LTspice IV можно .

Принцип работы следующий: т.к. порядок слагаемых не имеет значения, мы их просто аналогово смешиваем, и точно подбирая пороговое напряжение сдвоенного инвертора - сразу получаем перенос. Затем вычитая на транзисторе Q3 из аналоговой суммы перенос - получаем сумму. Конечно, все это требует точного подбора уровней срабатывания, и симуляции с учетом температуры. Диоды Шоттки - для предотвращения входа транзисторов в глубокое насыщение, что резко снижает скорость работы.

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

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

У меня получилось уместиться в 2 транзистора на бит, со следующими особенностями:
1) Регистры - основаны на конденсаторах, и если их «не двигать» - то со временем данные пропадут. Но с полевым транзистором время хранения достаточно большое.
2) Передача данных на следующую ступень - биполярным транзистором. В половине случаев он работает в обратном, нестандартном режиме - пробивное напряжение намного меньше (но 3.3В должно держать), и коэффициент усиления намного ниже прямого включения (но я надеюсь будет достаточно).
3) Каждая следующая ступень - инвертирует сигнал, это не проблема когда нужен только последовательный доступ (например в случае регистров процессора). Если же будет нужен не инвертированный параллельный выход - нужно будет добавить 8 инверторов (т.е. 16-и битный сдвиговой регистр потребует 40 транзисторов, а не 32).
4) Остается проблема с насыщением биполярного транзистора.

График работы:

С этими компактными реализациями цифровых схем - уложиться в 1000 транзисторов думаю будет вполне реально.
На этом пока все - меня же ждет впереди чудовищно много работы

А теперь - несколько вопросов к читателям: Какие варианты кажутся вам приемлемыми?

Сколько я себя помню, всегда мечтал сделать процессор. Наконец, вчера я его сделал. Не бог весть что: 8 бит, RISC, текущая рабочая частота — 4 кГц, но он работает. Пока что в программе моделирования логических цепей, но все мы знаем: «сегодня — на модели, завтра — на деле!».

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

Двоичная логика

Двоичная система счисления (для тех, кто не в курсе) — это такая система счисления, в которой нет цифр больше единицы. Такое определение многих сбивает с толку, пока они не вспомнят, что в десятичной системе счисления нет цифр больше девятки.

Двоичная система используется в компьютерах потому, что числа в ней легко кодировать напряжением: есть напряжение — значит, единица; нет напряжения — значит, ноль. Кроме того, «ноль» и «один» легко можно понимать как «ложно» и «истинно». Более того, большая часть устройств, работающих в двоичной системе счисления, обычно относится к числам как к массиву «истинностей» и «ложностей», то есть оперирует с числами как с логическими величинами. Для самых маленьких и тех, кто не в курсе, я расскажу и покажу, как работают простейшие элементы двоичной логики.

Элемент «Буфер»

Представьте, что вы сидите в своей комнате, а ваш друг — на кухне. Вы кричите ему: «Друг, скажи, в коридоре горит свет?». Друг отвечает: «Да, горит!» или «Нет, не горит». Ваш друг — буфер между источником сигнала (лампочкой в коридоре) и приемником (вами). Более того, ваш друг — не какой-нибудь там обычный буфер, а буфер управляемый. Он был бы обычным буфером, если бы постоянно кричал: «Лампочка светится» или «Лампочка не светится».

Элемент «Не» — NOT


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

Элемент «Или» — OR


Для объяснения сути элемента «Или» одной лампочки и одного друга, к сожалению, не хватит. Нужно две лампочки. Итак, у вас в коридоре две лампочки — торшер, к примеру, и люстра. Вы кричите: «Друг, скажи, хотя бы одна лампочка в коридоре светит?», и ваш друг отвечает «Да» или «Нет». Очевидно, что для ответа «Нет» все лампочки обязательно должны быть выключены.

Элемент «И» — AND


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

Элемент «Исключающее Или» — XOR


Повторим еще раз эксперимент для элемента «Или», но переформулируем свой вопрос к другу: «Друг, скажи, в коридоре только одна лампочка светит?». Честный друг ответит на такой вопрос «Да» только в том случае, если в коридоре действительно горит только одна лампочка.

Сумматоры

Четвертьсумматор


Четвертьсумматором называют элемент «Исключающее Или». Почему? Давайте разберемся.
Составим таблицу сложения для двух чисел в двоичной системе счисления:
0+0= 0
0+1= 1
1+0= 1
1+1= 10

Теперь запишем таблицу истинности элемента «Исключающее Или». Для этого обозначим светящуюся лампочку за 1, потухшую — за 0, и ответы друга «Да»/«Нет» как 1 и 0 соответственно.
0 XOR 0 = 0
0 XOR 1 = 1
1 XOR 0 = 1
1 XOR 1 = 0

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

Полусумматор

При переполнении результат сложения уже не помещается в столько же разрядов, во сколько помещались слагаемые. Слагаемые — два однозначных числа (одна значащая цифра, понимаете?), а сумма — уже двузначное (две значащих цифры). Две цифры одной лампочкой («Светится»/«Не светится») уже не передать. Нужно две лампочки. Нужно — сделаем!

Кроме XOR, для сумматора нам потребуется элемент «И» (AND).
0 XOR 0 = 0 0 AND 0 = 0
0 XOR 1 = 1 0 AND 1 = 0
1 XOR 0 = 1 1 AND 0 = 0
1 XOR 1 = 0 1 AND 1 = 1

Тадам!
0+0= 00
0+1= 01
1+0= 01
1+1= 10

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

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

Более сложные элементы

Мультиплексор


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

Мультплексоры состоят обычно только из сочетаний элементов «И», «Или» и «Не». У одноразрядного мультиплексора один вход называется «выбор адреса», два входа с общим названием «входной сигнал» и один выход, который так и называется: «выходной сигнал».

Когда на «выбор адреса» подается 0, то «выходной сигнал» становится таким же, как первый «входной сигнал». Соответственно, когда на «выбор» подается 1, то «выходной сигнал» становится равным второму «входному сигналу».

Демультиплексор


А вот эта штучка работает с точностью до наоборот. На «выбор адреса» даем адрес, на «вход данных» даем данные, на выходе с номером «адрес» имеем данные со входа.

Счетчик


Для понимания работы счетчика вам опять понадобится ваш друг. Позовите его из кухни (надеюсь, он не сильно там скучал, и, главное, не съел всю вашу еду), и попросите делать вот что: пусть он запомнит число 0. Каждый раз, когда вы будете прикасаться к нему, он должен прибавить единицу к тому числу, которое помнит, сказать результат и запомнить его. Когда результат будет равен (допустим) 3, он должен выкрикнуть «Абракадабра!» и отвечать при следующем прикосновении, что сейчас он помнит число 0. Немного сложно? Смотрите:

Вы прикасаетесь к другу. Друг говорит «Один».
Вы прикасаетесь к другу. Друг говорит «Два».
Вы прикасаетесь к другу. Друг говорит «Три». Друг выкрикивает «Хабрахабр! ». Критическая атака! Вы временно парализованы и не можете двигаться.
Вы прикасаетесь к другу. Друг говорит «Ноль».

Ну, и так далее. Очень просто, верно?
Вы, конечно, поняли, что ваш друг сейчас — это счетчик. Прикосновение к другу можно считать «тактирующим сигналом» или, попросту говоря, сигналом продолжения счета. Крик «Абракадабра» показывает, что запомненное значение в счетчике — максимальное, и что при следующем тактирующем сигнале счетчик будет установлен в ноль. Есть два отличия двоичного счетчика от вашего друга. Первое: настоящий двоичный счетчик выдает запомненное значение в двоичном виде. Второе: он всегда делает только то, что вы ему говорите, и никогда не опускается до дурацких шуточек, способных нарушить работу всей процессорной системы.

Память

Триггер


Давайте продолжим издеваться над вашим несчастным (возможно, даже воображаемым) другом. Пусть теперь он запомнит число ноль. Когда вы касаетесь его левой руки, он должен запоминать число ноль, а когда правой — число один. При вопросе «Какое число ты помнишь?» друг должен всегда отвечать то число, которое запоминал — ноль или один.
Простейшей запоминающей ячейкой является RS-триггер («триггер» значит «переключатель»). RS-триггер может хранить в себе один бит данных («ноль»/«один»), и имеет два входа. Вход Set/Установка (совсем как левая рука вашего друга) записывает в триггер «один», а вход Reset/Сброс (соответственно, правая рука) — «ноль».

Регистр


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

Регистр обычно может хранить в себе чуть больше, чем один бит. У него обязательно есть вход данных, выход данных и вход разрешения записи. С выхода данных вы в любой момент можете прочитать то, что в этом регистре записано. На вход данных вы можете подавать те данные, которые хотите в этот регистр записать. Можете подавать данные до тех пор, пока не надоест. В регистр все равно ничего не запишется до тех пор, пока на вход разрешения записи не подать один, то есть «логическую единицу».

Сдвиговый регистр


Вы когда-нибудь стояли в очередях? Наверняка стояли. Значит, вы представляете, каково быть данными в сдвиговом регистре. Люди приходят и становятся в конец очереди. Первый человек в очереди заходит в кабинет к большой шишке. Тот, кто был вторым в очереди, становится первым, а тот, кто был третьим — теперь второй, и так далее. Очередь — это такой хитрый сдвиговый регистр, из которого «данные» (ну, то есть люди) могут убегать по делам, предварительно предупредив соседей по очереди. В настоящем сдвиговом регистре, разумеется, «данные» из очереди сбегать не могут.

Итак, у сдвигового регистра есть вход данных (через него данные попадают в «очередь») и выход данных (из которого можно прочитать самую первую запись в «очереди»). Еще у сдвигового регистра есть вход «сдвинуть регистр». Как только на этот вход приходит «логическая единица», вся очередь сдвигается.

Есть одно важное различие между очередью и сдвиговым регистром. Если сдвиговый регистр расчитан на четыре записи (например, на четыре байта), то первая в очереди запись дойдет до выхода из регистра только после четырех сигналов на вход «сдвинуть регистр».

Оперативная память

Если много-много триггеров объединить в регистры, а много-много регистров объединить в одной микросхеме, то получится микросхема оперативной памяти. У микросхемы памяти обычно есть вход адреса, двунаправленный вход данных (то есть в этот вход можно записывать, и с него же можно считывать) и вход разрешения записи. На вход адреса подаем какое-нибудь число, и это число выберет определенную ячейку памяти. После этого на входе/выходе данных мы можем прочитать то, что записано в эту самую ячейку.
Теперь мы одновременно подадим на вход/выход данных то, что хотим в эту ячейку записать, а на вход разрешения записи — «логическую единицу». Результат немного предсказуем, не так ли?

Процессор

BitBitJump

Процессоры иногда делят на CISC — те, которые умеют выполнять много разных команд, и RISC — те, которые умеют выполнять мало команд, но выполняют их хорошо. Одним прекрасным вечером мне подумалось: а было бы здорово, если бы можно было сделать полноценный процессор, который умеет выполнять всего одну команду. Вскоре я узнал, что существует целый класс однокомандных процессоров — OISC, чаще всего они используют команду Subleq (вычесть, и если меньше или равно нулю, то перейти) или Subeq (вычесть, и если равно нулю, то перейти). Изучая различные варианты OISC-процессоров, я нашел в сети сайт Олега Мазонки, который разработал простейший однокомандный язык BitBitJump. Единственная команда этого языка так и называется — BitBitJump (скопировать бит и перейти по адресу). Этот, безусловно эзотерический, язык является полным по Тьюрингу — то есть на нем можно реализовать любой компьютерный алгоритм.

Подробное описание BitBitJump и ассемблер для этого языка можно найти на сайте разработчика . Для описания алгоритма работы процессора достаточно знать следующее:

1. При включении процессора в регистрах PC, A и B записаны 0
2. Считываем ячейку памяти с адресом PC и сохраняем прочитанное в регистр A
3. Увеличиваем PC
4. Считываем ячейку памяти с адресом PC и сохраняем прочитанное в регистр B
5. Увеличиваем PC
6. Записываем в ячейку с адресом, записанным в регистре B, содержимое бита с адресом А.
7. Считываем ячейку памяти с адресом PC и сохраняем прочитанное в регистр B
8. Записываем в регистр PC содержимое регистра B
9. Переходим к пункту 2 нашего плана
10. PROFIT!!!

К сожалению, алгоритм бесконечный, и потому PROFIT достигнут не будет.

Собственно, схема

Схема строилась стихийно, поэтому правят бал в ней страх, ужас и кавардак. Тем не менее, она работает, и работает прилично. Чтобы включить процессор, нужно:

1. Ввести программу в ОЗУ
2. Нажать на включатель
3. Установить счетчик в положение 4 (это можно делать и аппаратно, но схема стала бы еще более громоздкой)
4. Включить тактовый генератор

Как видите, использованы один регистр, один сдвиговый регистр, одна микросхема ОЗУ, два двоичных счетчика, один демультиплексор (представленный компараторами), два мультиплексора и немного чистой логики.

Никому не известный инженер Стив Чемберлин (Steve Chamberlin) решил изменить общепринятое мнение о том, что процессор своими руками создать невозможно. Точнее, процессор достаточно сложного ПК, который смог бы дублировать функции 8-битных вычислительных устройств, получивших распространение в начале 80-х. Вначале это было небольшой проект, который со временем вырос в нечто большее. Сейчас BMOW 1 представляет собой полноценный ПК на основе самодельного процессора, который запускает программы, имеет клавиатуру, VGA-видео, аудио-систему. Программная среда для BMOW 1 - Basic.

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

Стив поставил перед собой несколько целей, все из которых были выполнены:

Создать процессор из простых элементов, были использованы чипы 7400 серии, без компонентов серий 6502, Z-80 и т.д.;

Свести сложность аппаратной части к минимуму;

Компьютер должен был запускать «реальные» программы, не являясь чисто «игрушкой»;

Процессор должен стать элементом системы полноценного ПК;

Система должна быть достаточно быстрой для интерактивного запуска и работы программ.

Сама идея возникла у Стива в ноябре 2007, а к реализации инженер приступил в феврале 2008 года. В апреле 2008 система BMOW 1 запустилась в первый раз, чему наш создатель был несказанно рад. Постепенно были добавлены VGA-видео, аудио-система, BASIC, бутлоадер, который позволял взаимодействовать с подключенным ПК. Через некоторое время BMOW 1 стал достаточно сложным, чтобы обеспечивать работу непростых программ. Основные работы по созданию BMOW 1 были завершены в феврале 2009 года, ПК дорабатывался до настоящего времени.

Вот некоторые подробности о конфигурации устройства:

Текущая частота работы процессора около 2 МГц. Процессор может быть «разогнан» до 3 МГц (теоретически, пока не проверено);

512 КБ RAM, 512 КБ ROM;

Потребление энергии 10 Ватт, 2А при 5В;

Картинка на «выходе» имеет разрешение 512*480, два цвета, или же 128*240 - 256 цветов;

Аудио - трехканальный звуковой генератор;

Обычная клавиатура с PS\2-коннектором;

Дополнительный дисплей для вывода текста, 24*2 символа;

1250 проволочных проводника, т.е. около 2500 соединений;

Другие подробности - на

  • Микропроцессор своими руками. Часть 4.3. Как отладить встроенный в FPGA микроконтроллер?
  • Микропроцессор своими руками. Часть 5.1. По поводу начала проекта встроенного в FPGA микроконтроллера
  • Микропроцессор своими руками. Часть 5.2. По поводу начала проекта встроенного в FPGA микроконтроллера
  • Микропроцессор своими руками. Часть 5.3. По поводу начала проекта встроенного в FPGA микроконтроллера
  • Микропроцессор своими руками. Часть 5.4. По поводу начала проекта встроенного в FPGA микроконтроллера
  • Начинаем проект в FPGA

    Так же, как и предыдущий проект , будем выполнять проект на языке AlteraHDL (AHDL). Этот язык достаточно широко распространен и описан. Кроме того, для начинающих он гораздо более доступен, чем другие языки группы VHDL. Так же более доступны и студенческие версии ПО.

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

    Итак, проектируем:

    Построение ядра микропроцессора

    Ядро микропроцессора будет состоять из следующих узлов:

    1. аккумулятор разрядностью в 1 бит;
    2. область DS будет состоять из областей ввода и вывода и части одного блока синхронной памяти, находящейся на кристалле;
    3. область вывода будет представлять собой выходную шину и выходные данные будут записываться в часть блока синхронной памяти, находящейся на кристалле;
    4. применим самую быструю структуру выборки данных из памяти, то есть синхронную выборку с конвейером команд.

    На основании задания и сделанных упрощений на микропроцессор, получим архитектуру, показанную на рис. 2.

    Микропроцессор состоит из набора следующих блоков:

    • АЛУ, которое содержит узел контроля для выработки управляющих воздействий на все блоки микропроцессора - ALU;
    • счетчик адресов памяти программ - PS_CNT;
    • блок памяти программ - PS;
    • блок памяти данных - DS.

    На входы микропроцессора подадим сигнал синхрочастоты CLK, сигнал разрешения работы и системный сигнал СБРОС, так же, как и на все остальные блоки системы (на рис. не показано).

    Входами микропроцессора будут сигналы с входной шины данных.

    Выходами микропроцессора будут сигналы с выходной шины данных и сигнал разрешения записи.

    Счетчик команд при загрузке микросхемы или при инициализации системы по сигналу СБРОС устанавливается в состояние 0, после чего производит счет адресов памяти программ. Адреса поступают на вход блока PS. Данные, хранящиеся в памяти программ, выбираются в соответствии с поступившим адресом. Затем данные с выхода PS поступают как код адреса в двухпортовую память данных для того, чтобы можно было загрузить данные из памяти в аккумулятор. Чтобы скомпенсировать задержку, которую имеет синхронная память при чтении, данные с выхода PS поступают на двухкаскадный блок регистров задержки. ALU дешифрирует коды команд микропроцессора. В состав АЛУ входит триггер-аккумулятор, на котором и выполняются все команды микропроцессора. Данные на вход аккумулятора микропроцессора при чтении памяти поступают либо с выхода двухпортовой памяти, либо со входа Х в соответствии с адресом шины адресов данных при чтении внешних устройств микропроцессора. Данные с выходов аккумулятора записываются либо только в двухпортовую память, либо одновременно в двухпортовую память и во внешние устройства.

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

    Соглашение о названии сигналов (о наименовании цепей)

    Для однообразия примем, что активное состояние сигналов будет равно 1. Если активное состояние сигнала будет равно 0, то в название сигнала на конце будет добавлена буква «n ».

    В файлах описаний применим следующие названия сигналов:

    сlk - частота, синхрочастота;

    reset - сигнал системного сброса;

    _еna - сигнал разрешения записи, в большинстве случаев его длительность будет равна длительности 1-го периода синхрочастоты;

    _node - название сигнала относится к внутреннему узлу схемы.

    Верхний файл проекта, описывающий микропроцессор

    Верхний файл проекта one_bit_cpu.tdf - непосредственно микропроцессор. Для описания памяти команд применена библиотечная функция lpm_rom, и для ее инициализации применен файл step1.mif. Для описания двухпортовой памяти данных применена библиотечная функция lpm_ram_dp, для описания счетчика адресов применена библиотечная функция lpm_counter. Два каскада задержки реализованы на регистрах stage_a и stage_b.

    В отличие от АЛУ, описанного в предыдущей статье , в данном микропроцессоре нет прерываний, поэтому здесь АЛУ представляет собой простой дешифратор 4 в 16. На вход дешифратора подаются биты, соответствующие КОП. АЛУ вырабатывает сигналы управления для всего, что есть в данном проекте, и коммутирует данные на вход аккумулятора микропроцессора. Аккумулятор выполнен на триггере (acc).

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

    Пример работы битового микропроцессора

    Для примера представим, что у нас есть объект управления, состоящий из 16 входных переменных X0...X15.

    Представим некоторую управляющую программу для 4 выходных переменных - Z0, Z1, Z2 и Z3. Пусть каждая из этих переменных описывается логической функцией, в среднем состоящей, к примеру, из 5 членов.

    Представим, что входные переменные расположены по последовательным адресам, начиная с 0. То есть переменная X0 находится в поле памяти по адресу 0, переменная X1 - по адресу 1, и так далее. Представим, что выходы доступны по чтению с адреса 800, а выходные переменные доступны по чтению начиная с адреса C00. Теперь перепишем полученные данные в машинных командах и создадим файл программы, которую будет выполнять микропроцессор.

    Для описания памяти команд применим библиотечную функцию lpm_rom, и для ее инициализации применим файл step1.mif. Далее по полученным машинным кодам сформируем файл инициализации памяти программ - файл типа «.mif». Файл step1 будет содержать коды команд микропроцессора, причем команда перехода к началу программы будет выдаваться после всех команд вычислений.

    В данной программе после команды SKIP еще 4 ячейки памяти заполнены кодами команды NOP. Это сделано для того, чтобы показать, как выполняется команда перехода SKIP в микропроцессоре с конвейером команд. Подробное описание работы с этой программой будет приведено в следующем разделе.

    Создадим еще один файл инициализации памяти программы микропроцессора, файл step2.mif, который также будет содержать коды команд микропроцессора, но команда перехода к началу программы будет выдаваться на 2 такта раньше, чем последняя команда вычислений. На основе данного файла будут показаны последовательности выполнения команд переходов, приведенные в разделе «Время выполнения команды и конвейер команд» (см. «КиТ» № 7"2003).

    Создайте рабочую папку, например My_cpu, запишите файл в эту папку, затем выполните компиляцию, чтобы убедиться в отсутствии ошибок. В качестве DEVICE для проекта выберем серию ACEX, а для выбора микросхемы установим режим AUTO. Произведем компиляцию проекта.

    Что мы получили

    По итогам компиляции проекта из файла рапорта получаем следующий результат:

    Для реализации проекта потребовалось всего 64 ячейки логики и 2 блока внутренней памяти.

    Симуляции работы микропроцессора приведены на рис. 3–5.

    На диаграммах изображены входы:

    • сброс - reset;
    • сигнал разрешения работы - ena;
    • синхрочастота - clk;
    • вход битовых данных - хх.

    На диаграммах изображены выходы:

    • выход битовых данных - у;
    • сигнал разрешения записи выходных данных - wr;
    • шина адресов входных и выходных данных - addr.
    • адрес, поступающий на вход блока памяти команд - lpm_rom;
    • данные, поступающие на вход блока памяти данных - lpm_ram_dp;
    • адрес, поступающий на вход блока памяти данных - lpm_ram_dp;
    • два сигнала, соответствующие stage_a, stage_b;
    • сигнал на выходе аккумулятора - acc.

    Синхрочастота, поступающая на тактовый вход микропроцессора, имеет длительность импульса 30 нс, и каждый положительный фронт синхрочастоты пронумерован. Все описание работы будет опираться на соответствующий фронт синхрочастоты. Будем называть фронты так: фронт1, фронт2 и т. д.

    Режим начала вычислений

    После снятия сигнала «Сброс» счетчик адреса команд находится в состоянии 0000, регистры конвейера команд обнулены. При действии фронта1 состояние сброса уже снято и в конвейер команд загружается первая команда. Поскольку на выходе конвейера команд эта команда появится только на фронте2, то АЛУ выполняет два первых такта как команды NOP. И только к фронту3 данные из конвейера будут обработаны в АЛУ как первая команда вычислений. Затем под каждый фронт синхрочастоты из конвейера команд будет выдаваться очередная команда, которая будет выполняться в этом же такте синхрочастоты. Далее читатели могут самостоятельно рассмотреть все действия, происходящие при проверке работы микропроцессора с другими командами из файла step1.

    Выполнение команды перехода в начальный адрес, выполняемое без учета задержки, вносимой конвейером команд

    После того как были вычислены все значения выходных переменных, была выдана команда перехода на адрес 0000. Рассмотрим выполнение микропроцессором данной операции, выполняемой в соответствии с файлом step1. Результат симуляции приведен на рис. 4. На приведенной диаграмме синий вертикальный курсор установлен в том месте, где на вход памяти команд поступает адрес команды 1E, по которому расположен код команды перехода. Этот фронт синхрочастоты пронумерован на данной диаграмме как фронт1. Далее этот код попадает в конвейер команд, по которому и «путешествует» до такта фронт3. При этом счетчик команд продолжает инкрементироваться и из памяти команд извлекаются данные, находящиеся в адресах 1F, 20. Только после выполнения двух лишних тактов происходит переход в начало программы. Такой режим работы характерен для всех микропроцессоров, имеющих конвейер команд. Обычно устройство управления блокирует АЛУ на время перезагрузки конвейера новыми данными. То есть для данного примера это были бы такты 1, 2.

    Выполнение команды перехода в начальный адрес, выполняемое с учетом задержки, вносимой конвейером команд

    Для проверки микропроцессора в режиме работы с учетом задержки, вносимой конвейером команд, создадим файл инициализации памяти программ микропроцессора step2.mif. Произведем компиляцию проекта с данным файлом инициализации памяти.

    Рассмотрим выполнение микропроцессором операции перехода на адрес 0000, выполняемой в соответствии с файлом step2. Результат симуляции - временная диаграмма работы микропроцессора с файлом команд step2 - приведена на рис. 5. На приведенной диаграмме синий вертикальный курсор установлен, как и в предыдущем случае, в том месте, где на вход памяти команд поступает адрес команды 1E, по которому расположен код последней команды файла step2. Этот фронт синхрочастоты пронумерован на данной диаграмме как фронт1. Поскольку команда перехода на начальный адрес была выдана по адресу 1C, то к моменту времени, определяемому фронтом1, эта команда успела пройти весь конвейер и поступить в АЛУ. Устройство управления вырабатывает сигнал синхронного сброса счетчика команд. Далее из конвейера извлекаются команды, записанные туда еще до перехода, и эти команды исполняются. А на вход конвейера поступают команды, прочитанные по новому адресу. Таким образом, нет двух лишних тактов при переходе в начало программы.

    Итак, можно сделать вывод, что для вычисления значений 4 выходных переменных по 16 входным для приведенного выше примера мы получили 31 машинную команду. А это значит, что за 31 цикл значения всех выходных параметров будут вычислены. При использовании серии микросхем Apex или Acex при тактовой частоте 33 МГц весь цикл вычислений для приведенного выше примера займет 0,93 микросекунды. На микросхемах серии Cyclon или Stratix при тактовой частоте 300 МГц мы получим результат всего за 102 наноосекунды. Если учесть, что за это же время микропроцессор типа AVR при тактовой частоте 8 МГц успеет выполнить примерно 8 команд, то преимущества становятся очевидными.

    Еще один пример программирования на битовом процессоре

    Описываемый процессор при кажущейся своей «маломерности» способен, тем не менее, выполнять широкий круг задач, возникающих при управлении объектами. Первая из таких задач - счетчик. Приведем пример выполнения программного 2-разрядного счетчика сигналов, приходящих по шине Х с одного из входов. Чтобы предотвратить изменение сигнала во время одного цикла вычислений, будем записывать значение входного сигнала в ячейку Y() и далее будем использовать это значение для вычислений. Поскольку сигнал может меняться произвольно, программно определим положительный фронт сигнала, по которому будем вести счет. Далее приведены вычисления, необходимые для выполнения счета.

    Y(0) = X(0); - здесь мы зафиксировали значение входа для текущего цикла вычислений.

    Y(1) = Y(0) AND (NOT Y(4)); - выделитель фронта.

    Y(2) = (Y(0) AND Y(1)) XOR Y(2); - младший разряд счетчика.

    Старший разряд счетчика должен переключаться при условии, что младший разряд перешел в состояние 1, тогда получаем: Y(3) = (Y(2) AND Y(1) AND Y(0)) XOR Y(3);

    Y(4) = Y(0); - здесь фиксируется значение Y(0), задержанное на время обработки фронта.

    Создадим файл программы обработки step3.mif, который отличается от предыдущих файлов следующими кодами команд:

    Y(803), Y(802) - разряды счетчика, X(0) - входное событие, которое мы хотим сосчитать. Если во входном сигнале может быть дребезг, то выделим одну внутреннюю переменную Y(800) для фиксации приходящего импульса, Y(804) для фиксации задержанного импульса и еще одну переменную Y(801) для выделения фронта импульса. В тестовом проекте этим выходам будут соответствовать выходы: Y(800) ->y0, Y(801) ->y1, Y(802) ->y2, Y(803) ->y3, Y(804) ->y4.

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

    Произведем симуляцию тестового примера. Результат симуляции показан на рис. 6.

    Как видно на приведенной диаграмме, микропроцессор считает импульсы, приходящие на вход Х, а на выходах y2 и y3 представлено выходное значение счетчика. Конечно, для обработки многоразрядного счетчика требуется затратить соответствующее число команд. Но поскольку мы имеем дело с FPGA, то в том случае, когда необходимо проводить подсчет большого количества переменных, можно ввести в состав периферии для данного микропроцессора массив счетчиков. Ячейки со счетными триггерами могут проецироваться в поле памяти микропроцессора и выполнять счет при обращении к данной ячейке.

    Другая задача, очень часто встречающаяся при управлении дискретными объектами - статический автомат. Программирование статического автомата выполняется аналогично программированию счетчика.

    Сравнительная характеристика

    Для сравнения можно сказать, что широко известные микропроцессоры, такие, как MCS51, выполняют одну команду за 12 тактов, а их более «продвинутые» версии - за 4 такта, и только новейшие Cygnal - за 1 такт. Микропроцессоры, выполненные по структуре PIC16X, выполняют одну команду за 2 такта синхрочастоты. В таблице приведены сравнительные характеристики встроенных микропроцессоров. Сравнивая занимаемые в кристалле ресурсы, можно сделать вывод о том, что применение встроенного битового процессора оправдано, так как при очень малом занимаемом ресурсе он позволяет выполнить достаточно быстродействующие устройства обработки битовых данных.

    Таблица. Сравнение характеристик встроенных микроконтроллеров

    Примечания:

    1. http://www.alatek.com/pages/products/ip_industrial.asp.

    2. http://www.altera.com/products/ip/processors/m-cas-8051-micro.html.

    3. ttp://www.altera.com/products/ip/processors/m-cas-pic165x.html.

    Несколько слов об отладке программ во встроенных микропроцессорах

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

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

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

    Поскольку весь проект «самодельного» микропроцессора для нас открыт и мы знаем его устройство, то мы можем облегчить отладку программ при помощи дополнительных аппаратных ресурсов, так как в процессе отладки можно использовать FPGA с большим количеством ячеек, чем нужно для функционирования проекта. Это позволит выделять отладочные ресурсы. К таким ресурсам можно отнести:

    1. дополнительные поля памяти для вызова тестовых и мониторных программ;
    2. тестовые входы и выходы для микропроцессора, позволяющие снимать состояния сигналов и задавать воздействия;
    3. дополнительные поля памяти могут использоваться для включения в систему встроенных логических анализаторов, как входящих в комплект инструментального ПО, так и «самодельных», разработанных пользователем, что является очень мощным средством отладки (см. например, );
    4. дополнительные счетчики, тестовые триггеры и т. д.

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

    Все эти возможности позволяют проводить успешную отладку программы не только в программном симуляторе, но и на «живом железе».

    Заключение

    В целом применение управляющего микропроцессора в FPGA позволяет повысить интеграцию устройства и перейти от «системы на плате» к «системе на кристалле».

    Мы получили битовый RISC-микропроцессор, работающий на частоте 30–300 МГц и выполняющий все команды за один такт. И, следовательно, спроектированный микропроцессор имеет производительность 30–300 MIPS. Проект требует всего 64 ячейки логики и 2 блока внутренней памяти. При сравнении ресурсов кристалла, требуемых для такого микропроцессора, можно сказать, что они составляют не более десятой части от ресурсов ядра 8-разрядного микропроцессора.

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

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

    Следующей статьей в данном цикле будет статья о стековых процессорах - о Forth- и Java-микропроцессорах.

    Литература

    1. Каршенбойм И. Микропроцессор своими руками // Компоненты и Технологии. 2002. № 6–7.
    2. Каршенбойм И. Микропроцессор для встроенного применения Nios. Система команд и команды, определяемые пользователем // Компоненты и Технологии. 2002. № 8–9.
    3. Каршенбойм И. Микропроцессор для встроенного применения Nios. Конфигурация шин и периферии // Компоненты и Технологии. 2002. № 2–5.
    4. И. Каршенбойм, Н. Семенов. Микропрограммые автоматы на базе специализированных ИС // Chip News. 2000. № 7.
    5. И. Каршенбойм, К. Паленов. «Встроенный» логический анализатор - инструмент разработчика «встроенных» систем // Схемотехника. 2001. № 12.


    
    Top