nedoPC.org

Community of electronics hobbyists established in 2002

...
Atom Feed | View unanswered posts | View active topics It is currently 28 May 2020 12:04



Reply to topic  [ 6 posts ] 
RISC процессор с интуитивно понятным машинным кодом 
Author Message
Maniac
User avatar

Joined: 12 Apr 2011 21:43
Posts: 209
Location: Tashkent
Reply with quote
Давнo волновала мысль о реализации процессора с интуитивно прозрачной системой команд.
Так, x80 задумывался мною как нечто среднее между z80 и i8086. Но CISC довольно сложна в освоении реализации и там я наткнулся на множество подводных камней, хотя первые шаги и сделал.

Решил наконец перешагнуть через некоторые свои принципы и заняться RISC всерьёз.
А именно, сделать набросок простого (не простейшего) процессора, но с оригинальной системой команд и интуитивно ясным байт-кодом, чтобы не нужно было зубрить таблицу системы команд.
И я нашёл достаточно оригинальный вариант…

Мой подход максимально прост: Шестнадцатиричный код инструкции и является мнемоникой команды.

Code:
Bytes|Assm | Краткое описание
----- ----- ------------------
00    HALT - Куда без неё?
01…99 1…99 - Шестнадцатиричные цифры используются как десятичные
0A…0F ALU  - 0xA:Add; 0xB:suB; 0xC:Conjunction (AND); 0xD:Disjunction (OR); 0xE:Eor; 0xF:Flags (CMP)
A1…A9 A1…9 - Выбор одного из девяти регистров A
B1…B9 B1…9 - Выбор одного из девяти регистров B
C1…C9 C1…9 - Выбор одного из девяти регистров C
AA…CC R,T  - Выбор пары приёмник-источник (Receiver,Translator pair)
AD    ADDR - Фиксация значений приёмника-транслятора в регистре адреса
BE    BE   - Чтение из буфера памяти (Buffer Extract)
BF    BF   - Запись в буфер памяти (Buffer Flush)
DA…DF DA…F - Skip 1 Instruction by: Amount; Bigger; Carry; Dis-Carry; Equal; False
EB    EB   - Execute Buffer (Jump to Buffer Address)

С помощью ПЗУ объёмом в 256 байтов с асинхронным доступом можно легко прошить всю таблицу дешифратора команд, в которую также входят 99 ячеек перевода двоично-десятичных представлений кодов.

Сначала схему я строил в Atanua, но потом перешёл в Logisim, так как он удобнее в работе с шинами. За неделю мне удалось набросать более-менее приличную схему, если сравнивать с предыдущим безобразием из путаницы проводников и логики по всему экрану. Сейчас выглядит схема более приличнее и многое расположено гораздо ровнее, чем было в первых вариантах.
А главное - это работает.
Самым сложным моментом было разработка узла чтения/записи памяти, так как первый вариант был аналогичным Гарвадскому. Теперь набор вентилей и сдвиговый регистр выполняют нормальный Принстонский функционал, на отладку которого ушло несколько ночей. Думаю, опыт пригодится в моём x80, когда руки дойдут до него.

Как это работает…
Можно из схемы заметить, что значительную часть составляет регистровый файл.
Конечно, можно было использовать готовый элемент памяти, но схему я разрабатывал так, чтобы можно было на ТТЛ всё собрать при возможности.
В Logisim все дешифраторы выдают активную логическую единицу, тогда как подавляющее большинство физических микросхем активным используют логический ноль.

Всего данный процессор способен выполнить пока 140 инструкций.
И на данный момент АЛУ имеет только функцию сумматора под кодом операции 0A, так как пока нет нужды во всех операциях. Хотя, как и в x80, операции будут те же…
(0A:Add, 0B:suB, 0C:Conjunction/AND, 0D:Disjunction/OR, 0E:Eor, 0F:diFference/CMP)

Например:
Code:
0000 BA ; Выбор пары B,A
0001 B9 ; Выбор регистра B9
0002 64 ; Загрузить десятичное 64 (0x40) в регистр B9
0003 CB ; Выбор пары C,B
0004 C8 ; Выбор регистра C8
0005 30 ; Загрузить десятичное 30 (0x1E) в регистр C8
0006 AD ; Поместить в указатель адреса значения C8 и B9: Addr = (C8 << 8) | B9
0007 A1 ; Выбор регистра A1
0008 AB ; Выбор пары AB
0009 BE ; Прочитать память и сохранить данные: A1 = [Addr] или A1 = [0x1E40]
000A 00 ; Останов
Если вдуматься, то реализация процессора получилась почти полной по Тьюрингу.
Реализовать стек программно теоретически возможно уже сейчас.

