4-bit Processor

4-битные микроконтроллеры и микропроцессоры (прошлое, настоящее, будущее)

Moderator: Lavr

b2m
Devil
Posts: 905
Joined: 26 May 2003 06:57

Re: RAM Data

Post by b2m »

Lavr wrote:Далее - при работе 4 бита поступают как данные на внутреннюю шину данных - в АЛУ или регистры.
12 бит инструкции поступают на ПЗУ микрокоманд и всякие дешифраторы кода.
Не совсем понял, почему адрес данных всегда совпадает с адресом команд.
Lavr wrote:Немного изменив схему, я могу заставить её в одну из RAM обратно записать 4 бита данных через шину данных (правда испорчу 4 бита кода операции, но кода, может, и 8 бит хватит).
Я предполагал, что после чтения кода операции будут выполнены несколько микрокоманд, которые установят шину адреса ОЗУ данных и шину адреса команд. В случае RST они наверное совпадут, но не в случае других команд.

А схемы я не рисую :)

Выполнение команды RST n
data[n]=PC; PC=code[n];

и RET n
PC=data[n];
Страничка эмулятора наших компьютеров
http://bashkiria-2m.narod.ru/
User avatar
Lavr
Supreme God
Posts: 16680
Joined: 21 Oct 2009 08:08
Location: Россия

Re: RAM Data

Post by Lavr »

b2m wrote:
Lavr wrote:Далее - при работе 4 бита поступают как данные на внутреннюю шину данных - в АЛУ или регистры.
12 бит инструкции поступают на ПЗУ микрокоманд и всякие дешифраторы кода.
Не совсем понял, почему адрес данных всегда совпадает с адресом команд.
Ну вот такая у нас простота конструкции... однофазная синхронизация... трудное децтво... диривяные игрушки... :D
Если я не путаю - в PIC-e тоже так, поэтому я и назвал прототип - "Stupid PIC"! :wink:

Схему я не просил рисовать - имелось ввиду "глядя на схему", а то абстрактно обсуждать трудно...
b2m wrote:Я предполагал, что после чтения кода операции будут выполнены несколько микрокоманд, которые установят шину адреса ОЗУ данных и шину адреса команд.
Неее... :cry: Данные - сразу на шину данных внутреннюю, КОП - на дешифраторы и ПЗУ микрокоманд.
Счётчик перебирает младшие адреса ПЗУ микрокоманд, организуя все внутренние сигналы управления.

Но КОП+Данные поступают всегда одновременно. Слово программы по сути 16-битное.

Поэтому я и ввёл CMA как XOR 0FH - всё равно данные поступают...
И обнуления регистров отдельно не делал - всё-равно, что 0 из данных загружать.

Но разве это на систему PIC не похоже?

Image

Почти все комнды - за 1 машинный цикл. Ну у нас - также...
Только переходы - в два цикла РС перезаписать.
b2m
Devil
Posts: 905
Joined: 26 May 2003 06:57

Re: RAM Data

Post by b2m »

Lavr wrote:Но разве это на систему PIC не похоже?
У PIC-а адрес данных не совпадает с PC, а является частью команды, IMHO. Похоже только на команды, работающие с литералами.
Страничка эмулятора наших компьютеров
http://bashkiria-2m.narod.ru/
User avatar
Lavr
Supreme God
Posts: 16680
Joined: 21 Oct 2009 08:08
Location: Россия

Re: RAM Data

Post by Lavr »

b2m wrote:
Lavr wrote:Но разве это на систему PIC не похоже?
У PIC-а адрес данных не совпадает с PC, а является частью команды, IMHO. Похоже только на команды, работающие с литералами.
Согласен, но мы и не ставим задачей повторить PIC, но позаимствовать решения у него можно.
В частности "короткие" JMP-пы по условию точно надо взять - очень легко реализуются аппаратно.
Длинные JMP-пы тоже можно использовать, как загрузку РС в два приёма нибблами...

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

А память данных - как набор регистров, похоже, придётся делать на РУ2. Других вариантов пока не вижу.
User avatar
Lavr
Supreme God
Posts: 16680
Joined: 21 Oct 2009 08:08
Location: Россия

Post by Lavr »

b2m wrote:...
Если вложенность подпрограмм минимальна, то для адреса возврата можно сделать регистр. Но тогда подпрограмма не сможет вызывать другую подпрограмму.
...
Поскольку PC предполагается 8-битным, плюс 4-битный переключатель страниц, то для 1-уровневого стека понадобятся либо 3 корпуса 4-битных регистров, либо 2 корпуса - 8-битный и 4-битный регистры.
Это ещё аппаратно приемлемо...
Если глубину вложений увеличивать, то число корпусов умножается на глубину.

