nedoPC.org

Electronics hobbyists community established in 2002
Atom Feed | View unanswered posts | View active topics It is currently 28 Mar 2024 06:40



Reply to topic  [ 33 posts ]  Go to page 1, 2, 3  Next
CPU N 
Author Message
Fanat
User avatar

Joined: 24 Sep 2007 12:15
Posts: 63
Location: Украина
Reply with quote
После некоторого перерыва меня вновь охватила волна недо-энтузиазма.
Видеокарта, к несчастью, меня интересовать перестала, так и лежит не доделанная, даже схему в eagle нарисовать и выложить лень, извините. :(
Зато я всецело поглощен разработкой процессора (все-таки ввязался в это гиблое дело).
Идея отнюдь не утопична. Достаточно посетить этот сайт http://mycpu.thtec.org/www-mycpu-eu/ и потом полистать Homebuilt CPUs WebRing внизу страницы, чтобы узнать, что таких проектов было много, и большинство успешно воплощено в жизнь.
Основной принцип работы большинства этих CPU – управление микро-кодом, записанным в ПЛМ. На входы ПЛМ подается код операции, значения флагов и счетчик микрокоманд (микрокоанда – слово большой разрядности, каждый бит которого управляет некоторой простой отдельной частью ЦП, например, подает сигнал на вход OE\ некоторого регистра, управляя выдачей данных из него на внутреннюю шину и т. д.). Счетчик инкриементируется и таким образом с выхода ПЛМ последовательно подается набор микрокоманд необходимый для выполнения одной макрокоманды (той, чей код операции подан на входы ПЛМ)).
В качестве ПЛМ в этих проектах служит EPROM. Но я решил использовать для этих целей SRAM из-за малого (20 нс) времени доступа по сравнению с EPROM (100 нс), что позволяет добиться большего быстродействия. Сделать самопрограммирующийся при включении ЦП оказалось очень сложно, так что буду просто использовать батарейное питание SRAM хоть это и менее солидно.
АЛУ также строится на ПЛМ (в англ. варианте look-up tables), что гарантирует простоту и высокую скорость.

Это была теория. Сладкая. Теперь правда. Горькая.

Image

Это ПЛМ-ы АЛУ проекта MyCPU (регистры АЛУ и некоторая прочая логика на другой схеме, кому нужно все – зайдите на сайт и скачайте selfbuild guide).
АЛУ состоит из 2-х 8-ми мегабитных микросхем EPROM, в одной результаты бинарных операций, в другой флаги, и еще одной 8-ми килобайтной -- содержатся результаты унарных операций. У этих микросхем по 20 адресных входов. 2 х 8 – операнды, 3 – код бинарной операции, и один вход для флага переноса CF.
Я располагаю микросхемами SRAM xxC256 у которых лишь 14 адресных входов, чего не хватает даже для двух операндов.
Выход в каскадировании. Сделать 8-ми разрядное АЛУ из двух 4-разрядных. На входы первого 4р. АЛУ подаются младшие 4 бита каждого операнда, на входы второго – старшие. Флаги C и Z результата первого АЛУ заводятся во второе. Общая задержка «операнд-стабильный результат» равна суме задержек двух микросхем памяти. Такое АЛУ, к сожалению, не может умножать и делить.

Вот моя схема:

Image

ID_BUS — internal data bus внутренняя шина данных ЦП
CD_BUS – command data bus шина по которой передается операнд содержащийся в коде команды.
ALU_CMD – ALU command код операции АЛУ и управляющие сигналы.
Загрузка 2-го операнда осуществляется через «прозрачную» защелку 1-го, для уменьшения нагрузки на шину.
(Нашел в схеме незначительные ошибки, но перезагружаться в винду и исправлять -- не хочется)

К несчастью эта схема нуждается в переработке, т. к. она не может осуществлять сдвиги вправо. Однако каскадирование позволяет собрать и 16-разрядное АЛУ, чего нельзя сделать просто заведя все операнды и код в одну EPROM как это было сделано в MyCPU. Иначе нужна ROM на 64 ГБ :)