Code:
0000 A9 ;     A9  ; Чтобы организовать цикл, нужно настроить указатель
0001 B9 ;     B9  ; Выбираем регистры A9 B9
0002 AA ;     A,A ; Эти аргументы помогут очистить регистр A9
0003 0E ; EOR     ; (EOR A9,A9) посредством Исключающего ИЛИ
0004 BA ;     B,A ; Теперь загрузим адрес единственной метки
0005 16 ;      16 ; Сейчас B9,A9 имеют значения 0x10,0x00
0006 AB ;     A,B ; Формируем корректный адрес: 0x00,0x10
0007 AD ; ADDRESS ; Загружаем в указатель буфера 0x0010 из A9,B9
0008 A8 ;     A8  ; Теперь настроим регистры для циклического счёта
0009 B8 ;     B8  ; A8 будет счётчиком, а B8 будет хранить предел
000A AA ;     A,A ; Очистим будущий счётчик
000B 0E ; EOR     ; (EOR A8,A8) традиционным способом
000C BA ;     B,A ; Чтобы загрузить B8, нужно выбрать аргументы
000D 99 ;      99 ; (MOV B8,99) Теперь B8 == 0x63
000E B1 ;     B1  ; Здесь будет храниться шаг инкремента
000F 01 ;      1  ; (MOV B1,1)
0010 ;;;;         ; Этот адрес мы указали в начале программы - прошло 32 такта
0010 AB ;     A,B ; Указываем порядок аргументов
0011 A8 ;     A8  ; Чтобы обеспечить инкремент
0012 B1 ;     B1  ; как A8 += B1
0013 0A ; ADD     ; (ADD A8,B1)
0014 B8 ;     B8  ; Регистр предела
0015 0F ; CMP     ; (CMP A8,B8) Операция сравнения
0016 DC ; DC      ; (Do if Carry) Операция проверки флага переноса
0017 EB ;  EB     ; Если переноса нет, эта команда (Execute Buffer) будет пропущена - 16 тактов + 2
0018 00 ; HLT     ; Останов - всегда 2 такта
В этой программе на каждую инструкцию уходит по 2 такта (4 полупериода ручным кликом), за исключением условной DC, которая требует 4 такта для холостого инкремента указателя инструкций при завершении цикла. Тем самым, на всю программу потребуется 2*16+99*(2*8)+2+2


Attachments:
File comment: Текущий вариант процессора с программой Hello World!
cpu_risc.png
cpu_risc.png [ 93.7 KiB | Viewed 1389 times ]
logisim-risc_cpu.zip [13.21 KiB]
Downloaded 56 times


Last edited by Paguo-86PK on 25 May 2020 10:27, edited 3 times in total.

14 Mar 2019 05:10
Profile WWW
Doomed

Joined: 01 Oct 2007 11:30
Posts: 510
Location: Ukraine
Reply with quote
Ничего не понял (надо думать). Это вам надо R800 (MSX) курить? на базе Z80(Z280).

_________________
Эмулятор OrionEXT:
http://www.orion-ext.narod.ru


14 Mar 2019 07:34
Profile
Admin
User avatar

Joined: 09 Jan 2003 00:22
Posts: 18586
Location: Silicon Valley
Reply with quote
Логисим не глючит от такой большой схемы?

_________________
:eugeek: https://twitter.com/Shaos1973


14 Mar 2019 14:32
Profile WWW
Maniac
User avatar

Joined: 12 Apr 2011 21:43
Posts: 209
Location: Tashkent
Reply with quote
Первопoст обновил…
Добавил в схему все 6 операций АЛУ, флаговый регистр и инструкции условного исполнения.
Теперь есть операция загрузки указателя инструкций.

Очень любопытно, смогу ли я написать что-нибудь практическое?
Типа, Тетриса или простейшую BIOS-заставку…
Shaos wrote:
Логисим не глючит от такой большой схемы?
Когдa пытался сделать большой экран 320x192, симуляция часто подвисала и приходилось LogiSim закрывать через диспетчер задач.
Если развёртку делать последовательно по всем панелям, то период их обновления очень велик.
Потому я на каждую панель выделил отдельное ОЗУ и устал разводить шины плексеров.
Отдельное ПЗУ отвечает за линейный доступ к ячейкам всего дисплея, чтобы все 7680 ячеек не имели всяких фокусов с дешифрацией при доступе к ним.

Но весь труд себя не оправдал - симуляция через какое-то время зависает…


Attachments:
File comment: Большой экран
BigScreen.png
BigScreen.png [ 138 KiB | Viewed 1427 times ]
14 Mar 2019 17:55
Profile WWW
Maniac
User avatar

Joined: 12 Apr 2011 21:43
Posts: 209
Location: Tashkent
Reply with quote
Рeшил набросать схему контекстного файла - Logisim сильно тормозить стал.
Да и тактовый вход забыл вывести, как потом заметил…

Короче, должна быть схема памяти с четырьмя портами.
Но для Logisim это очень тяжело, оказывается…
Нужно что-то иначе делать…


Attachments:
File comment: Модуль файла контекста
Context.gif
Context.gif [ 76.27 KiB | Viewed 1320 times ]
File comment: Регистровый файл:
Порт #1 - 8-битовый операнд R(eceiver) и аккумулятор
Порт #2 - 8-битовый операнд T(ranslator)
Порт #3 - 2 8-битовых регистра (в том числе IP/BX/CX/DX/SP/BP/SI/DI)
Порт #4 - 2 8-битовых регистра страницы памяти

