Мои элементы - это четкая копия БФЯ, просто собрано в блоки (регистры и прочее), и оптимизировано. Без какого-либо изменения логики.
Вид для печати
Это не так. Ты нарисовал "как ты видишь" 4 (четыре (sic!) схемы), а теперь ты спрашиваешь "где рабочая УКНЦ на FPGA?" и "A какие проблемы с асинхронными схемами на ПЛИС?" Потому что дальше одного шага ты не видел и никого не слушал.
Скажи, ты хорошо понимаешь мои слова "автоматическая генерация HDL по схеме"? Ты хорошо осознаешь, что я могу взять любую пикадовскую схему 1801ВП1, за одну минуту получить нетлист, за вторую минуту получить верилог этой микросхемы, а на третью минуту увидеть все диаграммы в модельсиме, причем с задержками вносимыми реальной микросхемой? При этом нет никакой отсебятины, группирования, ручного перерисовывания и прочего, плюс имеем сквозной контроль с топологией. @Ynicky сейчас просто пишет ХМ-ки практически заново опираясь на сомнительные эталоны. Были бы схемы нарисованы с БФЯ - сомнительность эталонов была бы значительно ниже и получены были бы они мгновенно по готовности схемы.
Вообще-то у меня для каждой ХМ-ки есть и оригинальные БФЯ-схемы. Единственное отличие - это триггеры сразу нарисованы триггерами. Но тоже без отсебятины.
- - - Добавлено - - -
А вот как раз где можно насовать отсебятины - это переписывая асинхронную модель на синхронную.
Я еще не уверен, что твой синхронный ВМ2 соответствует оригиналу ;-) Может даже поймаю это на тестах, если будет модель УКНЦ на ФПГА с твоей синхронной моделью ВМ2.
Так чего же не выложил?
- - - Добавлено - - -
Конечно можно. Но - отсебятина отсебятине рознь. Твоя отсебятина - волюнтаристкая, а моя вынужденная - потому что нет другого способа запустить процессор на современных ПЛИС.
Вот чтобы минимизировать вероятность ошибки процесс и построен пошагово - есть асинхронная модель, есть ее диаграммы, и постепенно, по одному сигнальчику переводим в синхронную.
А потом сравниваем диаграммы эталона с тем что получилось, и процесс этого сравнения легко автоматизируется - синхронная модель проходит все заводские тесты с теми же обращениями к памяти и в те же такты что и асинхронная.
Да я только рад буду, ошибки всегда возможны, дополнительная верификация всегда на пользу.
Все выложено в этой теме. Оригинальная схема на БФЯ, и оптимизированная схема для каждой из ХМ-ок.
- - - Добавлено - - -
https://www.youtube.com/watch?v=u8mYMw4vtXE
1. Присоединяюсь к просьбе выложить все ценное в первом посте этой темы.
2. Я посмотрел бфяшную схему ХМ2-001, там у тебя опять изысканный волюнтаризьм с библиотекой :). Чтобы не страдать с ее написанием на верилоге хорошо бы иметь правильные имена типов, например если ячейка типа 621 то и тип должен быть 621 и три гетерогенных гейта с нумерацией, а не просто NOT. Второй момент - внутренние цепи должны быть поименованные, иначе это автоматически помоделировать можно - а вот осознать - нет :). Так шо - пусть оно уже идет как идет.
Такие извращенцы, которым кушают только схему в БФЯ пусть сами и переименовывают, как им нравится. И за это скажите спасибо)
Вот, например, я дооолго тебя просил сделать ВМ2 в виде логической схемы. В итоге сделал сам. Ну раз тебе не нужно, а мне нужно, а работа трудная, приходится самому.
- - - Добавлено - - -
Все упаковал в один архив, и выложил в первом посте.
Все четыре чипа - оригинальный реверс, и оптимизированный.
:)
@Alex_K, @Vslav, интересную особенность заметил в микрокоде ВМ2, но пока подробно в этом не разбирался.
В режимах HALT и USER по разному анализируется ситуации при выборке следующей команды, когда адресация регистра-источника модифицирует R7, и когда регистр приемник использует R7. Хотя, казалось бы, какая разница, какой режим, HALT или USER.
Это при выборке следующей команды или предвыборке следующей команды? Какие типы адресаций - 67 и 77? Если используется 67 или 77, то по идее процессор может использовать предвыбранную команду в качестве индексного значения для адресации. Да, и в режиме HALT с запрещёнными прерываниями CPC и CPSW не обновляются.
А, вот, наверное, с этим и связано.
- - - Добавлено - - -
Пока еще не разбирался.
Но там два условия, обозначенных признаками RI0 и RI2:
RI0 - dd использует R7 (любая адресация, с использованием R7)
RI2 - ss модифицирует R7 (любая адресация по (R7), либо индексная адресация)
T.e. ss = (R7), (R7)+, -(R7), @(R7)+, @-(R7), X(Rn), @X(Rn)
Коротко об интересном.
В процессоре ВМ2 дофигищи 16-битных регистров. Гораздо больше, чем доступно посредством инструкций PDP-11.
Если бы микрокод был другим, то, я думаю, процессор мог быть гораздо интереснее и богаче по возможностям.
Интересно, что на шину X АЛУ может выставляться один из 16 регистров,
А на шину Y АЛУ может выставляться один из 32 регистров/констатнт/частей слова инструкции:
В списке нет, например, PC2, который может читаться только на шину X АЛУ.Код:0 - R0
1 - R1
2 - R2
3 - R3
4 - R4
5 - R5
6 - R6
7 - PC1
8 - EA1
9 - EA2
10 - нет регистра
11 - RS
12 - PSW
13 - ACC
14 - RA
15 - BRD
16 - IR & 0x000F
17 - IR & 0x003F
18 - 0x0001 (если ALT_CNST=0 (байтовый инкремент))), 0x0002 (если ALT_CNST=1 (словный инкремент)) (константа автоинкремента при формировании исполнительного адреса)
19 - 0x0002
20 - 0x0000
21 - 0x0004
22 - CPSW
23 - BIR
24 - IR & 0x00FF с расширением знака до 16 бит
25 - 0x0000 (если PSW3=0), 0xFFFF (если PSW3=1) (флаг N)
26 - PSW0 & 0x0001 (флга C)
27 - 0x0000
28 - выбор константы вектора прерывания
29 - 0x0014
30 - PC
31 - PC
- - - Добавлено - - -Код:0 - R0
1 - R1
2 - R2
3 - R3
4 - R4
5 - R5
6 - R6
7 - PC1 (если RA_FR1 = 0) или PC2 (если RA_FR1 = 1)
8 - EA1
9 - EA2
10 - нет регистра
11 - RS
12 - PSW
13 - ACC
14 - нет регистра
15 - BRD
Кроме того, есть запись результата обратно в регистр, который выставлялся на X или на Y:
Обратная запись для X:
Код:0 - R0
1 - R1
2 - R2
3 - R3
4 - R4
5 - R5
6 - R6
7 - PC2
8 - EA1
9 - EA2
10 - EA_CTLD (счетчик для расширенной арифметики)
11 - RS
12 - PSW (если /NA0=1, то запись и в PSW4), (если операция со словом (BYTE=0), то запись в PSW4 и PSW8). Работа с константой (PL8=1) блокирует WR_PSW.
13 - ACC
14 - нет регистра
15 - BRD (если QD_SWAP=1, то QSWP=1) (обмен байт при обращении по нечетному адресу)
Обратная запись для Y:
Код:0 - R0
1 - R1
2 - R2
3 - R3
4 - R4
5 - R5
6 - R6
7 - PC2
8 - EA1
9 - EA2
10 - EA_CTLD (счетчик для расширенной арифметики)
11 - RS
12 - PSW (если /NA0=1, то запись и в PSW4), (если операция со словом (BYTE=0), то запись в PSW4 и PSW8). Работа с константой (PL8=1) блокирует WR_PSW.
13 - ACC
14 - нет регистра
15 - BRD (если QD_SWAP=1, то QSWP=1) (обмен байт при обращении по нечетному адресу)
16 - R0
17 - R1
18 - R2
19 - R3
20 - R4
21 - R5
22 - CPSW
23 - R7
24 - EA1
25 - EA2
26 - EA_CTLD (счетчик для расширенной арифметики)
27 - RS
28 - PSW (если /NA0=1, то запись и в PSW4), (если операция со словом (BYTE=0), то запись в PSW4 и PSW8). Работа с константой (PL8=1) блокирует WR_PSW.
29 - ACC
30 - PC
31 - PC
Краткое описание ядра и основного цикла процессора 1801ВМ2.
Описание составлено исключительно по оригинальной потранзисторной схеме @Vslav'a, за которую ему огромная благодарность.
Все сигналы имеют те же наименования, что и на транзисторной схеме Vslav'a. За исключением сигналов NA0..NA5 (адрес следующей микрокоманды), и сигналов PL0..PL36 (выход ПЛМ микрокоманд), которые при описании микрокоманды и адреса микрокоманды приведены в инверсном виде, что более точно отражает суть информации, заложенной в них. Кроме того, добавлено некоторое количество сигналов, не именованых на схеме Vslav'а.
В данном описании будет рассмотрено ядро процессора на примере простейшего цикла выборки команды типа регистр-регистр. Прерывания, таймауты шины и прочие тонкости пока что не рассматриваются.
Основным времязадающим и управляющим узлом процессора является микропрограммный автомат, который непосредственно управляет АЛУ и блоком ввода-вывода. Управление АЛУ синхронное, т.е. можно сказать, что АЛУ является частью микропрограммного автомата. Управление блоком ввода-вывода асинхронное.
Каждая инструкция процессора выполняется как минимум за две микрокоманды. Первой из которых всегда является команда выборки и преддекодирования инструкции. Цикл микрокоманды равен 4-м тактам входной частоты процессора CLCI. В дальнейшем тактом будет называться один цикл CLCI, а полутактом - половина цикла CLCI. Цикл АЛУ в большинстве случаев также выполняется за 4 такта синхронно с микророграммным автоматом. АЛУ используется как для выполнения математическо-логических операций, так и для вычисления исполнительного адреса. Цикл чтения шины AD блока вввода-вывода, при отсутствии задержек доступа к внешнему устройству, выполняется за 8 тактов. Исключение составляет недокументированный режим чтения шины с опережающим RPLY, который выполняется за 6 тактов, и рассматриваться здесь не будет.
Для выполнения простейшей инструкции процессора требуется две микрокоманды (8 тактов), и один один цикл ввода (8 тактов). Блок ввода-вывода работает в параллель с микропрограммным автоматом, поэтому общее время выполнения простейшей инструкции также составляет 8 тактов.
Микропрограммный автомат может приостанавливаться в некоторых случаях. Чаще всего это происходит, когда буферный регистр инструкции (BIR) еще не содержит действительных данных. Выполнение микропрограммы приостанавливается, пока блок ввода-вывода не прочитает с шины слово инструкции и не обновит BIR.
Микропрограмма находится в ПЛМ микрокоманд, и состоит из 198-ми записей, которые, в свою очередь, условно обьединены примерно в 64 микрокоманды. Та или иная запись выбирается в зависимости от условий, передаваемых в ПЛМ в виде адреса инструкции (16 бит), получаемого с преддекодера адреса микрокоманды (6 бит) и двух трехбитных модификаторов RI0,RI1,RI2 и IX0,IX1,IX2. Преддекодер для упрощения пока что не рассматриваем.
В зависимости от входных данных, выбирается одна или несколько записей ПЛМ, которые обьединяются по логическому ИЛИ (OR), и поступают на выход матрицы в виде сигналов PL0..PL36. В сигналах PL закодированы следующие данные:
1. Номер регистра для шины X АЛУ.
2. Номер регистра или константы для шины Y АЛУ.
3. Математическо-логическая функция для АЛУ.
4. Функция сдвига для АЛУ.
5. Тип операции ввода-вывода.
6. Группа модификаторов, влияющих на выполнение команды.
Трехбитный модификатор выборки микрокоманды RI имеет многофункциональное назначение. В микрокоманде выборки слова инструкции значение следующее:
RI0 - поле dd инструкции использует R7 (любая адресация, с использованием R7)
RI1 - HALT-режим (PSW[8]=1)
RI2 - поле ss модифицирует R7 (адресация (R7), (R7)+, -(R7), @(R7)+, @-(R7), X(Rn), @X(Rn))
Другие значения поля RI будут рассмотрены в отдельной главе.
Трехбитный модификатор выборки микрокоманды IX может меняться для каждого шага микрокоманды и означает:
IX0 - идентификатор словной двухоперандной инструкции записи
IX1 - двухоперандная инструкция использующя R7, выполнено условие условного перехода, или RCMD (требует уточнения)
IX2 - некоторые двухоперандные инструкции
Кроме того, блок преддекодера выдает следующие сигналы, влияющие на исполнение микрокоманд:
DC_RTT - инструкция RTT
DC_FB - инструкция работает с байтом, а не словом
DC_MOP0 и DC_MOP1 - кодирует тип цикла инструкции:
Часть сигналов PL, получаемых с выхода ПЛМ микрокоманд используется для выбора режима работы микрокоманды. Большинство же запоминаются в регистре слова микрокоманды (REG_MCMD_WORD), и доступны в виде PLM0..PLM36. Часть сигналов инвертируется.Код:DC_MOP1 DC_MOP0 Операция ввода-вывода Цикл памяти
0 0 IO_RD, IO_IN, IO_WR RMW
0 1 IO_WR W
1 0 IO_RD, IO_IN R
1 1 NOWRA -
Диаграммы работы микропрограммного автомата, АЛУ и блока ввода-вывода на примере выполнения простейшей инструкции типа регистр-регистр.
Слева пример с нулевой задержкой памяти, справа пример с задержкой памяти на 2 такта:
https://pic.maxiol.com/images2/16053...51951043.2.png
Для каждой инструкции выполняется микрокоманда с адресом 0x01 (выборка инструкции), и микрокоманда исполнения самой инструкции.
Для наглядности приведен только один цикл АЛУ, и один цикл блока ввода-вывода.
Код:Полутакт:
7 - Готовы сигналы PL с ПЛМ микрокоманд.
Модификатор микрокоманды SET_CEND, означающий выборку следующей инструкции.
Адрес микрокоманды 0x01.
8 - Начало микрокоманды. Регистр BIR (буферный регистр инструкции) содержит действительны данные,
поэтому безо всякой задержки запускается конвейер преддекодера инструкции.
9 - Данные с преддекодера инструкций выставляются на шину PLD.
10 - Данные с преддекодера инструкций стабильны и могут быть защелкнуты в регистре инструкций.
Они содержат слово инструкции, адрес первой микрокоманды инструкции, модификаторы IX, RI.
В соответствии с микрокомандой на шину X АЛУ выдается PC2 (опережающий счетчик команд),
а на шину Y АЛУ выдается константа 0x0002.
11 - В соответствии с микрокомандой формируется операция ввода-вывода IO_RD (чтение шины AD),
IO_IN (данные предназначены для BIR), IO_RCD (сохранять данные также в BRD (буферный региср данных)
12 - RA (регистр адреса) = PC2. Запросить цикл шины IO_RD.
Блок ввода-вывода свободен, поэтому сразу начинается операция ввода.
На шину адреса выставляется регистр адреса RA, в котором содержится значение опережающего счетчика команд PC2.
13 - PC=PC1=PC2 (действие операции IO_RCD).
16 - PC2=PC2+2 (результат работы АЛУ).
Выставляется сигнал SYNC (адрес выставлен на шине).
Сразу получаем в ответ сигнал AR (подтверждение получени адреса).
В этом же полутакте начинается исполнение следующей микрокоманды, собственно и выполняющей инструкцию.
18 - Выставляется сигнал DIN (ввод информации с шины).
20 - Получено подтверждение RPLY.
22 - Данные на шине AD стабильны, и начинают записываться в регистры BIR и BRD.
24 - Начало следующей микрокоманды, извлекающей инструкцию из регистра BIR.
26 - Снимается сигнал DIN. Шина AD может быть освобождена.
28 - В ответ внешнее устройство снимает SYNC, AR и RPLY. Возможна новая операция ввода-вывода.
Одиним из случаев приостановки работы АЛУ и микропрограммы является удержание регистра адреса RA.
Регистра RA содержит адрес, выставляемый на шину AD в цикле чтения/записи. Ввиду того, что этот реигстр не буферизирован, а транслируется на шину напрямую, он требует защиты от перезаписи в то время, пока адрес удерживается на шине AD. За защиту RA от перезаписи отвечает сигнал RA_HOLD.
Работа АЛУ с регистром RA отличается от работы с другими регистрами следующими особенностями:
1. Регистр RA может обновлятся не только в конце цикла АЛУ (по WR2), сохраняя результат математическо-логической операции, но и в самом начале цикла АЛУ (по ALU_WR). Такая возможность позволяет более удобно и быстро реализовывать постинкрементные режимы адресации, когда одна операция АЛУ сперва выдает исполнительный адрес блоку ввода-вывода, а затем инкрементирует адрес, в то время, как блок ввода-вывода уже работает.
2. Каждая запись в регистр RA сразу же запрашивает цикл ввода-вывода. И если блок ввода-вывода свободен, начинается обмен.
3. Как только запрошен цикл ввода-вывода, регистр RA блокируется сигналом RA_HOLD до тех, пор, пока не будет получен ответ AR (подтверждение адреса), с задержкой до 2-х тактов (по заднему фронту сигнала RTA). Если RA заблокирован, то любой следующий цикл АЛУ/микрокоманды, обновляющий RA, будет приостановлен до тех пор, пока не будет снят сигнал RA_HOLD. Цикл, не обновляющий RA, будет работать без задержки.
На графике приведены примеры блокировки регистра RA.
1. Слева RA обновляется в начале цикла АЛУ (по ALU_WR). Задержка следующей микрокоманды 2 такта.
2. Справа RA обновляется в конце цикла АЛУ (по WR2). Задержка следующей микрокоманды 4 такта.
https://pic.maxiol.com/images2/16054...1951043.ra.png
p.s.: Предыдущий пост тоже обновлен и дополнен.
Расшифровал и составикл карту аппаратных прерываний.
Справа-налево:
1. Номер записи в ПЛМ прерываний
2. Группа условий для срабатывания прерывания
3. Служебные флаги
4. Вектор и описание, приоритет в квадратных скобках
Комбинации поля RI:
000 - режим WAIT
001 - нет запроса на прерывание
100 - прерывание в режиме USER
110 - прерывание в режиме HALT
111 - начальный пуск
Примечание: TOVF - зависание, TOVF2 - двойное зависание
Замечание: Во всех случаях, если не указано иное, AC0_ECHO=1
Код:[0]
Подготовка начального пуска?
10: AC0_ECHO=0 ALCO_FALL=0 VECID=0x0, RI=000 AC0 WAIT?
Начальный пуск
1: AC0_ECHO=0 ALCO_FALL=1 VECID=0xF, RI=111 ACLO_ACK VEC=0x00 (Начальный пуск)
[1.0]
Зависание при приеме АВП
6: TOVF=1 VEC=1 VECID=0x4, RI=110, TOVF_ACK VEC=0xBC (Зависание при приеме АВП)
[1.1]
Двойное зависание
2: TOVF=1 VEC=0 TOVF2=1 VECID=0xC, RI=110, TOVF_ACK VEC=0x7C (Двойное зависание)
Зависание
0: TOVF=1 VEC=0 TOVF2=0 VECID=0xD, RI=100, TOVF_ACK VEC=0x04 (Зависание в режиме USER)
0,18: TOVF=1 VEC=0 TOVF2=0 PSW8=1 VECID=0xD, RI=110, TOVF_ACK VEC=0x04 (Зависание в режиме HALT)
[3]
Прерывание по T-разряду
8: TOVF=0 WAIT/TBIT=01 VECID=0xA, RI=100 VEC=0x0C (T-разряд)
8,12: TOVF=0 WAIT/TBIT=01 RTT=1 VECID=0xA, RI=001 VEC=0x0C (Т-разряд + RTT) (Нет прерывания?)
[4]
Сигнал ACLO в режиме HALT с запрещенными прерываниями
13: TOVF=0 ALCO_RISE=1 PSW87=11 WAIT/TBIT=00 VECID=0x0, RI=001 Нет прерывания
17: TOVF=0 ALCO_RISE=1 PSW87=11 WAIT=1 VECID=0x0, RI=000 WAIT
Сигнал АCLO не в режиме HALT с запрещенными прерываниями
15,22: TOVF=0 ALCO_RISE=1 PSW87!=11 WAIT/TBIT!=01 VECID=0x0, RI=100, ACLO_ACK VEC=0x14 (ACLO)
[5]
Прерывание по сигналу HALT в режиме USER
7,9: TOVF=0 ALCO_RISE=0 HALT=1 PSW8=0 WAIT/TBIT!=01 VECID=0x2, RI=110 VEC=0x78 (HALT)
Прерывание по сигналу HALT в режиме HALT
11: TOVF=0 ALCO_RISE=0 HALT=1 PSW8=1 WAIT/TBIT=00 VECID=0x0, RI=001 Нет прерывания
21: TOVF=0 ALCO_RISE=0 HALT=1 PSW8=1 WAIT=1 VECID=0x0, RI=000 WAIT
[5.1]
Прерывания запрещены, не обрабатывать EVNT и VIRQ
4: TOVF=0 ALCO_RISE=0 HALT=0 PSW7=1 WAIT/TBIT=00 VECID=0x0, RI=001 Нет прерывания
16: TOVF=0 ALCO_RISE=0 HALT=0 PSW7=1 WAIT=1 VECID=0x0, RI=000 WAIT
[6]
Прерывание по событию EVNT
3,5: TOVF=0 ALCO_RISE=0 HALT=0 EVNT_RISE=1 PSW7=0 WAIT/TBIT!=01 VECID=0x3, RI=100 EVNT_ACK VEC=0x40 (EVNT)
[7]
Векторное прерывание VIRQ
19,23: TOVF=0 ALCO_RISE=0 HALT=0 EVNT_RISE=0 VIRQ=1 PSW7=0 WAIT/TBIT!=01 VECID=0x0, RI=101
[8]
Всякий режим, когда нет ни одного запроса прерывания
14: TOVF=0 ALCO_RISE=0 HALT=0 EVNT_RISE=0 VIRQ=0 WAIT/TBIT=00 VECID=0x0, RI=001 Нет прерывания
20: TOVF=0 ALCO_RISE=0 HALT=0 EVNT_RISE=0 VIRQ=0 WAIT=1 VECID=0x0, RI=000 WAIT
Модификатор выборки микрокоманды RI.
Трехбитный модификатор выборки микрокоманды RI имеет многофункциональное назначение, в зависимости от выбранного режима.
1. Режим выборки инструкции (стробируется сигналом IR_STB). Инициируется сигналом SET_CEND (PL26=1, PL25=0, /NA=0), и используется только в одной микрокоманде с адресом 0x01.
RI0 - поле dd инструкции использует R7 (любая адресация, с использованием R7)
RI1 - HALT-режим (PSW[8]=1)
RI2 - поле ss модифицирует R7 (адресация (R7), (R7)+, -(R7), @(R7)+, @-(R7), X(Rn), @X(Rn))
2. Режим разбора запроса аппаратного прерывания (стробируется сигналом PLI_ACK). Инициируется сигналом PLI_REQ (PL27=0, /NA1=0). Обычно инициируется в последней микрокоманде каждой инструкции, перед переходом на микрокоманду 0x01.
RI2.RI1.RI0:
000 - режим WAIT
001 - нет запроса на прерывание
100 - прерывание в режиме USER
110 - прерывание в режиме HALT
111 - начальный пуск
3. Режим разбора запроса программного прерывания (стробируется сигналом PI_STB). Инициируется, если PLM0=1. Используется в инструкциях программных прерываний.
нет описания
Замечание. В режиме (1) RI0 может только сбрасываться, а RI1 и RI2 только устанавливаться. Потому микрокоманда выборки инструкции чаще всего вызывается после микрокоманды инициирующей разбор запроса прерывания, со входящим значением RI равным 001.
p.s.: Предыдущие статьи тоже обновились.
А вот здесь интересный момент. При возникновении зависания должен устанавливаться какой-то флаг. Если снова происходит зависание при уже установленном флаге, то производится прерывание по двойному зависанию. Соответственно вопрос - при каких условиях сбрасывается этот флаг? По идее он должен сбросится, если операция ввода-вывода прошла нормально, т.е. есть ответ по RPLY. Но по моим опытам получалось, что данный флаг сбрасывался только при успешном чтении команды.
Сбрасывается по микрокоманде чтения следующей инструкции или по reset'у.
А флаг простого зависания сбрасывается при вызове обработчика прерывания по зависанию.
- - - Добавлено - - -
Это и есть флаги.
TOVF - флаг обычного зависания,
TOVF2 - флаг двойного зависания
Ага! Конкретный пример: Указатель стека равен 01000, в 4-м векторе находится адрес 0170000. Ячейка 0170000 нечитаемая, нет ответа RPLY, должно произойти прерывание по вектору 4.
Командой TST @#170000 читаем ячейку с адресом 0170000. Ответа по RPLY нету, потому производится прерывание по вектору 4. Сначала в стек по адресам 0774 и 0776 ложатся текущие CPC и CPSW. Запись в стек происходит нормально, нет никакого зависания. Далее из ячеек 4 и 6 читаются новые значения PC и PSW. Здесь тоже всё нормально, без зависаний. А вот далее интересней. Т.к. новая команда находится по адресу 0170000, то при её чтении произойдёт зависание, а т.к. флаг не сброшен, то будет двойное зависание. Вроде так.
Там работы немало, скажу я вам)
Вообще, процессор в целом весьма сложная штуковина. Я думаю, какой-нибудь Z80 явно в разы попроще.
Тут и независимые блоки, и конвейеры в каждом блоке, сложные зависимости.
И, самое интересное, есть много вещей, которые словно приляпывались поверх уже существующих. Я не говорю о расширенной арифметике, которая именно так и сделана.
Например, модификаторы для микрокоманды сделаны совершено по-разному. Этому один бит, этому два, этому три, и все эти биты разбросаны, перемешаны и доляпаны друг к другу. Не говоря уже о том, то, видимо, за нехваткой разрядности микрокода, в качестве модификаторов использовались даже отдельные биты адреса следующей микрокоманды (NA5..NA0). Так что сборной солянки для расшифровки там не мало.
Ну, и, конечно же многофункциональное поле RI, сделанное в виде трехпортового трехбитного регистра, при этом третий порт работает в виде reset/set/set, как описано чуть выше.
Полно было триггеров, которых надо было проверять, не встанут ли они в третье состояние.
Словом, распутано и приведено в человеческий вид многое, но еще не все.
Я вообще не понимаю, как @Vslav разбирается в потранзисторной схеме, или же в ее аналоге на VHDL. Запускать это можно, отследить любые сигналы можно, но разобраться во всей поднаготной и систематизировать реверс, при этом не теряя всю общую картину, по такой схеме для меня было бы нереально.
Вот мне как раз важно 2-е.
Ибо, я эмуляторщик, и если соберусь писать потактовый УКНЦ, то без второго пункта можно даже не пробовать.
Естественно, писать даже потактовую эмуляцию в виде эмуляции всех вентилей - это абсурд и дикие тормоза.
А, стало быть, надо понять ВСЮ структуру процессора до мелочей, и преобразовать в тот вид, когда это уже можно эмулировать, а не просто тупо повентильно симулировать.
Поэтому, опять же, верилог для основы мне не подходит.
@Alex_K, интересное наблюдение.
При обработке прерывания безадресный регистр (SEL) читается в любом случае, независимо от того, в режиме USER обрабатывается прерывание или в режиме HALT.
Все, что читается с шины, размещается в BRD (буферный регистр данных).
А если читается код следующей инструкции, то он размещается и в BRD, и в BIR (буферный регистр инструкций) одновременно.
- - - Добавлено - - -
Уточню - все, что я уже рассмотрел. Но могут быть режимы, до которых я еще не добрался.
Чтение вектора прерывания в документации от @Alex_K нарисовано неправильно:
https://pic.maxiol.com/images2/16058...51043.iak0.png
На самом деле происходит так:
https://pic.maxiol.com/images2/16058...51043.iak1.png
То есть, данные с шины защелкиваются внутри активного DIN, а точнее внутри RDAT.
А если ответить RPLY не дожидаясь IAKO, то можно сократить время чтения на два такта,
хотя практической пользы от этого, видимо, никакой.
https://pic.maxiol.com/images2/16058...51043.iak2.png
Цикл записи шины в процессоре ВМ2 (12 тактов) значительно медленнее, чем цикл чтения (8 тактов).
Кроме того, невозможно задать опережающий RPLY, таким же образом, как в цикле чтения, чтобы сократить время доступа к шине. Это связано с тем, что 'увидев' RPLY на шине, контроллер не выдаст данные. Поэтому, если мы хотим ускорить запись опережающим RPLY, выдавать его нужно после того, как на шину выставлены данные, но до того, как появился сигнал DOUT.
Как же этого добиться? В принципе, такое возможно.
Например, после получения адреса сперва ожидаем появление на шине значения 0x0000, затем ожидаем любого изменения на шине, либо же появления сигнала DOUT. После чего выдаем RPLY.
В случае, если записывается число 0x0000, опережающего RPLY выдать не получится. При записи любого другого числа, RPLY будет с опережением, и цикл записи сократится до 10 тактов.
Конечно, это усложнит контроллер памяти, но позволит ускорить запись.
https://pic.maxiol.com/images2/16059...1951043.01.png