Теперь я думаю, а не сделать ли 16-bit CPU? Это было бы круто! Но к несчастью сопряжено с рядом трудностей.

Сейчас важно понять в каком направлении идти. Вот и хотел бы вас по этому поводу спросить. Кто что думает?

Многие проблемы касательно выравнивания команд я уже решил. Но самые большие заморочки с программной архитектурой. Какой должен быть набор команд?
В 8-ми битных ЦП во всех арифметических командах один неявно заданный операнд – аккумулятор. Это экономит коды команд. А в x86 можно написать
Code:
add   bx, cx

и что вообще страшно
Code:
add   bl, bh

для таких «извращений» нужно мультиплексировать в АЛУ младшие и старшие части шины, или хотя-бы сделать между ними мост.

256 кодов операций для этого не хватит.

Регистры я храню во внутреннем ОЗУ, так что их число ограничивается лишь количеством кодов...

Делать ли регистры делимыми на независимые старшую и младшую часть?


20 Nov 2009 11:44
Profile
Admin
User avatar

Joined: 08 Jan 2003 23:22
Posts: 22409
Location: Silicon Valley
Reply with quote
Post 
А ты сделай длину команды в 16 бит, а не в 8 - тогда всё влезет :)

P.S. Интересно, что к посетителям данного форума идеи приходят синхронно - я на днях купил себе 100 микросхем 74F00 (это ЛА3 со средним временем срабатывания 3 нс) за 4.5 цента за штучку (clearance) - буду городить 16-битный риск-процессор на мелкой логике :)

_________________
:dj: https://mastodon.social/@Shaos


20 Nov 2009 14:54
Profile WWW
Senior

Joined: 28 Feb 2006 21:34
Posts: 180
Reply with quote
Post 
Хм. Как показывает расчет, для 16ти битной шины нужно этак примерно на порядок больше. Ведь часть уйдет просто на инверторы и реализацию ИЛИ. А большая часть на всякие триггеры для регистров. Видел недавно гдето в инете студенческую поделку - программа переводит схему из помоему Верилога как раз в ИЛИ-НЕ.

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


20 Nov 2009 23:50
Profile
Fanat
User avatar

Joined: 24 Sep 2007 12:15
Posts: 63
Location: Украина
Reply with quote
Post 
Quote:
А ты сделай длину команды в 16 бит, а не в 8 - тогда всё влезет :)

Длинну кода операции или команды ))
65536 кодов... я уже вижу эти рекламные объявления "Very hard, very CISC"
Но у меня 14 входов в SRAM, совершенно некак дешифровать 2-байтные коды. Конечно было бы очень заманчиво сделать коды только 2- или 4-байтными, тогда код операции оказывался бы всегда в младщем байте, и не нужно было бы ничего мультиплексировать, но ведь память расходуется зря, а напрямую процессор сможет адресовать только 64 Кб. Так что лучше иметь и 1-, 2-, 3- и 4...

Так вот и вопрос, делать RISC or CISC?
RISC в этом случае это набор <= 256 инструкций.
Например все арифм. и логические операции только с аккумулятором,
что к тому же быстрее работает, т.к. не нужет 1 такт на сохранение результата, он по умолчанию защелкивается в АЛУ в аккумуляторе.

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

Пример:
1-й байт: код "сложить 2 16-бит регистра"
2-й байт: уточнение каких регистра

Дешифруется только 1-й байт, а затем микрокод "вытягивает" из второго нужную информацию. Работает медленно, т.к. в 1-м такте микрокод "разбирается" что ему делать, вместо того, чтобы уже выполнять работу.

Как вариант можно сделать быстрые однобайтные команды пересылки регистр-регистр, и арифм. с аккумулятором, при этом выравнивать их на ширину 2 байта.


21 Nov 2009 01:11
Profile
Fanat
User avatar

Joined: 24 Sep 2007 12:15
Posts: 63
Location: Украина
Reply with quote
Post 
А ну его!

"Пусть будут команды длинной только 2 или 4 байта!
Регистрам шестнадцатиразрядность и неделимость на младших и старших!
Регистрам равноправие, никаких аккумуляторов!
Больше рабочих мест -- обещаю увеличить колличество регистров до максимума!
Да, у нас нет умножения, но у нас есть сдвиги!
УРА!!!"
Мое популистское выступление перед рядами интергальных схем.