Поскольку разместить стек в памяти программ простой возможности пока не вижу, а в памяти регистров места практически нет.
В качестве РОН К155РУ2 - это всего 16 4-битных регистров.

Формат 8-битной команды:
KKKKDDDD, где KKKK-КОП, DDDD-данные (литера или номер регистра) не даёт возможности и число регистров увеличить более 2^4=16.

Если KKKK = 1111 (0Fh), то это префикс. Тогда DDDD - интерпретируются также как КОП однониббловой команды без аргумента типа NOP, RRC, RAL, и т.д.

Одноуровневый стек видел только у TI TMS1000. Сейчас пытаюсь посмотреть программы для TMS1000 - сколь они эффективны с 1-уровневым стеком. :roll:
Согласно мануалу - TMS_1000_Data_Manual.pdf, работать вобщем-то можно... но у TMS1000 ячеек ОЗУ побольше, чем 16...

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

PS. Чисто для сравнения:

Intel 4004 - 4-х уровневый стек;
Intel 4040 - 8-и уровневый стек;
PIC16F8x - 8-и уровневый стек;
Intel 8048 - 8-и уровневый стек.
b2m
Devil
Posts: 905
Joined: 26 May 2003 06:57

Post by b2m »

Lavr wrote:Поскольку разместить стек в памяти программ простой возможности пока не вижу, а в памяти регистров места практически нет.
В качестве РОН К155РУ2 - это всего 16 4-битных регистров.
Если у тебя шина адреса 8-ми разрядная и ты предполагаешь доступ к данным по адресу в регистрах, то надо бы подумать о регистровых парах. Проще всего поставить две К155РУ2, одну для чётных, другую для нечётных регистров. Но тогда будет 32 регистра.

А если будет команда перехода по адресу в регистрах, то стек возвратов можно будет реализовать программно. Например вызов подпрограммы в пределах одной страницы:

Code: Select all

  MOV R0,LOW RETADDR1 ; загружаем в пару R0,R1 адрес возврата, это константа
  MOV R1,MID RETADDR1 ; возможно будет отдельная команда для загрузки пары
  MOV R2,LOW CALLADDR1 ; аналогично для адреса п/п
  MOV R3,MID CALLADDR1
  JMP CALLPROC
RETADDR1:
Код CALLPROC должен будет поместить R1,R0 в стек (например по адресу R14,R15) и сделать переход на R3,R2

Аналогично можно сделать RETPROC.
Last edited by b2m on 04 Nov 2011 07:11, edited 3 times in total.
Страничка эмулятора наших компьютеров
http://bashkiria-2m.narod.ru/
User avatar
Lavr
Supreme God
Posts: 16680
Joined: 21 Oct 2009 08:08
Location: Россия

Post by Lavr »

b2m wrote:
Lavr wrote:Поскольку разместить стек в памяти программ простой возможности пока не вижу, а в памяти регистров места практически нет.
В качестве РОН К155РУ2 - это всего 16 4-битных регистров.
Если у тебя шина адреса 8-ми разрядная и ты предполагаешь доступ к данным по адресу в регистрах, то надо бы подумать о регистровых парах. Проще всего поставить две К155РУ2, одну для чётных, другую для нечётных регистров. Но тогда будет 32 регистра.

А если будет команда перехода по адресу в регистрах, то стек возвратов можно будет реализовать программно. Например вызов подпрограммы в пределах одной страницы:

Code: Select all

  MOV R0,LOW RETADDR1 ; загружаем в пару R0,R1 адрес возврата, это константа
  MOV R1,MID RETADDR1 ; возможно будет отдельная команда для загрузки пары
  MOV R2,LOW CALLADDR1 ; аналогично для адреса п/п
  MOV R3,MID CALLADDR1
  JMP CALLPROC
RETADDR1:
Код CALLPROC должен будет поместить R1,R0 в стек (например по адресу R14,R15) и сделать переход на R3,R2

Аналогично можно сделать RETPROC.
Lavr wrote:Формат 8-битной команды:
KKKKDDDD, где KKKK-КОП, DDDD-данные (литера или номер регистра) не даёт возможности и число регистров увеличить более 2^4=16.
Я аппаратно не имею возможности выбрать более 2^4=16 регистров.
Если их сделать сдвоенными, вторые половины мне просто будут недоступны программно....
Lavr wrote:Поскольку PC предполагается 8-битным, плюс 4-битный переключатель страниц, то для 1-уровневого стека понадобятся либо 3 корпуса 4-битных регистров...
Шина адреса 8-ми разрядная - непосредственно адресует блок в 256 байт памяти программ. Блоки по 256 байт переключает 4-битный переключатель страниц.
То есть в стек надо загнать 12 бит адреса возврата.
Это никак не сохранить даже в сдвоенных регистрах, тем более этого нет в том, что ты предлагаешь...

