Pentagon 2.666LE (часть 1)
30vii
Изучал документацию на Pentagon 2.666LE. Там нет JTAG для ПЛИС.
Ставил ADM MDK. Регистрация работает только до 2020 года, надо
переводить часы?
31vii
И так компилирует. Смог скомпилировать проект под плату (время
сборки 7 минут 21 секунда: Quartus + cmd + Keil) и прошить его
(через Keil). Сделал top модуль на Verilog (проект был на VHDL).
1viii
Переношу части из одного большого модуля VHDL в Verilog, чтобы
понять, какие из них сколько занимают (занято 89% ПЛИС). При
прошивке через Keil (Flash) ни в коем случае не соглашаться на
firmware update!!! Иначе сломается программатор.
2viii
Переношу дальше. Проект превышает заданные тактовые частоты
(основной клок 114 МГц).
5viii
Разобрался в схеме. Самые долгие сигналы - выходы данных для ОЗУ
на ногах. Но частоту нарушают сигналы, дешифрованные из выходов
процессора в том же такте. Начал их оптимизировать через реги.
6viii
Схема работает при расчётной частоте 30-34 МГц (раньше было 22,
работало на 28 по счастливой случайности). Занято 87% (было
89%). 913 ворнингов. 39 клоков (было 51).
Не смог разобраться с протоколом между ПЛИС и микроконтроллером,
любые исправления синхронизации вызывают глюки.
7viii
Внёс авторские изменения в прошивке с сайта github. Там удалён
отладчик, но я его сохранил - пригодится.
8viii
Пробовал подключить процессорное ядро TV80 (версия T80 на
Verilog). Не работает.
9viii
Не проходят адресные сигналы, Quartus оптимизирует все эти цепи
в ноль. Проверял свою обвязку - ошибок нет.
12viii
Должен работать хотя бы счётчик адресов, если не залип reset_n.
Поставил reset_n=1. Не помогло. При 0 Quartus оптимизирует ещё
сильнее. Сбросил прочие управляющие сигналы - не помогло.
Выходит только A[0].
13viii
Явно прописал везде ширину адресной шины, появились адреса 0..7
и 10..11.
15viii
Проверял прохождение данных - ошибок нет. Quartus вылетает при
попытке посмотреть чип (Chip Planner).
19viii
Добавлял в TV80 дополнительные цепи из проекта на VHDL. Не
помогло, хотя формирование всех адресов внутри TV80
прослеживается.
Пробовал выдать на WR случайный сигнал. Не помогло.
То же на A[15:0], IORQ, IOcycle, D[7:0] - не помогло.
Заменил iorq_after_bus (iorq процессора, задавленный сигналом
IORQGE с ZX-BUS) на virt_cpu_iorq (т.е. прямо с процессора). Не
помогло.
20viii
Пробовал сформировать случайные сигналы на верхнем уровне
проекта. Выяснилось, что не проходил сигнал M1.
Починил. всё равно что-то переоптимизируется (процессор меньше
на 500 ячеек, обвязка на 200), не работает (процессорный матрац,
как будто из ПЗУ читается 0xff).
22viii
Вывел сигналы на экран. Сигнал /MREQ висит в 0.
23viii
Пробовал исправить /MREQ по старому образцу. Всё равно висит в
0, но уже без матраца. /RD тоже теперь в 0.
Вернул старый /RD. Нули не починились, но теперь видно
периодическую выдачу /WR (раньше не было). Теперь значения в
портах меняются по сбросу.
29viii
Пытался запустить симуляцию своего проекта в ModelSim. Не
компилировалось - пришлось менять порядок строк и убирать
include.
Но симуляция не запустилась (даже на скомпилировалась для
симуляции).
30viii
Выкинул несколько модулей (в первую очередь память), симулятор
смог скомпилировать и запустить, но дальше непонятно.
4ix
Читал документацию на ModelSim на английском.
5ix
Читал документацию дальше. Что-то связанное с симуляцией памяти
встречается на с.256 мануала.
9ix
Читал дальше. На с.286 есть про отладку race conditions.
10ix
Читал дальше. На с.321 начинается про сохранение и использование
сгенерированных сигналов, с возможностью обработки (с.362).
12ix
Читал дальше. Оказалось, что в моём проекте выходные сигналы не
0/1, а 0/X, потому что некоторые входные не заданы.
16ix
Проверял время прохождения сигнала от угла до угла ПЛИС. На
Cyclone I 17 нс (самом большом), на Cyclone III 15 нс (самом
большом). Прочитал reference manual.
Такое ощущение, что внутри спрятан Лисп, и весь интерфейс
управляется на Лиспе, а наружу вынесены обёртки для этих
управляющих функций.
18ix
Дочитал tutorial по ModelSim. Можно подключать файлы для
заполнения памяти (но не как в Quartus). Скрипты (со списком
сигналом и запуском симуляции на нужное время) нельзя запускать
по кнопке, только через do s.do.
19ix
Нашёл статьи про ModelSim на русском, читал. В тестбенче можно
читать текстовые файлы с настройками, которые меняются во
времени.
20ix
Пробовал тестбенчи от KOE (T80, vg93 и video). Не получилось
запустить, ругается.
23ix
Пробовал сделать свой проект тестбенча для T80. Вроде
заработало.
24ix
Переделал тестбенч на TV80. Оказалось, что нельзя сочетать
Verilog с VHDL: "ALTERA version supports only a single HDL".
25ix
LVD говорит, что такого не может быть, надо взять за образец
проект Pentevo. Проверил. Те тесты у меня тоже не работают.
26ix
Исправил скрипт, чтобы поддерживался systemverilog (ключ -sv).
Всё компилируется, но ModelSim всё равно пишет, что нельзя
сочетать разные HDL.
Это версия 6.0. Попробовал версию 10.0 - не нашёл лицензию.
Попробовал скачать и установить версию 2021.1 - не захватывает
лицензию, хотя его тулза lmutil пишет, что лицензия есть,
прописана правильно, имеет правильную структуру и не истекла.
Запуск lmgrd не помогает: "Unable to checkout a license. Make
sure your license file environment variable (e.g.,
LM_LICENSE_FILE) is set correctly and then run 'lmutil lmdiag'
to diagnose the problem". Всё делал, лицензия правильная,
LM_LICENSE_FILE на неё указывает, но он её не подцепляет.
Пробовал короткий путь, путь в папке программы, в win64 внутри
неё - не помогает.
Пробовал в пути слэш в другую сторону - не помогает.
Попробовал добавить MGLS_LICENSE_FILE - не помогает.
Пробовал переустанавливать с поддержкой лицензионного ключа
(файлы заменены) - не помогает.
27ix
KOE подтвердил, что моя версия ModelSim урезанная, рекомендовал
убрать -novopt в скриптах. Найти полную не удалось.
Переделывал тестбенч TV80 на Verilog. Не работает
30ix
Нашёл глюк, заработало под симулятором, но нет /RFSH. Видимо,
из-за отсутствия /RFSH (проверяется только в одном месте)
выкидывались все обращения к портам в базовом проекте. Забил
/RFSH=1, прошил - не работает. Есть какая-то реакция на сброс
(записывает в порты).
1x
Сравнил диаграммы T80 (доработанного) и TV80: в TV80 rd,mreq
начинаются на полтакта позже (по переднему фронту clk, а надо по
заднему) и имеют длительность не полтора такта (rd,mreq не в m1
надо два такта по задним фронтам), а 1 такт (видно, что сигнал
write занимает целый машинный цикл).
wr наоборот, занимает 3 такта по задним фронтам (wr надо 1 такт
по задним фронтам).
rd,wr при iorq надо 2.5 такта (от переднего до заднего). m1
нормально.
Для wr (по идее и для rd вне m1?) надо продлить mreq на
полтакта.
Оказалось, что в TV80 несовместимая нумерация tstate - бегущая
единица вместо счётчика.
Причём такты считаются с 000010 (000001 только при сбросе), в
цикле iorq два такта 000010.
Исправил wr, rd, mreq, iorq.
Проект заработал с TV80, но что-то не так с портами.
2x
Исправил порты, теперь всё работает с TV80.
7x
Переносил интерфейс с видеоконтроллером наружу, в Verilog часть.
Убрал лишние кнопки настройки видео. Не работает (экран
полностью чёрный).
8x
Исправил. Переносил интерфейс с палитрой наружу. Отвалилась
запись в палитру. Пробовал написать эту запись заново. Не
работает.
9x
Починил палитру. NedoOS виснет при инициализации HDD/SD.
пробовал заменить ядро TV80 на T80. Quartus вываливается при
сборке. Настроил Fitter с заданным seed. Так не вываливается
(впоследствии вываливание Quartus'а повторится очень много раз,
я каждый раз в таких случаях менял seed). С T80 такие же
зависания. Искал, с какой версии сломалось (потом я буду это
делать ещё много раз по поводу разных глюков. Я постоянно
сохраняю промежуточные версии).
В версии 2.8.2024 интерфейс T80 просто перенесён в Verilog, и
закомментированы iocycle1, iocycle2. Вернул iocycle1, iocycle2.
NedoOS грузится.
Поменял на TV80. NedoOS не грузится.
iocycle = 4 такта, но wr при iorq слишком долгий, кончается
после iocycle (надо синхронно с iorq). Исправил iorq. NedoOS
заработала.
Изображение прилипает к левому краю, нет нескольких левых
символов. Поправил (сдвинул ССИ на 32 малых пикселя).
10x
Переписал YM2149F на Verilog.
11x
Переписал видеоконтроллер на Verilog. Чёрный экран. Проблема со
считыванием из памяти или из буфера, т.к. константы выводит.
Пробовал сократить растактовку цикла M1 до 3 тактов - не
работает (пропал второй машинный цикл команды записи в память).
Не работает даже при сокращении одной команды nop (после неё не
сформировался сигнал m1, потому что не сформировался
last_mcycle).
Расхождение началось с иголки на last_tstate (в это время как
раз обновился (и должен) mcycles_d=010) - переприсвоился
tstates=100 (tstate продолжило считать ещё 2 такта!!!).
непонятно, как могла появиться иголка:
- tv80_core по posedge clk захватывает код команды (IR)
- tv80_mcode асинхронно декодирует команду (IR), формирует
tstates - оттуда асинхронно формируется last_tstate
- оттуда асинхронно формируется T_Res
- оттуда по posedge clk сбрасывается tstate <= #1 7'b0000010;
при last_mcycle сбрасывается mcycle <= #1 7'b0000001;
Добавил statesshifter, который (пока не щёлкает сдвигом вправо)
сравнивается с tstate, который щёлкается сдвигом влево.
Работает так же. При попытке сократить nop на 1 такт всё равно
иголка и неработоспособность m1 (реально в 4-м такте готовятся
важные сигналы для следующего машинного цикла, а в 3-м
дешифрация, но там ещё и дополнительный бардак в 3-м).
14x
Тестировал все видеорежимы, пытался подменить сигналы.
textmode реагирует на атрибут экрана, но неправильно; hires
чёрный; EGA отображается, но криво, с неправильными
растактовками.
Починил (было = вместо == в условии).
15x
Монитор стал сдвигать экран вправо (помогает только auto adjust,
когда экран полностью заполнен). Сделал растактовку ССИ среднюю
между тем, что было, и тем, что я ставил. Сдвигает влево (опять
помогает только auto adjust). Видимо, дело в мониторе.
Перенёс экран отладчика в Verilog.
Отвалилась клавиатура. Починил (не был выведен наружу один
процесс и пара сигналов).
Завышена растактовка команды ret. Исправил.
TV80 имеет грязную шину во время прерывания (нет такта
iorq+m1?). Сделал костыль внутри.
Не работает регистр R. Исправил.
Оптимизировал видеоконтроллер. занято 83%, Fmax=38 МГц.
Половина компиляций прошивки работают нестабильно.
16x
Переношу часы реального времени в Verilog, попутно оптимизирую.
Не работает 128K menu. Исправил.
17x
Ускорил Fmax до 43 МГц (буферизация портов перед чтением). При
этом на T80 только 30! (и не грузится NedoOS - виснет после
mount, в двух разных сборках). Сама логика влезает в 46 МГц.
Не работает запись времени в часы (секунды не пишутся, в час
пишется 0x30).
Вернул I2C как было, без синхронизации - работает, но нужно
ждать, когда пропишется половина числа, прежде чем ввести вторую
(в FPGA данные не обновляются, пока MCU их не пришлёт обратно, а
он шлёт редко).
Иногда внезапно меняется всё содержимое дополнительной памяти
часов (причём каждый раз разные числа) и нельзя писать ни в
часы, ни в их память. после сброса функциональность
восстанавливается. Пропало eff7 bit 7? С T80 тоже так сбивается!
Из-за асинхронной дешифрации адресов выбрался порт eff7 вместо
bff7 или dff7? (нет! там синхронная дешифрация по negedge
virt_cpu_clk) - глюк исчез после внедрения полной синхронности?
По pixel_clock (114 МГц) есть очень сложные вычисления, которые
точно не влезут в 114 МГц, в том числе в видеоконтроллере (хотя
там много сравнений с границами можно заменить на маски).
114 - это от PLL (*19/3)
Для сравнения пересобрал версию из github - 6429 LE (78%), 20
MHz, сама логика 34 MHz (без дебагера), 949 warnings (у меня
796), MCU 19 warnings (с дебагером было 45). Что-то не так с
настройками программатора в проекте, прошил со своего проекта.
18x
Ускорил до 44 МГц (упростил текстмод, условия адресации ОЗУ и
др.), сама логика влезает в 52 МГц (в 56 МГц в другой сборке).
В отладчике на экране случайно проскакивают символы (до моих
изменений не проскакивали). Экран отладчика перекидывается
целиком, блоками по 64 байта. Мигают одни и те же буквы, которые
отстоят друг от друга на 64 - в младших адресах все 0 или все 1.
Символы берутся из соседнего блока по 64. textbuffer_rd_addr и
textbuffer_clk - регистры. Причём буква выводится неправильно
целиком, хотя считывается несколько раз (на каждой строчке).
Пробовал поставить ещё регистры - не помогает. Проблема из-за
разных клоков чтения и записи в textbuffer. Исправил.
С версии 16.10.2024 cmosbuf пишет время в MCU, а в FPGA не
пишет. Исправил.
21x
Убираю использования negedge pixel_clock - не работает Fatall.
Делаю при этом обработку hardware_reset по pixel_clock -
исправилось. Но при этом сломалась запись в часы и память часов.
negedge pixel_clock осталось только в сигналах самой памяти.
Убрал. В часах показывается не текущая ячейка, а адресованная
раньше (не относится к ячейкам со временем). Исправил
тактированием cmosram от pixel_clock. Сломалось чтение из памяти
cmos (0, если возвращать просто номер ячейки, читаются только
ячейки со временем).
Оптимизировал условия сигналов памяти и видеоконтроллер. Уже
6757 LE, 25% device routing resources.
22x
Переношу i2c в домен pixel_clock. Несколько раз переставал
работать даже начальный экран (видимо, синхронный i2c добавил
лишние такты).
Починил чтение из памяти cmos и запись в часы (всё по posedge
pixel_clock).
Сломалось прерывание (на T80 тоже). Исправил (сброс номера
строки не там).
23x
Сломались видеорежимы - починил.
С процессором T80 не грузится NedoOS - виснет после
монтирования. Зависание может быть на OS_SETSYSDRV и далее в
FatFS. Дело в том, что я упрощал мукс шины данных. Попробовал
вернуть порты без промежуточного регистра - на T80 стала
грузиться NedoOS. Оставил без регистра только spi - не работает.
Добавил kempston и cmos - не работает. Вместо них betadisk - не
работает. AY, kempston, betadisk, spi - не работает. Без AY, но
с мышью - не работает. Всё, кроме неиспользуемых портов чтения
страницы - не работает. В других комбинациях тоже. Требует
именно все ветки. Видимо, непредсказуемые глюки из-за
асинхронного дизайна. Слишком быстрая логика в одном месте даёт
проблемы в другом.
При зависании крутится явно не в адресах ОС.
Пробовал включить 57 МГц для процессора. Не работает.
Пробовал включить 28 МГц всегда. Сломался доступ к SD-карте.
Пробовал сделать его без задержки - вылетает Fitter. Взамен
убрал IDE - сломался i2c. Вернул старый i2c - вылетает Fitter.
Вернул оба - рекорд, TV80 собрался на 50 МГц (остальное на 44),
но SD-карта не работает.
Перевёл части схемы на dvixel_clock (57 MHz). Буфер портов
перевёлся нормально (может и на 129 MHz), но SD-карта всё ещё не
работает.
24x
Перевожу память на dvixel_clock. Чтобы соблюсти фазы, сделал
везде negedge (по нему меняется счётчик). SD-карта работает.
6912, 16с: рамка отстаёт на 1/2 пикс - исправил.
textmode: момент переключения атрибута отстаёт на 2 пикс -
исправил, но теперь чёрный бордер.
Процессор в некоторых сборках сбоит даже на 3.5 МГц.
В некоторых сборках вообще нет экрана.
ВГ93 не работает на запись и чтение. ВГ93 оказалась по
pixel_clock, ещё и с использованием negedge. Перевёл на negedge
dvixel_clock. Чёрный экран (проц работает! отладчик работает!
бордер работает!)
Вернул в ВГ93 pixel_clock, но только posedge. Экран вернулся.
При попытке чтения из ВГ93 процессор подвисает на 3f27, спасает
только сброс, и то реагирует не каждый раз.
25x
Сделал вместо ВГ93 затычку. Число warning'ов сократилось раза в
два. Но всё равно чёрный бордер.
Попробовал поставить стабильно 28 МГц на процессоре - нет
экрана, проц не работает.
Попробовал поставить стабильно 14 МГц на процессоре - нет
экрана, проц не работает.
Попробовал вместо защёлкивания по posedge pixel_clock
защёлкивание по negedge dvixel_clock - нет экрана, проц
работает.
Убрал буфер бордера. Бордер появился, но чёрный экран (а в
текстмоде все символы равны 0, атрибуты нормальные).
То же с постоянным 28 МГц - нет экрана, проц не работает.
Вернул гибкую частоту - нет экрана, проц не работает.
То же без тормозов от ВГ93 - чёрный экран, проц не работает.
Казалось бы, почему могут исчезать и искажаться экранные
сигналы? Они же привязаны только к dvixel_clock! Похоже, нельзя
синхронизировать по 0-му разряду предделителя (т.е. по
dvixel_clock) и при этом использовать 1-й разряд предделителя -
они в рассинхроне. Сделал отдельный счётчик от 0-го разряда,
именно по нему переключаются фазы памяти. Заработало.
Вернул буфер бордера и атрибуты. Поставил постоянное 28 МГц с
фазы памяти. Проц не работает.
Поставил постоянное 28 МГц с предделителя (какая разница, когда
оно потом защёлкивается по dvixel_clock?). Проц работает,
SD-карта не работает.
Сделал чтение SD-карты мимо буфера портов. Не загружается даже
начальный экран.
Поменял в паре мест pixel_clock на dvixel_clock. Проц работает,
SD-карта не работает.
Слишком быстрае обращение к SD-карте? Сделал wait группами по 8
тактов 57 МГц (4 такта 28 МГц) (раньше wait в схеме не
использовался. wait в процессоре учитывается только в tstate[2])
- процессорный матрас.
Поставил 3.5 МГц - проц висит на адресе 0 (всё время ловит
wait?).
Поставил 14 МГц - процессорный матрас, проц чаще всего на адресе
38.
Поставил Т80 вместо TV80. То же самое.
Заменил wait на cen (clock enable, в него завёрнуты все
действия, был стабильно 1) - чёрный экран, проц чаще всего на
адресе 0. Как-то реагирует на сброс - пишет в порты.
Сделал cen в домене cpu_clk - проц бегает по всей памяти. Как-то
реагирует на сброс - пишет в порты.
Поставил 3.5 МГц - то же самое.
Убрал cen, вернул гибкую частоту - всё работает.
Подключил обратно ВГ93 (по pixel_clock) - в командере пишет NO
DISK, Fatall виснет при попытке записи.
28x
Пытаюсь убирать сигналы ВГ93, чтобы узнать, что влияет. Убрал
чтение из портов - висит по сброса, потом работает. Сброс
срабатывает не каждый раз (висит на 0).
Сделал синхронную дешифрацию адресов xxf7 по negedge
virt_cpu_clk (читаемые порты дешифруются по negedge
dvixel_clock, но они не должны сильно влиять на поведение
компьютера), вернул порты ВГ93.
CMOS отвалился (читаются только предзаданные ячейки и АЦП). При обращении к ВГ93 — NO DISK.
Почему не работает торможение процессора по cen? Это единственный правильный синхронный способ! В исходнике ничего подозрительного. Попробовал cen каждый второй такт. Процессор висит в 0, не реагирует на сброс. В исходнике сброс длится много тактов, заканчивается по команде. Сделал 5-битный счётчик — процессорный матрас. Заменил модуль vg93 на пустышку vg93fake — то же самое. Завернул внешние сигналы процессора (которые я делал) тоже в cen. Так сброс работает через раз (иногда пишет бред в порты).
Поставил всегда 57 МГц (cen на каждом втором такте). Работает меню, не работает сдкарта. Запись в бордер не всегда срабатывает.
Сделал cen в 3/4 тактов (эквивалентно 14 МГц) — сдкарта заработала.
Сделал эквивалентное 7 МГц по iocycle, иначе 28, убрал лишние сигналы пересинхронизации. Процессорный матрас.
Сделал всегда эквивалентное 7 МГц — иногда сбрасывается и работает (CMOS работает, запись в другие порты нестабильна).
Сейчас процессор в основном по posedge dvixel_clock, а остальное в основном по negedge dvixel_clock.
Переделал всё на posedge dvixel_clock — видеоконтроллер не читает память (начальную заставку тоже не показывает).
Убрал main_state_counter — видеоконтроллер заработал. Сброс и запись в порты (возможно, и чтение) нестабильны.
Сделал negedge virt_cpu_clk зависимым от cen не сейчас, а на момент posedge — то же самое.
Нашёл ещё синхронизацию от negedge virt_cpu_clk, заменил на posedge dvixel_clock — то же самое.
Сделал эквивалентное 7 МГц по iocycle, иначе 28 — то же самое.
Сделал эквивалентное 7 МГц по iocycle, иначе 57 — не работает (вертикальные цветные полосы).
Оптимизировал IncDecZ через I_DJNZ_reg.
29x
Перевёл cmosram и отладчик на posedge dvixel_clock.
Оптимизировал условия записи в регистры. Отлаживал в ModelSim. interconnect уже 20-22%. Fmax доходит до 50 МГц.
Design Space Explorer не может определить рабочую частоту и не пишет seed на ходу.
Пытался выделить регион для процессора (в Quartus 11 уже не так, как в 7) — не помогает ускорить. 35x10 не компилируется. При Auto всего 38 МГц (предлагает регион 15x13, минимум 15x11 — говорит, будет неоптимально).
Растактовка прерывания неправильная, сбивается делимость тактов на 4. Убрал Auto_Wait в захвате прерывания — количество тактов поправилось.
30x
Оптимизировал условие last_mcycle. В ModelSim всё развалилось (хотя реально работает). По идее несоответствие должно быть только на 3-м такте 1-го машинного цикла (там, где дешифрация команды), сделал там отдельное условие. В ModelSim нормально, хотя с иголкой между 3-м и 4-м тактами. Реально тоже работает.
Левый пиксель в hires не виден — исправил.
Сигналы с обратной логикой подписал _n.
На 3.5 МГц не работает клавиатура и виснет KOT. Формирование сигнала int синхронно и с учётом cen. Починился командер, но виснут тест клавиатуры и Fatall (бейсик на 3.5 MHz работает). KOT заработал, но не работает автосинхронизация бордера.
interconnect usage 19%
С T80 процессорный матрас (расчётная частота 32 МГц, а надо 57 МГц, а на TV80 расчётная всегда 42..50). Пробовал сделать отдельные цепи в регистрах для ex de,hl — почему-то 38 МГц (бывает и 45).
31x
Ещё оптимизировал расчёт last_mcycle.
Исправил пересчёт машинных циклов на командах с индексной адресацией (из битмаски делалось число, хотя нужна битмаска).
Перенёс incdec16 в такт 4 (было в 3, только sp в 4) — 46 МГц. Но теперь тормоза уже не в основных регистрах, а в шинах адреса и данных (где-то спрятана цепочка IR -> do), а ещё во флаге P.
Оптимизировал флаг P — теперь 50 МГц.
Сократил логику портов.
Сократил breakpoint_event (только 8 точек останова вместо 16) — 52 МГц.
Перенёс порт bf в posedge dvixel_clock — 57 МГц (впервые), но сброс иногда идёт не туда, Fatall и sd_boot вылетают.
Вернул tapein, добавил сброс dos — 54 МГц, но вообще всё сломалось.
Сделал dos за 1 такт (сразу в такте записи в порт bf или обращении по адресу), а не за 3 — 54 МГц, вылеты исправились, но бордер и сброс нестабильные, Fatall так и не заработал, хотя NedoOS работает.
Сделал 57 МГц с выкусыванием такта клока после детекта начала /MREQ. Не работает (вертикальные полосы, не реагирует на сброс, адреса тикают).
Сделал 28 МГц с разгоном до 57, когда не такт после детекта начала /MREQ. То же.
Сделал выкусывание асинхронно от начала /MREQ. Собралось на 55 МГц. Висит, ничего не пишет на экран, не реагирует на сброс.
Чтобы сделать во время начала /MREQ и при этом не вылететь из домена dvixel_clock, вытащил из процессора обещание /MREQ на следующем такте. Собралось на 55 МГц. То же самое.
Попробовал просто разрешить 57 МГц, когда не memcycle (сделал его на весь такт, но не проверил). Собралось на 56 МГц. Пишет бред в порты и память.
Попробовал привязать к cpuram_flag (сейчас счётчик выкусывания тактов независимый) — то же.
Сделал переключение megaturbo по сбросу и promisemreq перед каждым тактом mreq, даже с запасом (такты 1 и 2 (т.е. перед 2 и 3), кроме цикла iorq). То же самое.
Посмотрел в ModelSim — promisemreq выдаётся одновременно с mreq по заднему фронту clk, а по следующему переднему фронту clk принимается решение давить cen. По идее должно работать, но не работает.
ModelSim показывает, что процессор работает неправильно! Похоже, реально он работает, только когда нет двух тактов cen подряд.
Сделал тормозной last_tstate (так работает в ModelSim). 54 МГц. Всё так же не работает.
1xi
Проверил с подстановкой значений вместо памяти — работает и с бордером, и с экраном (на чтение и запись).
Сделал в отладчике показ не просто адресной шины процессора, а именно адреса команды.
Проверил со включенным прерыванием — не работает (чаще всего адреса ffxx — как он туда попадает? на 38 тоже бывает).
Но если подключить память, то она мгновенно забивается 00 3d.
Убрал сокращение rd,mreq в m1 — не помогло.
Сделал ret всегда на адрес 3 (вдруг не может прочитать из стека) — так работает.
Без прерываний, но с rst 0x38 — не работает.
Поставил стек в экран, чтобы видеть — пишет туда ерунду?
Сброс проходит нестабильно - что-то с первой командой.
Попробовал сдвинуть (первая di) - то же самое (сборка была на 60 МГц).
Добавил mreq в условие cen - то же самое.
Сделал ret всегда на адрес 6 - так работает и пишет в стек правильно, сброс стабильный.
Что-то не так с DI_Reg в last_tstate? (защёлкивается в tstate[2] по posedge clk, как и dinst - оба с учётом cen).
Добавил busak_n в условие защёлкивания в DI_Reg - не помогает, сброс опять нестабильный.
Попробовал сделать память стека во внутренних регах - так работает и пишет в стек правильно, сброс стабильный.
То же с задержкой на такт (в том числе для команд) - работает, сброс стабильный.
Что может быть не так с реальной памятью? в памяти задержка тоже на 1 такт!
Исправил cen_buffered - заработало в ModelSim. С rst 0x38 пишет неправильно. Заменил на nop - пишет во всю память нули (или читает ff?). Сделал запись чисел - пишет.
Обратно расширил promisemreq на tstate[2] - тест работает (но в ModelSim появляется лишний такт тормоза).
Вернул rst 0x38 - не работает на 57 МГц, сброс нестабильный (хотя собралось на 57 МГц).
Адрес выставляется в начале машинного цикла, ещё до mreq. После всех муксов он защёлкивается в начале tstate[2], тогда же и управляющие сигналы.
В конце tstate[2] защёлкивается результат - итого 2 такта от выставления адреса.
Пробую со снегом (у процессора приоритет над всем, когда mreq) - нестабильно работает даже на 28 МГц, пишет ерунду.
Попробовал имитировать задержку адреса на 2 такта в псевдопамяти - не работает на 57 МГц.
В ModelSim тоже так не работает, отрабатывают di, ld sp, а следующий код команды считывается 0x40 - с прошлого адреса (0003)!
- адрес 0004 выставился одновременно с m1, защёлкнулся в начале tstate[2].
- всё время tstate[2] didata читается 0x26 (правильно).
- в конце tstate[2] защёлкиваются выходные данные памяти - didata_r.
- в начале tstate[3] муксом формируется di - напрямую идёт в dinst, защёлкивается в IR в конце tstate[2]!!!
Попробовал сделать асинхронное чтение ОЗУ, без защёлкивания - не работает даже на 28 МГц.
Инвертировал cpuram_flag (для 3.5 МГц уже было правильно) - 28 МГц работает, 57 нет (не проходит сброс - вообще не переключаются адреса).
Сделал сброс некоторых сигналов в процессоре - теперь адреса щёлкают, но в память ничего не пишется (в порты пишется правильно, судя по палитре! а на 28 МГц неправильно).
Сделал promisemreq с учётом wr. На 57 МГц пишет, но работает нестабильно (сборка на 53). Запустилось демо Reset+D.
Оптимизнул mreq. На 57 МГц теперь работает почти всё, но глючит.
Сдкарта недоступна в 57 МГц.
Добавил скорость 14 МГц для работы с сдкартой. Глючит даже на сборках с Fmax=58 МГц.
Компьютер работает на 57 МГц (с тормозами в среднем полтакта на машинный цикл - эквивалентная частота 52 МГц), но глючит!
2xi
Лишний сброс при старте компьютера: процессор работает, на лету зашивается ПЗУ, потом сброс, и начинает работать отладчик. Это потому, что я раньше убрал команду "снять сброс" и заменил на счётчик. Вернул как было (теперь синхронно).
The Board не работает ни на какой скорости (включает hires). Это из-за замены поведения сигнала dos_n - сделано синхронно.
Попробовал по negedge - не помогло (сборка на 55). Попробовал по m1 (без mreq, но с учётом rfsh) - не помогло. Попробовал по фронту m1 - вообще не работает. Попробовал по фронту m1,mreq,rd (как было) - не помогло на 28, сломало 57. Вернул, как было вчера, только переписал по-другому - работает.
Fatall виснет на 57 МГц (на 28 работает).
Edge Grinder виснет на заставке. Это изменились условия записи в порты. Вернул полную дешифрацию dff7 - не помогло. Вернул старый код - не помогло и отвалилась SD-карта. С новой дешифрацией 7ffd - Edge Grinder не работает. Исправил 7ffd в сегодняшней версии - Edge Grinder работает на обоих частотах, но отвалилась SD-карта (сборка на 53). Заменил seed (сборка на 54) - SD-карта работает.
Сокращаю количество сложных сигналов, которые на грани влезания в 57 МГц.
Оптимизировал di ОЗУ (точнее, do внешней части процессора). 58 МГц, нестабильно, SD-карта не работает.
Сделал запись в основные порты через буферизацию всех сигналов - нестабильно, SD-карта не работает.
Сделал так все порты - нестабильно, SD-карта не работает.
Сделал сигнал memwr_n в процессоре - нестабильно, SD-карта не работает.
Учёл z80_to_ram_n = '0' в vg93_rd/wrtransaction - сборка на 59 МГц - нестабильно, SD-карта не работает.
Убрал оптимизацию do - сборка на 52 - нет SD-карты, 57 МГц не работает.
Попробовал через write_buf_negedge - сборка на 59 - нет SD-карты, в 57 в CMOS setup стрелки клавиатуры нажимаются глючно (в тесте клавиатуры норм).
Вернул порты по-старому - SD-карта работает, но 57 МГц глючит.
Сделал переключение мегатурбо по кнопке. The Board работает на 57 (если переключить на ходу). NedoOS не работает на 57.
Что-то с прерыванием или с переключением страниц?
Сделал dos_n по nededge - не помогло
Сделал dos_n по nededge и только m1 - помогло с Edge Grinder и NedoOS, но SD-карта не работает на 57, Fatall виснет на 57, даже если включить на лету.
Сделал 28 МГц при обращении к сдкарте на 57 МГц (31 такт).
Первая стабильная сборка на 57 МГц, но без ВГ93 и ZX-BUS, SD-карта только на 28 и ниже (p2666_megaturbo.zip)!
5xi
Добавил ebl_n (блокировка портов с шины) в дешифрацию при чтении портов. Исправил чтение внешних портов (не проверил).
Пробовал сделать чтение SD-карты в предыдущем такте — не работает.
Сделал SD-карту синхронно от dvixel_clock — работают не все сборки, причём после попытки доступа на 57 МГц SD-карта отваливается и на 28 МГц (сборка на 59 МГц). Сделал однократное чтение байта из SD-карты. Сборка на 57 МГц — SD-карта не отваливается (но и не работает на 57 МГц), 57 МГц работает нестабильно.
6xi
Похоже, задержки в 31 такт для SD-карты недостаточно, т.к. она работает байтами по 8 бит, каждый бит на 4 такта, а между операциями 12 тактов (в Fatall бывает даже 11 (out (77),a:out (57),a), остальные случаи по 16 между операциями, но в NedoOS по 12! как это работает на 28?).
Сделал 63 такта. Не помогло (сборка на 59 МГц).
Сделал начало задержки на 1 такт раньше — не помогло. После переключения частот в Fatall'е крутится на 71d0:
in a,(57):cp e:jr nz
(e=ff?).
Пробовал возвращать чтение SD-карты в мультиплексоре шины данных — это делает 57 МГц сильно ненадёжным, не помогает.
Попробовал читать данные из SD-карты не по адресу, а по всем сигналам (цикл iorq позволяет делать 2 такта) — не помогло.
На 57 fatall и sd_boot не работает, но NedoOS теперь работает (если 57 включать после всех mount).
x86.com вылетает в livin и digger (I для старта) в процессе (в эмуляторе не вылетает), один раз повесило систему на chess (1 для старта) и один раз в ratillery (в эмуляторе не вешает) (сборка на 61 МГц).
Пробовал sd_clock 28 МГц, а не 14 — SD-карта перестала работать на частоте процессора 28 МГц. 57 МГц нестабильное (сборка на 60).
Попробовал sd_mojno0 не после первого такта, а сразу, и сброс фазы sd_clock при обращении к порту — не работает.
Оставил только сброс фазы — стало как раньше.
Сделал все сбросы и выставления в одном такте с дешифрацией порта — ничего не изменилось.
Упростил условия формирования SPI без всяких sd_mojno — работает только на 28 (все эти сборки на Fmax=57 МГц и выше).
Сделал полную остановку процессора на 63 такта от момента обращения к SD-карте — работает (сборка на 58), но 57 МГц глючит.
Сделал полную остановку процессора во время приёма/передачи — работает всё (сборка на 56).
То же только в режиме 57 МГц — работает (нестабильная сборка на 61, 5806 LE).
28 МГц во время приёма/передачи — работает (сборка на 56).
Подключил ВГ93 — виснет при доступе к диску, не доходит до "no disk".
Сделал в ВГ93 запись в регистры синхронно от dvixel_clock — то же самое.
Заменил данные при записи в ВГ93 на buf_cpu_d — то же самое.
Исправил задержки в ВГ93 для dvixel_clock (вместо pixel_clock) — то же самое.
Убрал доступ ВГ93 в ОЗУ — то же самое.
SD-карта работает на 57 МГц (p2666_sdwait_56_stable.zip)!
7xi
Работа с диском в основном крутится на 3ef5:
in a,(ff):and c0:jr z,3ef5:ei:ret m:di:in a,(7f):jr 3ef5
(т.е. из ff читается 01111111 = {vg93_intrq, vg93_drq, 6'b111111}, как будто сектор никогда не заканчивается (нет intrq)).
Расставлял комментарии и _n в сигналах с обратной логикой.
8xi
Исправил работу с внешней шиной.
Переписал запрос от ВГ93 к памяти на negedge dvixel_clock. Не работает.
Переписал запрос от ВГ93 с использованием primisenomreq — не помогло.
Сделал проскакивание чтения байт в ВГ93 — виснет ли? Всё равно виснет, номер байта не тикает.
В это время стоит read_addr_flag=0.
Сделал костыль в чтении адреса — сразу выход. Показывает Disk Error.
Убрал проскакивание чтения байт — во время чтения гаснет экран, висит на sector=9, read_byte_number=0 (иногда 3).
Убрал только проскакивание тормоза, в чтении адреса сократил задержки под 57 МГц — всё как изначально.
Сократил задержки до минимума, заменил сигналы процессора в ВГ93 на буферизированные (синхронные с cs) — всё равно висит.
Вернул задержки для 57 МГц, сделал оба чтения синхронно от dvixel_clock — всё равно висит.
Сделал выдачу cs на один такт.
Сделал задержки для 57 МГц в чтении сектора, изменил порядок условий — всё равно висит.
Как будто cs вообще не приходит во время команды чтения адреса.
Исправил cs при rd — читает сплошные ff.
Сделал регистр данных ВГ93 всегда доступным на чтение, без синхронизации по cs — не помогло.
11xi
Сделал синхронизацию начала запроса ВГ93 по negedge — читает числа типа 0x74, 0x64, 0x24, 0x34 (сборки на 54 МГц).
Оптимизировал delay_vg. Вообще не работает — точки на загрузочном экране (все на D7). Пересобрал с другим seed (56 МГц). Точки исчезли. Читает те же числа.
Сделал сигналы запроса ВГ93 не регами, а логикой. Сборка на 56. Читает числа 0xf5 (возможно, также 0x75).
Переписал условие приёма данных для ВГ93. С этого момента практически все сборки на Fmax=57 МГц и выше. ВГ93 работает (читает и пишет), режим 57 МГц глючит.
Упростил циклы приёма и выдачи данных ВГ93 (ожидание просто счётчиком) — так чтение не работает. Вернул ожидание чтения процом, исправил negedge. Не работает запись. Вернул ожидание записи процом. Не помогло (сборка на 57). Вернул проверку захвата запроса (отработку запроса не проверяю — это 1 такт, всегда отрабатывается) — исправилось. Но ВГ93 не работает на чтение на 57 МГц (NO DISK, некоторое время было видно адрес 2f8f — вызывалка 48 из DOS, для break), хотя работает на запись (сборка на 55). Сделал в досе 28 МГц. ВГ93 полностью работает.
Сделал motor синхронно по dvixel_clock. Выдал cs ВГ93 на один такт, вернул 57 МГц в досе — не помогло. Поэтому оставил 28 МГц в досе.
59 МГц, 6458 LE (изначально было 7171, в github 6429 без отладчика), interconnect usage 19%.
3094 dhrystones/s.
Сделал promisemreq по posedge.
Перевожу I2C на синхронность. Расписал протокол.
ВГ93 работает (p2666_vg15.zip)!
Поделитесь вашим мнением о статье