Quote:
буду городить 16-битный риск-процессор на мелкой логике


Есть где разгуляться программисту, в плане синтеза и разводки, или планируете использовать сторонние программы для этих целей?


21 Nov 2009 02:05
Profile
Admin
User avatar

Joined: 08 Jan 2003 23:22
Posts: 22409
Location: Silicon Valley
Reply with quote
Post 
danchandoo wrote:
Quote:
буду городить 16-битный риск-процессор на мелкой логике


Есть где разгуляться программисту, в плане синтеза и разводки, или планируете использовать сторонние программы для этих целей?


C compiler ;)

_________________
:dj: https://mastodon.social/@Shaos


21 Nov 2009 03:09
Profile WWW
Admin
User avatar

Joined: 08 Jan 2003 23:22
Posts: 22409
Location: Silicon Valley
Reply with quote
Post 
danchandoo wrote:
Quote:
А ты сделай длину команды в 16 бит, а не в 8 - тогда всё влезет :)

Длинну кода операции или команды ))
65536 кодов... я уже вижу эти рекламные объявления "Very hard, very CISC"
Но у меня 14 входов в SRAM, совершенно некак дешифровать 2-байтные коды.


ну операцию непосредственно кодировать несколькими битами, а остальное - номера вовлечённых регистров :)

Quote:
Так вот и вопрос, делать RISC or CISC?


по моему пониманию RISC будет быстрее работать и проще в реализации

_________________
:dj: https://mastodon.social/@Shaos


21 Nov 2009 03:10
Profile WWW
Fanat
User avatar

Joined: 24 Sep 2007 12:15
Posts: 63
Location: Украина
Reply with quote
Post 
Shaos wrote:
ну операцию непосредственно кодировать несколькими битами, а остальное - номера вовлечённых регистров


Да я вот тоже об этом подумал когда писал
Quote:
...добавить постфиксный байт, в код команды, уточняющий где брать операнды.


Этот постфиксный байт и состоит собственно из 2-х номеров регистров.
Однако и правда лучше отвести не байт, а 10 бит, тогда можно использовать
32 регистра! :rotate:
На коды операций останется 6 бит = 64 кода, должно хватить.

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


21 Nov 2009 08:32
Profile
Admin
User avatar

Joined: 08 Jan 2003 23:22
Posts: 22409
Location: Silicon Valley
Reply with quote
Post 
Сподвигли вы меня на великие размышления: http://www.nedopc.org/forum/viewtopic.php?t=9182

_________________
:dj: https://mastodon.social/@Shaos


21 Nov 2009 13:10
Profile WWW
Fanat
User avatar

Joined: 24 Sep 2007 12:15
Posts: 63
Location: Украина
Reply with quote
Post 
Немного подумал. За последнюю неделю много что изменилось в моих взглядах по поводу этого проекта.


Сверх глобально:
Не нужно бросаться в проработку деталей, если еще не подготовлена концепция задумки вцелом. Вот сделал я схему АЛУ, выложил, а вопрос зачем? В свете последних решений она не очень актуально. Разве-что в eagle попробовал работать...
Я понял, что делать что-то простое и легко воплотимое в жизнь, это "тупая" механическая работа. Это не мой путь, я поступлю иначе:

Глобально:

N16 CPU

Тип: RISC, что-то около берклийской архитектуры
Разрядность 16 бит.
Архитектура: гарвардская, запись данных в область памяти команд осуществляется внешними схемами.
Тактовая частота: ~20 МГц
Тактов на команду: около 2-х (для большинства)
Адресуемое пространство: 64К x 32 код, 64K x 16 данные.
Колличество регистров: 128 для каждой подпрограммы.
Всего видимых регистров 256 (еще 128 от вызывавшей подпрограммы, или той из которой произощел возврат)
Длинна команды: 32 бита, пусть будет. Из них:
- 1-й байт: код операции
- 2-й байт: регистр-источник1/приемник операнда из кода команды
- 3-й байт: регистр-источник2/младший байт операнда в кода команды
- 4-й байт: регистр-приемник/старший байт операнда в коде команды