Code: Select all

  MOV R0,LOW RETADDR1 ; загружаем в пару R0,R1 адрес возврата, это константа
  MOV R1,MID RETADDR1 ; возможно будет отдельная команда для загрузки пары
Это только 8 бит... куда деть ещё 4 бита переключателя страниц?

Поскольку условные переходы у нас короткие, то безусловные JUMP и CALL должны быть длинными - межстраничными, как и возвраты из вызовов.
Last edited by Lavr on 04 Nov 2011 07:32, edited 1 time in total.
b2m
Devil
Posts: 905
Joined: 26 May 2003 06:57

Post by b2m »

Тут, кстати, пригодилась бы система рестартов, потому как для команды JMP надо делать 4х-битный регистр страницы, в котором будут старшие 4 бита адреса перехода и менять этот регистр для вызова "дальних" версий CALLPROC и RETPROC нежелательно. А рестарт будет всегда прыгать на нулевую страницу, независимо от этого регистра.

А если команда рестарта будет ещё и регистровую пару загружать... Например, полезно для номера функции (пусть даже это будет фиксированная пара R0,R1), или как в данном случае - "ближний" адрес. То будет вообще шоколадно :)

К примеру, обычная коротенькая п/п (рестарт) будет использовать R1,R0 как адрес возврата, и заканчиваться будет JMP R1R0, т.е. коротким переходом на текущую страницу, откуда мы, предположительно, и вызвали рестарт.

Но вообще, в таком случае, проще сделать так, чтобы команда рестарта заносила в R1R0 младшие биты PC, это подойдёт и для вызова CALLPROC.
Страничка эмулятора наших компьютеров
http://bashkiria-2m.narod.ru/
b2m
Devil
Posts: 905
Joined: 26 May 2003 06:57

Post by b2m »

Lavr wrote:Это только 8 бит... куда деть ещё 4 бита переключателя страниц?
Я думал, предполагался регистр текущей страницы. Тогда можно обойтись одной командой JMP и для дальних вызовов, и для ближних.

Т.е. дальний переход выглядел бы так:

Code: Select all

MOV PAGEREG, HIGH LBL123 ; старшие 4 бита
JMP LBL123 ; используются только младшие 8 бит
Страничка эмулятора наших компьютеров
http://bashkiria-2m.narod.ru/
User avatar
Lavr
Supreme God
Posts: 16680
Joined: 21 Oct 2009 08:08
Location: Россия

Post by Lavr »

b2m wrote:Тут, кстати, пригодилась бы система рестартов, потому как для команды JMP надо делать 4х-битный регистр страницы, в котором будут старшие 4 бита адреса перехода и менять этот регистр для вызова "дальних" версий CALLPROC и RETPROC нежелательно.
...
Может быть я неудачно придумал дальние безусловные JUMP и CALL?

Я их решил реализовать так: если 8-битная команда:
KKKKDDDD, где KKKK-КОП, DDDD-данные (литера или номер регистра), то DDDD - подключены к внутренней 4х-битной магистрали, а KKKK - к памяти микрокоманд.

Аппаратно 4х-битный регистр страницы подключен к внутренней 4х-битной магистрали,
PC_Low - подключен к внутренней 4х-битной магистрали,
а вот PC_High к ней не подключен.

При выполнении JUMP и CALL:
KKKK-JUMP или CALL,
DDDD - 4х-битный регистр страницы .
после выборки КОПа JUMP или CALL программный счётчик PC автоматом аппаратно увеличивается на 1 и во время выполнения КОПа указывает уже на следующий KKKKDDDD.
DDDD сразу защёлкиваем в 4х-битный регистр страницы
А вот во время выполнения КОПа можно защелкнуть DDDD - в PC_Low, а KKKK - в PC_High, причём одновременно, поскольку PC_High должен быть аппаратно подключен входами к линиям KKKK - это никак не мешает обычной работе.

После чего снова делаем инкремент PC.

Инкремент PC происходит аппаратно, т.к. PC_Low и PC_High - это два счётчика с предзагрузкой, включенные последовательно.

1-уровневый стек, я хотел реализовать аппаратно защёлкивая состояния PC_Low, PC_High и 4х-битный регистр страницы в отдельные 4х-битные регистры одновременно и параллельно.
b2m
Devil
Posts: 905
Joined: 26 May 2003 06:57

Post by b2m »

Lavr wrote:Может быть я неудачно придумал дальние безусловные JUMP и CALL?
...
1-уровневый стек, я хотел реализовать аппаратно защёлкивая состояния PC_Low, PC_High и 4х-битный регистр страницы в отдельные 4х-битные регистры одновременно и параллельно.
Я пытаюсь придумать, как можно сделать многоуровневый стек. В конце концов можно дать программный доступ к этим 3-м регистрам, но это сильно усложняет конструкцию.

