Схематически может выглядить примерно вот так:

Проект сейчас начал переписываться с нуля и застрял на блоке контроля шины.
Так, не совсем ясно, как реализовать обработку WAIT, BUSRQ, INT. С RESET более-менее разобрался.
Процессор не сразу сбрасывается по приходу RESET. Необходимо выждать некоторое время. Так как предусмотрен системный регистр-счётчик ___ss, первый байт которого подсчитывает, сколько операций выполнилось с момента прихода RESET. Программа может предотвратить перезагрузку, обнуляя счётчик.
Вычисления
В CLŒVER нету встроенного универсального АЛУ и все вычисления должны производиться на уровне периферии.
Для работы с внешними вычислителями выделен псевдо-стек с ячейками:
____0 -> Id:07777777700 -> hexId:0x3FFFFFC0 -> Vector:0xFFFFFF00
____1 -> Id:07777777701 -> hexId:0x3FFFFFC1 -> Vector:0xFFFFFF04
____2 -> Id:07777777702 -> hexId:0x3FFFFFC2 -> Vector:0xFFFFFF08
____3 -> Id:07777777703 -> hexId:0x3FFFFFC3 -> Vector:0xFFFFFF0C
____4 -> Id:07777777704 -> hexId:0x3FFFFFC4 -> Vector:0xFFFFFF10
____5 -> Id:07777777705 -> hexId:0x3FFFFFC5 -> Vector:0xFFFFFF14
____6 -> Id:07777777706 -> hexId:0x3FFFFFC6 -> Vector:0xFFFFFF18
____7 -> Id:07777777707 -> hexId:0x3FFFFFC7 -> Vector:0xFFFFFF1C
____8 -> Id:07777777710 -> hexId:0x3FFFFFC8 -> Vector:0xFFFFFF20
____9 -> Id:07777777711 -> hexId:0x3FFFFFC9 -> Vector:0xFFFFFF24
Десять внешних регистров дешифратором подключаются по указанным векторам...
Служебные регистры:
___pp -> Id:07777776060 -> hexId:0x3FFFFC30 -> Vector:0xFFFFF0C0 // Program Pointer
___ql -> Id:07777776154 -> hexId:0x3FFFFC6C -> Vector:0xFFFFF1B0 // Block Length
___qp -> Id:07777776160 -> hexId:0x3FFFFC70 -> Vector:0xFFFFF1C0 // Block Pointer
___qs -> Id:07777776163 -> hexId:0x3FFFFC73 -> Vector:0xFFFFF1CC // Block Stack
Таблица кодирования вектора по имени или выражению:
Например:
Оператор "+=" имеет код 0x00BD. Оператор "-=" - код 0x009D.
Вектор "DEBUG" имеет адрес 01516132573₈
Хотя, реально, принцип кодирования операторов несколько сложее. Так, первые три ниббла слова несут информацию об арифметических знаках. Но последний ниббл несёт информацию об операндах. Так, есть ли операнды слева или справа (унарная операция или бинарная) указывается в первых двух битах ниббла. Третий бит - имеет ли место присвоения. Четвёртый - обратная операция.
Тем самым, получается примерно следующее:
0x1007 -> ^y;
0x2007 -> x^;
0x3007 -> x^y;
0x5007 -> ^=y;
0x6007 -> x^=;
0x7007 -> x^=y;
0x9007 -> ^x;
0xA007 -> y^;
0xB007 -> y^x;
0xD007 -> ^=x;
0xE007 -> y^=;
0xF007 -> y^=x;
И позволяет кодировать операторы до четырёх символов длиной (x>>>y - 0x3EEE; x<<<=y - 0x7CCC). Конечно, первые 12 бит используются реально внешними устройствами обработки. Тогда как старшие 4 бита нужны для внутреннего дешифратора для корректной работы с операндами. Тем самым, используется всего до 4096 слов таблицы операторов, хранящей векторы обрабатывающих устройств.
Синтаксис несколько своеобразен. Хотя похож и на Python табулированием блочных операций. Специальных символов под комментарии нет и используется знак табуляции. Так, знаки табуляции в начале строки указывают на уровень вложенности блочных операций. Но, знаки табуляции после - обозначают комментарий. Например:
↵Label→Remark
↵→Main expressions→Remark
↵→→Nested expressions→Remark
↵→ →Remark
↵ →Remark
К тому же, предусматривается вставка служебным комментарий, подобно #-операторам препроцессора Си. Куда сам процессор сможет записывать служебную информацию для ускорения последующего исполнения определённых кусков кода. Например:
↵Label→Remark
↵→Main expressions→Remark
↵→→___ql=23→Size of nested block (start - '↵' symbol)
↵→→Nested expression...
⟝⟶
😶ꕁ😦ᓩ⍨ᓤﺕﺖ
Перевод строки - классические 0x0D + 0x0A, табуляция - 0x09.
Так, 0x0D - может быть командой на исполнение текущей конструкции. А 0x0A - командой сброса статуса конструкции.
Код 0x09 - инкремент счётчика вхождения в блок инструкций.
Технически, расстояние между 0D и 0A не критично и может быть любым. В частности, для служебной информации процессора. Вопрос лишь в том, что обычный текстовый редактор не сможет верно отобразить листинг. К чему я стремился с момента старта идеи.
На текущий момент всё заморозилось.
Нет достаточно ясных набросков некоторых ключевых моментов задумки.
Сейчас планируется ввести дополнительные 10 регистров управления векторами доступа в память.
В частности, если сначала задумывал 1x - как *(BYTE *)x, а 4y - *(DWORD *)y. То сейчас конструкцию 1x можно интерпретировать как использование 1-го регистра описания доступа к ресурсам через x.
Все те десять регистров можно гибко настраивать на доступ к памяти, к стеку, реализации SIMD-вычислений и пр...
Дело в том, что решение имеется, но ничего конкретно не ясно. Я - всего лишь любитель, а не инженер... Тут нужна коллективная работа, советы и предложения...
#Parser, #Processor, #Verilog
15 сентября 2012
(Обновление: 26 дек 2014)
Комментарии [1]