Стек: встроенный 256 2-байтовых адресов возврата (может быть хоть 32 К адресов, но все ограничивается счетчиком-указателем стека -- он 8-ми разрядный).

АЛУ 16 разрядов. Поддерживаемые операции:
- бинарные: add, adc, sbb, sbc, and, or, xor;
- унарные: sal, rcl, not, neg, inc, dec. Возможно еще и: sar, rcr, ror, rol.

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


28 Nov 2009 12:44
Profile
Fanat
User avatar

Joined: 24 Sep 2007 12:15
Posts: 63
Location: Украина
Reply with quote
Post 
Основное направление -- повышение скорости, из-за чего вся логика по прежнему помещена в SRAM, однако никакой загрузки микрокода во время рестарта нет. SRAM используется как ROM, для чего процессор снабжен 4-мя батарейками АА (кто-нибудь знает сколько энергии, например, в mAh, может выработать батарейка? (нужно для рассчета как долго процессор протянет без внешнего питания)).

Одна команда за 2 такта:
1) макро-уровень:
- 1-й такт -- считывание (защелкивание команды в конце такта)
- 2-й такт -- декодирование, инкремент PC с одновременной выдачей
адресса следующей команды на шину.

2) микро-уровень. Для АЛУ все операции выполняются за 2 такта, что достигается конвееризацией:
Code:
|...|SL1|SH1|SL2|SH2|
|LL1|LH1|LL2|LH2|...|

Где:
LL1, LL2, LLN -- загрузить одновременно младшие 8 бит 1-го, 2-го, N-го операнда
SL1, SL2, SLN -- сохранить младшие 8 бит 1-го, 2-го, N-го результата
LHN, SHN -- загрузить и сохранить старшие 8 бит N-го операнда или результата

Это достигается тем, что мое 16-бит АЛУ строется из четырех 4-битных, объедененных в два 8-битных. Эти два 8-битных АЛУ и действуют соответственно над младшим и старшим байтами операндов.

Для одновременной подячи младших или старших частей операндов в АЛУ, число микросхем под регистры удваивается с 2 до 4-х. В тоже время запись ведется одновременно в оба блока регистров.

Есть проблема с логическими операциями действующими в "неприродном" направлении справа налево, например, со здвигами вправо. Это приводит к необходимости передачи значения флага переноса в 2-х направлениях между всеми 4-разрядными АЛУ. Кроме того необходимо сначала загрурать старшие байты операндов, что останавливает конвеер.
Кроме того есть "замечательные" циклические сдвиги без учета флага переноса. Чтобы их осуществить операнды должны присутствовать в АЛУ полностью, а не по частям. Например при rol загружаем сначала младшую часть, нужно делать сдвиг при котором младший бит старшего байта перейдет в старший бит загруженного младшего байта. Но где взять значение этого бита, если старшая часть не загружена в АЛУ? Вот из-за этого приходится загружать оба операнда целиком. Технически это возможно, но опять останавливает конвеер, а кроме того -- усложняет АЛУ.

Может и вовсе отказаться от вращений без флага переноса... Где они применяются? И хорошо бы отказаться от всех сдвигов вправо, но, боюсь, они все же нужны. Что думаете?


28 Nov 2009 13:18
Profile
Fanat
User avatar

Joined: 24 Sep 2007 12:15
Posts: 63
Location: Украина
Reply with quote
Post 
Ну и кратко о регистрах, стеке и процедурах.

Вызов подпрограммы приводит к тому что регистры вызывающе программы переходят в область 128-255, а доступные ей регистры располагаются от 0 до 127. Все параметры таки образом передаются через регистры. В стек ничего кроме адресов возврата поместить нельзя. Но думаю 128 2 байтных слов для параметров должно хватить.
При возврате все также. От 0 до 127 расположены регистры программы куда произошел возврат, от 128 до 255 регистры подпрограммы из которой произошел возврат, содержащие результат работы.
Один из регистров 0-127 нужно зарезервировать для сохранения флагов при прерывании (в стек значения флагов поместить нельзя).

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