Но начал я совсем с другой темы: как удобнее адресовать данные через регистры. Если оставить одну К155РУ2, то адрес будет выдаваться за два такта, нельзя ведь выдать одновременно два регистра. К тому-же придётся ставить дополнительный 4-х битный регистр для старших битов адреса.
Страничка эмулятора наших компьютеров
http://bashkiria-2m.narod.ru/
User avatar
Lavr
Supreme God
Posts: 16680
Joined: 21 Oct 2009 08:08
Location: Россия

Post by Lavr »

b2m wrote: Я пытаюсь придумать, как можно сделать многоуровневый стек. В конце концов можно дать программный доступ к этим 3-м регистрам, но это сильно усложняет конструкцию.
Да и я бы хотел сделать многоуровневый стек. :wink:
Но как не кручу - это действительно сильно усложняет конструкцию. :cry:

И возвраты в 0-страницу придумывал, чтобы регистр страниц просто сбрасывать в 0 аппаратно при возврате... :oops:
Раздельно PC_Low, PC_High аппаратно манипулировать проще, это всего лишь
завести их входы на внутреннюю магистраль данных, а вот регистр страниц всё усложняет...

Но всего 256 байт памяти программ, как в прототипе, - это тоже некавайно.
Добавив регистр страниц, я хоть приемлемые 4096 байт выкрутил...

PS. Со стеком пытаюсь взять пример как с PIC-a, так и с ранних 4-битников. У всех них стек отдельный,
ограниченный и программно-недоступный.
TMS1000 с 1 ячейкой стека на 1 вызов в этом смысле - аппаратный предел.
:wink:

PPS. Вся абурдность ещё и в том, что ОЗУ, как таковое у нас есть, но выполняет роль ПЗУ программ.
На запись доступно с пульта, а программно на запись - недоступно.
Вот и подмывает адреса возврата и стек засунуть как-то в это "ОЗУ программ", хотя бы в 0-страницу...
или в вершину...
User avatar
Lavr
Supreme God
Posts: 16680
Joined: 21 Oct 2009 08:08
Location: Россия

Post by Lavr »

Lavr wrote:
TMS1000 с 1 ячейкой стека на 1 вызов в этом смысле - аппаратный предел.
:wink:

PPS. Вся абурдность ещё и в том, что ОЗУ, как таковое у нас есть, но выполняет роль ПЗУ программ.
На запись доступно с пульта, а программно на запись - недоступно.
Вот и подмывает адреса возврата и стек засунуть как-то в это "ОЗУ программ", хотя бы в 0-страницу...
или в вершину...
1 ячейка стека на 1 вызов, судя по TMS1000, - решение всё-таки работоспособное... раз уж
TMS1000 активно и успешно продавалась...
Но по собственному опыту знаю - хотелось бы иметь хотя бы 2 уровня вложения.

Но если всё-таки реализовать запись в "ОЗУ программ", можно попробовать другое древнее решение:
адрес возврата сохраняется в первых ячейках подпрограммы, а вместо RET подпрограмма заканчивется
переходом на свой начальный адрес
, где во время вызова уже подготовлен JMP по адресу возврата.

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

Этот приём я увидел ещё в одном "самоварном" компьютере:
http://www.ljw.me.uk/educ8/educ8.html

Интересная самоделка в принципе, только авторы как-то по-жадовски зажали принципиальную схему... :(

Image

Авторы пишут, что опираются на решения DEC PDP-8... Интересно, этот знаменитый
раритет был бесстековой машиной? Если да - может не грех это перенять?

PS. Да, похоже DEC PDP-8 обходилась без стека, и никто её за зто не ругал:
Обратите внимание на команду «Переход на подпрограмму». Поскольку в машине нет
поддержки стековых операций, то перед началом подпрограммы просто резервируется
слово для сохранения адреса возврата.
Источник
User avatar
HardWareMan
Banned
Posts: 2139
Joined: 20 Mar 2005 13:41
Location: От туда

Post by HardWareMan »

ЕМНИП, у МИПСов же 1 уровень стека. Точнее, у них специальный регистр адреса возврата, куда сохраняется адрес при вызове подпрограммы. Но никто не мешает сохранять этот регистр где-нибудь еще, ведь правда? Я думаю, это достаточно красивое решение.
User avatar
VituZz
God
Posts: 1343
Joined: 13 Nov 2010 04:06

Post by VituZz »

Прошу не пинать, если я невпопад... Но почему мы не можем просто поставить ОЗУ нужной разрядности шины данных и к нему реверсивный счётчик? PUSH записывает в ОЗУ и добавляет к счётчику единицу, POP - обратные действия. Чем это решение не подходит? Вложенность стека определится только объёмом ОЗУ.