x80_context.png
x80_context.png [ 424.55 KiB | Viewed 1321 times ]
21 Mar 2019 16:35
Profile WWW
Maniac
User avatar

Joined: 12 Apr 2011 21:43
Posts: 209
Location: Tashkent
Reply with quote
Всe эти дни я усердно скрипел мозгами и дорабатывал схему процессора собственной RISC-архитектуры. Полностью перерисовывал её несколько раз и она в малом масштабе выглядит достаточно симпатично. Правда, из-за не совсем удачного расположения блоков АЛУ и Выборки довольно много проводов и шин опоясывает всю схемы. Потому, можно добиться в перспективе более аккуратного вида.

Упростил процессор до предела в рамках выбранной концепции, упразднив некоторые инструкции и упростив доступ к памяти. Появилась возможность расширения системы команд программными процедурами по адресам E000…FF00.
Теперь основных групп команд сократилось до девяти, включая группу АЛУ. Тем самым, если операции АЛУ вынести напрямую к дешифратору, то потребуется всего один типа ИД3…

Вся схема выполнена в строгом синхронном стиле и легко должна ровно лечь в Verilog и FPGA.

Регистровый файл расширен с трёх до четырёх групп регистров общего назначения.
Четвёртая D-группа представляется внешними устройствами - Devices, что позволяет обращаться к устройствам типа клавиатура или джойстик непосредственно и в скором порядке, как кэш-периферия первого уровня с мгновенным доступом. Более медленные устройства требуется проецировать в адресное пространство памяти.

Тем самым, процессор теоретически пригоден для построения любого автомата, типа «Ну, Погоди!», «Тетриса» или «Лунохода».

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

------------------------------------------------------------------------------
|Код команд / диапазоны|Группа    |Описания, замечания, комментарий
-----------------------|----------|-------------------------------------------
00                     |HLT       |Прекращение счёта указателем команд IP
01-99                  |ADD Ri,BCD|Двоично-десятичное накопление в регистр
0A-9F                  |ALU Ri,Tk |Операция АЛУ с комбинацией аргументов
A0-A9 B0-B9 C0-C9 D0-D9|REG Rn    |Установка индекса активного регистра группы
AA-AD BA-BD CA-CD DA-DD|ARG Ri,Tj |Выбор комбинации аргументов операциям АЛУ
AE    BE    CE    DE   |EXT Ri    |Экстракция данных из внешнего ОЗУ в регистр
AF    BF    CF    DF   |FIX Ri    |Фиксация значения регистра во внешнее ОЗУ
E0-E7                  |EX0-7     |Переход на адрес 0xE000-0xE700
E8-EF                  |Ecnd      |Выполнение следующей команды по условию
F0                     |FIN       |Завершение с переходом на адрес Базы:Счёта
F1-FF                  |FN1-15    |Переход на адрес 0xF000-0xFF00
------------------------------------------------------------------------------
(n - устанавливаемый индекс, указанный битами команды)
(i или j - индекс, установленный раннее)
(k - индекс регистра временно берётся из старшего ниббла кода команды)

Группы регистров A0-A9, B0-B9 и C0-C9 составляют внутренний регистровый файл с
безусловным доступом к ним на программном уровне. Регистры B0-B9 хранят "Базу"
для обращения к памяти блоком в 256 байт, а регистры C0-C9 - счёт байта блока.
Инструкция с кодом F0 помещает текущий адрес указателя инструкций из IP в B0 и
C0, а значения из Bi и Cj помещает в IP, производя переход на адрес Bi:Cj. Тем
самым, можно обращаться к коду подпрограмм и знать адрес возврата через B0:C0.

Группу регистров D0-D9 составляют внешние Device-устройства с непосредственным
использованием в качестве операндов. Не рекомендуется активно использовать эту
группу в любых вычислительных действиях, так как нет гарантии работы программ.
Тем самым, как любитель Hex-кода, разработал вполне работоспособную архитектуру, которая не требует даже ассемблера и позволяет в голом дампе набивать машинный код, визуально прозрачный к пониманию.

Есть соблазн упразднить ПЗУ разметки карты команд и заменить его на комбинаторику. Правда, не уверен, оправдает ли это себя…

P.S.: Пожалуй, это - самый удачный из всех моих проектов данного класса.


Attachments:
File comment: Снимок схемы для ознакомления
x80_RISC.png
x80_RISC.png [ 166.82 KiB | Viewed 67 times ]
File comment: LogiSim-схема и HTML-дизассемблер
x80_RISC_20200525.zip [25.34 KiB]
Downloaded 2 times
25 May 2020 10:25
Profile WWW
Display posts from previous:  Sort by  
Reply to topic   [ 6 posts ] 

Who is online

Users browsing this forum: No registered users and 2 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.