Саможе переключение "окон" осуществляется крайне просто. Есть счетчик, который может как инкрементировать так и декрементировать свое значение -- указатель стека, и есть защелка, данные в которой фиксируются по сигналу инкремента/декремента счетчика. Значение в этой зашелке это значение указателя стека в n-1 такте. Тоесть при вызове это указатель на адресс вызывающей процедуры, а при возврате -- той из которой произошел возврат.
Старший бит номера используемого регистра как раз и выбирает, откуда брать адрес блока регистров: из этой защелки или из счетчика.
Вот и получается что там где старший бит = 1 (128--255) обращение идет к банку регистров функции чей адрес был в защелке, а там где он = 0 к банку, адрес которого сейчас на счетчике т.е. к банку регистров текущей, исполняемой процедуры.

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


28 Nov 2009 13:35
Profile
Admin
User avatar

Joined: 08 Jan 2003 23:22
Posts: 22409
Location: Silicon Valley
Reply with quote
Post 
А зачем блоками по 4(8) бит вычислять? Почему не сразу все 16?

И 2 такта на команду - выглядит черезчур оптимистично...

P.S. А вообще получилось очень похоже на мой дизайн - может нам объединить усилия? ;)

_________________
:dj: https://mastodon.social/@Shaos


28 Nov 2009 17:04
Profile WWW
Banned
User avatar

Joined: 20 Mar 2005 13:41
Posts: 2141
Location: От туда
Reply with quote
Post 
Любите вы все усложнять. Вот вам выдежржка из мегакнижки всех времен и народов (кликабельно):
Image
Image
Image


28 Nov 2009 23:17
Profile
Fanat
User avatar

Joined: 24 Sep 2007 12:15
Posts: 63
Location: Украина
Reply with quote
Post 
И чем я все усложнил?
Нету у меня К155ИП3. Вместо него микросхема памяти, которая выполняет точно теже функции. На ее адресные входы подаются 4-разрядные операнды, код операции и используемые флаги, 14 входов 32 К памяти на это хватает, а на выходе 4 бита результата и 4 новых значения флагов.
Сделать сразу 16-разрядное АЛУ из микросхем памяти нельзя! Входов не хватает:
2 операнда * 16 разрядов + 4 бита код операции + 1 флаг С = 37.

Единственным выходом является соединение 4 таких АЛУ в одно.

При этом флаг переноса из регистра флагов заходит в 1-е АЛУ, в каждое последующее заходит флаг переноса предыдущего (можно и флаг ноля тоже), с выходов 4-го АЛУ значения флагов считываются по окончанию операции.
Но так НЕЛЬЗЯ ДЕЛАТЬ СДВИГИ ВПРАВО. Чтобы это стало возможным нужно завести флаг С еще и в 4-е АЛУ, завести флаг С 4-го в 3-е и т.д. и сделать возможным его считывание из 1-го АЛУ, в общем проблема...

Quote:
А зачем блоками по 8 бит вычислять? Почему не сразу все 16?


Зачем 2 АЛУ относительно свободно работающих? Дело в том что задержка общая АЛУ будет равна суме задержек составляющих его 4-разрядных АЛУ т.е. около 15*4 = 60 нс. Если АЛУ "монолитное" то для операции при Т = 50нс потребуется 3 такта:
1) одновременная загрузка двух и операндов начало обработки
2) обработка
3) сохранение результата и флагов
Для 8-ми разрядных АЛУ задержка равна 2*15 = 30 нс, что позволяет осуществить конвеерную обработку, как показано на ранее приведеной диаграмме. В момент сохранения результата операции над младшими байтами, флаг этого результата защелкивается, и в следующем такте влияет на операцию над старшими, вто время как "младшее" АЛУ уже обрабатывает новые операнды.

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


29 Nov 2009 01:28
Profile
Display posts from previous:  Sort by  
Reply to topic   [ 33 posts ]  Go to page 1, 2, 3  Next

Who is online

Users browsing this forum: Google [Bot] and 12 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB® Forum Software © phpBB Group
Designed by ST Software.