PDA

Просмотр полной версии : Потактовый клон Денди на FPGA



HardWareMan
10.11.2016, 18:52
Здесь я буду выкладывать свои изыскания при построении тактово точной модели Денди для реализации в FPGA. Небольшой дисклаймер:

1. Не спрашивайте, для чего это мне, мне просто нравится этим заниматься. Не загаживайте тему, сделайте одолжение тем, кому будет интересно.

2. Вся фундаментальная информация взята с нашего проекта BreakNES (http://breaknes.com/), за что особая благодарность Org'у - он сделал львиную долю по распознаванию транзисторной схемы. Можно посмотреть записи стримов (https://www.youtube.com/user/Andorianin/videos), чтобы узнать, как он это делал. Без него этого проекта бы не было.

3. На данный момент у нас есть декап и транзисторная эквивалентная схема оригинальных NTSC микросхем CPU 2A03 и PPU 2C02 ревизии G. Поэтому, первичная модель будет оригинально NTSC, как USA NES или FamiCom. Но мы уже закинули в очередь декаперу PAL версии NES и, самое главное, 6527/6538 от нашей любимой Денди. Так что в итоге, после нахождения разницы, модель будет мультиформатной.

4. Система делается под разъем картриджей и будет 100% совместима с ними (в пределах родного региона и режима). Она будет содержать весь набор сигналов, который имеет оригинальная консоль.

5. Видеовыход будет сдвоенный, одновременно композит и S-Video. Причем, по всем правилам формирования сигнала оригинального PPU (для композита) и его адаптации под S-Video. Кому нужен RGB - пусть изменяют модель сами.

6. Так как система относительно сложная, то создание модели будет разбито на этапы. И в первую очередь будет запущен PPU, т.е. имея рабочий PPU можно уже ковырять CPU. На стадии обкатки модель будет прогоняться вот в этой приставке:
http://savepic.net/10183768m.jpg (http://savepic.net/10183768.jpg)
Не спрашивайте меня, где такую достать, сами догадаетесь. Отличительная особенность этого стенда в том, что набортная VRAM будет уже внутри FPGA.

7. В виду очевидных причин, данная модель будет обкатываться именно на FPGA фирмы Altera. Пользователи Xilinx будут адаптировать проект под свои системы сами.

8. Здесь я буду выкладывать свой личный опыт программирования ПЛИС. Моя философия может отличаться от вашей и/или описанной в книжках по xHDL. Смиритесь с этим.

Данный пост будет в будущем обновляться. Ну, вроде пока все, на первое время. Чтобы не загромождать тред, пожалуйста, спрашивайте строго по теме, остальные вопросы можно в соседнюю "Денди тему".

- - - Добавлено - - -

Итак, начинаем разбор PPU.

В сети гуляет вот такая картинка, выдранная из патента:
http://savepic.net/10189912.png
На ней абстрактно показаны самые важные узлы PPU. Я буду придерживаться данной блок-схемы, насколько это возможно.

Блок #1: Выбор регистра PPU. (http://zx-pk.ru/threads/27091-potaktovyj-klon-dendi-na-fpga.html?p=891182&viewfull=1#post891182)
Блок #2: Системные регистры PPU. (http://zx-pk.ru/threads/27091-potaktovyj-klon-dendi-na-fpga.html?p=891822&viewfull=1#post891822)
Блок #3: Синхрогенератор PPU. (http://zx-pk.ru/threads/27091-potaktovyj-klon-dendi-na-fpga.html?p=933194&viewfull=1#post933194)
Блок #4: Управление локальной шиной PPU. / Мультиплексор шины данных PPU. (http://zx-pk.ru/threads/27091-potaktovyj-klon-dendi-na-fpga.html?p=933323&viewfull=1#post933323)

HardWareMan
11.11.2016, 16:54
PPU это Picture Processing Unit. Т.е. видеоадаптер, если упростить. Изготавливается в корпусе DIP40. УГО для PAL/NTSC PPU можно нарисовать вот так:
http://savepic.net/10169432.png
Здесь, условно слева это сигналы связи видеопроцессора с центральным процессором системы, а справа это сигналы связи с личным адресным пространством PPU. Как правило, эту память называют VRAM/VROM, где V означает Video. В терминологии конкретно к приставке NES/FC/Dendy часто применяют CHR RAM/ROM, т.е. CHaRacter RAM/ROM. Пробежимся вкраце по сигналам.
Dn - Шина данных связи с CPU.
An - Шина адреса связи с CPU, эти сигналы выбирают один из 8 внутренних регистров PPU.
R/W - Сигнал направления шины данных, если здесь лог.1 то происходит чтение (Dn - выход) иначе происходит запись (Dn - вход).
STB - Сигнал стробирования данных на шине, активный уровень лог.0.
CLK - Тактовый сигнал, для композитного варианта PPU частота этого сигнала строго в 6 раз больше поднесущей цвета выбранной системы.
NMI - Сигнал запроса прерывания, вырабатывается сразу как только закончился активный растр, если данный сигнал разрешен в управляющем регистре PPU.
RES - Сигнал сброса PPU, активный сигнал лог.0. Во время сброса растр не генерируется.
EXTn - Интересный порт. Он позволяет соединить 2 PPU для генерации общей картинки. В NES/FC/Dendy эта функция не используется и эти сигналы заземлены. Однако, случайное включение бита управления сжигала PPU.
PADn - Это мультиплексированная шина из младших 8ми бит адреса видеопамяти и 8ми бит данных этой же видеопамяти.
PAn - Старшие биты адреса видеопамяти.
PRD - Сигнал строба чтения данных из видеопамяти, активный уровень лог.0.
PWR - Сигнал строба записи данных в видеопамять, активный уровень лог.0.
PALE - Сигнал защелкивания младших 8ми бит адреса видеопамяти, активный уровень лог.1. Выделение младших бит адреса видеопамяти можно производить обычной прозрачной защелкой, вроде x4x373 (ИР22).
VIDEO - Аналоговый выход композитного видеосигнала. Относительно высокоомный выход, поэтому как правило нагружен на каскад с ОЭ, причем, на PNP транзисторе, чтобы не было сдвига уровня.
VCC - Питание, 5в.
GND -Питание, земля.

Подробнее о сигналах будет при обсуждении блоков, которые обслуживаются или генерируют их, соответственно.

HardWareMan
12.11.2016, 06:02
Я хочу, чтобы данный туториал подходил для самых маленьких детей. (с) stalker29218 Поэтому, необходимо дать некоторую базу по цифровой электронике. Есть разные технологии цифровых микросхем, во многом они похожи. Я не буду описывать, как работает базовая логика. Практически одинаково во всех технологий, а кому интересно я рекомендую очень хороший справочник, который называется "Популярные цифровые микросхемы", за авторством В.Л.Шило из серии МРБ выпуск 1111.

Так вот, логику мы опустим. Мы будем рассматривать ключевой момент - хранение состояния, в народе триггеры. Построение триггера сильно зависит от технологии. Что такое триггер? Это элемент с двумя устойчивыми состоянии. В простейшем случае это кольцо из двух инверторов:
http://savepic.net/10173528.png
Однако, практической пользы от него нет - им не возможно управлять, не вызвав короткое замыкание одного из выходов. Поэтому, обычно используются многовходовые элементы с инверсией (без разницы И или ИЛИ):
http://savepic.net/10171480.png
Это простейший RS триггер. Он уже может быть полезен, например, для подавления дребезга ответственной кнопки. Однако, у него есть недостаток: если активировать оба входа управления возникает неопределенное состояние. Поэтому, к нему добавляется простейшая схема управления:
http://savepic.net/10161240.png
И триггер обретает сигнал строба. Это позволяет ввести нечувствительность RS триггера к изменению на входах R или S во время изменения сигнала. Замечу, что это не тактируемый тригер, а обычная прозрачная защелка, поэтому, во время активного сигнала управления неопределенное состояние все еще может возникнуть. Поэтому, сигналы R и S объединяют через инвертор и получается D триггер:
http://savepic.net/10159192.png
Это схема классической прозрачной защелки. Иногда прозрачность защелки вредна: если выходной сигнал завязан на вход, то схема при активации защелки станет осцеллировать, вызывая непредсказуемые состояния логики. Для развязывания выхода от входа нужен тактируемый триггер. Обычно, это цепочка ведущий-ведомый из двух защелок:
http://savepic.net/10165336.png
Теперь, ведомый получит сигнал от мастера тогда, когда мастер станет нечувствительным ко входу. И наоборот, ведомый будет не чувствителен к изменению состояния мастера когда мастер управляется извне. Это классический тактируемый триггер (Т триггер). Если объединить R и S входы через инвертор, как это сделано у D триггера, то получаем тактируемый D триггер. Если нам нужен тактируемый D триггер с ассинхронными входами сброса и установки, то нужно вводить дополнительные ведущие RS триггеры:
http://savepic.net/10218587.png
Вот так сложно дается базовый элемент синхронной схемы на технологии ТТЛ. Вот этот же примитив в схемном вводе Quartus'а:
http://savepic.net/10216539.png
Очень расточительно расходуется пространство кристалла: по нескольку транзисторов на каждый субэлемент примитива. Но все изменилось, когда пришла КМОП технология. Среди разных достоинств этой технологии есть одна ключевая, которую имеют только полевые транзисторы: большое сопротивление затвора и большой диапазон изменения сопротивления канала (от практически короткого замыкания, до практически полной изоляции). Поэтому, в некотором смысле каждый транзистор КМОП структуры можно рассматривать как управляемый тумблер:
http://savepic.net/10221659.png
Всего два разнополярных транзистора позволяют организовать Z состояние выхода (электронный ключ):
http://savepic.net/10219611.png
Причем, при определенных условиях питающего напряжения, это позволяет коммутировать даже аналоговый сигнал. Яркий пример - К561КП2 в Вега МП122 или К176КТ3. Даный ключ (на картинке блок "КК") позволяет очень просто построить триггер:
http://savepic.net/10213467.png
Действительно, нет ничего проще, чем просто разорвать кольцо из инверторов. Это схема полноценного тактируемого D триггера с асинхронными входами сброса или установки. Если они не нужны, то вся схема упрощается до 2х инверторов и 2 ключей на каждый RS триггер (всего 8 транзисторов на RS триггер). Сравните с ТТЛ вариантом.

Есть еще кое-что в технологии КМОП, что наследуется из особенностей полевых транзисторов. Ключевой недостаток полевого транзистора вытекает из его достоинства: из-за большого сопротивления затвора паразитная емкость последнего начинает иметь значение. Таким образом, если вдруг затвор полевого транзистора повиснет в воздухе, то его затвор будет сохранять заряд некоторое время, что будет эквивалентно подаче управляющего сигнала. Это очень похоже на ячейку DRAM. И этим же воспользовались инженеры, которые проектировали микросхемы КМОП на заре электроники.

Действительно, если допустить, что паразитной емкости затвора достаточно для хранения заряда в пределах периода тактовой частоты и недостаточно, чтобы исказить (затянуть фронт) форму сигнала при переключении, то транзистор с оторванным затвором можно рассматривать как элементарную ячейку DRAM, которую периодически следует регенерировать. А если еще допустить то, что нам не требуется, чтобы ток тек в обоих направлениях, то управляющий ключ упрощается до одного транзистора. Таким образом, мы получаем триггер-защелку всего из трех транзисторов (транзистор разрывающий затвор ключевого транзистора, сам ключевой транзистор и транзистор-нагрузка, если не требуется ОС):
http://savepic.net/10212443.png
Причем, добавление всего одного транзистора позволяет организовать мультиплексор: на картинке выше сигнал OAM8 подключает один источник к триггеру, а сигнал OAP к другому. Конечно, такие схемы не будут статичными и будут иметь нижний предел рабочей частоты (верхний предел есть у всех). Но простота реализации и стабильная тактовая частота оправдывают это.

- - - Добавлено - - -

Я думаю, многое теперь понятно. Теперь ключевая особенность ПЛИС. Особенность ПЛИС в том, что они могут менять эквивалентную логическую функцию в зависимости от "программы" пользователя. Это не копия дискретной схемы в прямом смысле, это функциональная симуляция. Конечно, можно создать ASIC на основе описания схемы посредством xHDL языка (для чего этот язык и создавался) и это будет либо транзисторная копия, либо функциональная, созданная из примитивов библиотеки CELL. Но это может быть применено только на стадии выпуска готовой схемы. На стадии разработки требуется многократное реконфигурирование. И только из-за этого приходиться мириться с некоторыми ограничениями любой ПЛИС, от CPLD до FPGA. Более подробно как сделаны ASICи на основе CELL можно подсмотреть у Org'а на PSXDev (http://psxdev.ru/news).

Реконфигурируемые ПЛИС выдвигают определенные требования к дизайну (так называется проект функциональной схемы, описываемой на языках xHDL либо схемным вводом). Особенность ПЛИСин в том, что они состояит из базовых блоков, в состав каждого входит один (или несколько) триггеров, логическая программируемая матрица (в старых CPLD и FGPA) или LUT (Look-Up Table в новых CPLD и FPGA) и несколько вспомогательных схем, вроде схемы выбора тактирования триггера или ускоренного переноса для организации сумматоров и счетчиков. LUT позволяет "запаковать" целый кусок логической комбинаторной схемы по построенной синтезатором таблице истинности, что положительно сказывается на "вместимости" микросхемы ПЛИС. Вот так выглядит ячейка у CPLD семейства MAX3000:
http://savepic.net/10199131.png
А вот так у FPGA семейства Cyclone IV:
http://savepic.net/10200155.png
Все ячейки связаны между собой магистралями. Это PIA (Programmable Interconnect Array) у CPLD и просто LAB Interconnect у FPGA. И вся соль в том, что именно эти магистрали и дают ту самую гибкость при построении эквивалентной схемы. Однако именно они и являются самым главным недостатком.

Во-первых, ее емкость конечна. У CPLD PIA общий для всех LAB, поэтому, даже простую схему, требующую большое количество соединений в CPLD бывает не уместить. У FPGA магистрали разбиты на категории: локальная, глобальная горизонтальная и глобальная вертикальная. Это дало больше свободы, однако ограничения всегда есть.

Во-вторых, "растекание" схемы по ячейкам. И если на входы одной ячейки подаются сигналы от других, находящихся на разном расстоянии, то сигналы могут прийти с разной задержкой. Она не большая, однако быстродействия ПЛИС хватает, чтобы среагировать на нее. И все это зависит как от синтезатора и компилятора, так и (наверное в большей степени) от фиттера (программа, которая планирует в какую ячейку какую часть схемы положить). Конечно, в каких-то пределах можно влиять на процесс, например можно указать границы района, куда следует расположить отдельный модуль (и фиттер поругается, если ему не хватит ресурсов этого региона) или допустить локальное дублирование кусков схем, если позволяет место.

В любом случае, при программировании ПЛИС следует стремиться строго к синхронному дизайну, и тогда многие грабли просто не появятся. По моим личным наблюдениям, комбинаторику следует синхронизировать не далее 2го уровня (вложенность логических функций), стараться не допускать появления защелок (latch'ей, Quartus сам предупредит об этом в логе). Почаще заглядывать в RTL Viewer, чтобы проконтролировать, правильно ли понял вас синтезатор. В общем-то, это все и так описано в соответствующих книгах.

- - - Добавлено - - -

И на последок напомню, что исходная схема у нас построена на прозрачных защелках, а в ПЛИС следует использовать синхронный дизайн. Наличие защелок в дизайне ПЛИС (кроме специально созданных) может привести к метастабильности, а это в свою очередь приведет к неработоспособности схемы. Конечно, после просмотра RTL можно прогнать модель в симуляторе (это либо встроенный в Q9.x.x для ограниченного набора ПЛИС, либо ModelSim для любого другого Quartus'а и семейства ПЛИС), но проще всего это проверка в железе. Тем более, там можно использовать логический анализатор (как дискретный, что предпочтительно, так и встроенный в ПЛИС SignalTap). О каждой особенности переноса схемы будет указано в процессе обсуждения каждого блока PPU позже.

Надеюсь, теперь многое станет понятней.

Vslav
12.11.2016, 09:05
Есть еще кое-что в технологии КМОП

А препарируемая Денди разве КМОП-истая? Если судить по рисунку топологии, то похоже на n-МОП.



Таким образом, мы получаем триггер-защелку всего из трех транзисторов

Это было очень удобно, просто и выгодно для разработчиков оригинальной схемы. И это же настоящее проклятье при переносе на ПЛИС :)

HardWareMan
12.11.2016, 12:49
А препарируемая Денди разве КМОП-истая? Если судить по рисунку топологии, то похоже на n-МОП.
Ну КМОП это Комплементарный МОП. Т.е., когда имеется оба транзистора. N-МОП всего лишь упрощение для исключения создания P кармана, что дороже и занимает место (между границами диффузии нужно пространство). Так что, технически, я используя КМОП имел в виду x-МОП в целом. И, кстати, именно потому что она n-МОП у нас и идет третий транзистор - активная нелинейная нагрузка. Был бы полный КМОП это был бы P транзистор (верхнее плечо).

Это было очень удобно, просто и выгодно для разработчиков оригинальной схемы. И это же настоящее проклятье при переносе на ПЛИС :)
Именно. Современные схемы компилируются из CELL библиотек и полностью комплементарные. Все-таки полный КМОП работает быстрее и стабильнее. Ну и сам техпроцесс, видимо, сильно шагнул вперед и теперь нет особой проблемы в создании P кармана в подложке.

Titus
12.11.2016, 13:52
Причем, добавление всего одного транзистора позволяет организовать мультиплексор: на картинке выше сигнал OAM8 подключает один источник к триггеру, а сигнал OAP к другому. Конечно, такие схемы не будут статичными и будут иметь нижний предел рабочей частоты (верхний предел есть у всех). Но простота реализации и стабильная тактовая частота оправдывают это
Кстати, хорошо бы пояснить, почему схема не может быть статичной)

x86128
12.11.2016, 13:58
А разве абзац про паразитную емкость затвора это не ответ? Я в КМОП деле нуб, но именно так и понял текст.

HardWareMan
12.11.2016, 15:55
Небольшое дополнение к посту про синхронность.

Правильный синхронный дизайн, задуманный сразу таким, как правило не вызовет каких-либо подозрений у синтезатора и он не будет ругаться. И даже если фиттер раскидает его по всему кристаллу, он все равно будет работать при разных условиях, если рабочая частота будет ниже той, что рассчитает TimeQuest в отчете FMax Summary. Однако, бывают ситуации, когда применение латчей в синхронном дизайне неизбежны, особенно, когда проект переносится с железа, вроде нашего случая. Здесь нам поможет гейтирование тактового сигнала - особой схемы внутри логического элемента ПЛИС:
http://savepic.net/10217562.png
Этот узел можно увидеть на картинках логических элементов выше. Он сделан специально и имеет защиту от метастабильности. В Верилоге этот вывод задействуется, если в списке чувствительности блока always будет более одного элемента. Однако, лично я не люблю когда always блок содержит что-то еще кроме тактовой частоты. Старайтесь обходиться только одним параметром. Так вот, мы можем использовать этот вывод как вход LE защелки, единственное условие это наличие более высокой тактовой частоты. В этом нам повезло: ядро PPU работает на частоте пиксельклока, что ровно в 4 раза меньше от входной частота для NTSC PPU и 5 раз выше для PAL версии. Таким образом, вот так мы эмулируем прозрачную защелку в синхронном дизайне:
http://savepic.net/10215514.png
Так же, в реальном мире используются часто RS триггеры из прошлого поста. Почему? Как правило, это сделано для синхронизации внешнего события к внутреннему распорядку схемы, которая живет строго по тактовой последовательности. В случае с PPU это интерфейс CPU. Действительно, даже при общей главной тактовой частоте, делители для ядра PPU и ядра CPU изначально разные. Каждое ядро работает на своей частоте и строго не синхронно на своем уровне. При этом, более медленное может пропустить событие от более быстрого. И вот здесь выручает RS триггер, который срабатывает практически мгновенно от внешнего сигнала и сохраняет свое состояние, пока внутреннее ядро не опознает сигнал и не среагирует на него. Оно же и снимает запрос с триггера. Выглядит это примерно вот так:
http://savepic.net/10221658.png
Здесь: зеленый это фронт тактовой частоты ядра, красный - ее спад. А набор W сигналов это управление извне. Нас интересует комбинаторное кольцо из элементов DATACTR_NOR3/4. Видно, вход S (вверху) синхронизирован к спаду тактовой частоты ядра, вход R подключен ко входному сигналу. Как это работает: лог.1 на W6_2 сбросит триггер и на верхнем элементе будет 1 а на нижнем 0. Этот 0 подается на NOR но так как W6_2 все еще действует, NOR будет продолжать выдавать лог.0 на защелку, которая будет повторять этот сигнал до синхронного тригера. Лог.0 на выходе уже синхронного триггера не может повлиять на исходный RS триггер потому, что на входе элемент AND. Так будет продолжаться до тех пор, пока W6_2 не уйдет в лог.0, сигнализируя об окончании запроса. Теперь 2 лог.0 (один со входа и другой с триггера) вызовут появление лог.1 на входе защелки, которая пробросит эту единичку на синхронный триггер. Этот триггер щелкнет такт и запишет эту единичку, которая вернется на вход S и при спаде тактовой частоты сформирует импульс длинной в пол периода таковой частоты, который вернет RS триггер в исходное состояние. Триггер обнулит нижний NOR и следующим тактом синхронный триггер запишет 0, а предыдущая лог.1 продолжительностью ровно 1 такт при этом уйдет в схему дальше. Вот так незатейливо сделана синхронизация по спадающему фронту не синхронного управляющего сигнала. По спаду обычно синхронизируют запись, т.к. данные следует сначала получить во входной буфер, а потом уже обработать. При чтении синхронизация может быть сделана по фронту, но сути это не меняет. Однако, Quartus'у это не нравится:
http://savepic.net/10219610.png
И это справедливо: мы нарушаем закон синхронности дизайна. А при этом корректная работа схема не гарантируется. Она может работать, но будет зависеть от фазы луны: чуть что-то добавил или исправил и все тайминги поехали. Когда я делал схемную интерпретацию схемы PPU влоб, чтобы получить хоть что-то наглядное и работоспособное, иногда приходилось вставлять задержку в одну ячейку (примитив LCELL), заставляя удлинять путь сигнала, чтобы тот приходит тогда, когда надо. Это не правильный путь, но это пока и не требовалось. Далее, схема потихоньку кромсалась, переводя тайминги в синхронный режим. И комбинаторное кольцо выше с помощью трюка повышенной частоты (напомню, у нас есть 4х или 5ти кратная частота от ядра) этот узел стал вот таким:
http://savepic.net/10209370.png
Здесь, зеленый все тот же позитивный пиксельклок, синий это повышенная частота. Функционал схемы работает так: пока W6_2 равен лог.0, сигнал на входе у нашей импровизированной защелке будет зависеть от выхода элемента OR, т.к. на нижнем выводе элемента AND будет лог.1 Элемент OR пропустит единичку либо с выхода защелки либо с выхода синхронного триггера, но в данный момент на синхронном триггере будет 0 а в защелке 1. Это устойчивое состояние, которое обновляется каждый такт повышенной частоты. Как только сигнал W6_2 станет лог.1, элемент AND обнулит свой выход из-за инверсии сигнала W6_2. Защелка запишет лог.0 на следующем такте (получается синхронный сброс) и дальше схема будет ждать деактивации сигнала W6_2, прямо как в предыдущем варианте схемы. Как только W6_2 станет равен лог.0, лог.1 появится на входе синхронного триггера, но на выход она попадет только строго по такту пиксельклока. Таким образом, элемент AND опять станет пропускать сигнал с OR, но там оба 0, так что в защелке сохранится лог.0. Как только синхронный триггер запишет лог.1, она появится на элементе OR и попадет на вход защелки. И она запишет ее на следующем своем такте но из-за того, что ее частота гарантированно в 2 раза выше тактовой частоты синхронного триггера, то синхронный триггер ровно на своем следующем такте подхватит лог.0, который будет результатом NOR операции над лог.1 с выхода защелки. Сама защелка станет себя удерживать, подавая себе на ход свой выход через OR и AND, вызывая устойчивое состояние. Вот так, легким движением руки мы сделали синхронную защелку. На самом деле это очень красивое решение, которое на Верилоге можно записать так:


wire W6_2; // Входной сигнал
reg Str; // Синхронный триггер
reg Sgt; // Синхронная защелка
always @(posedge HClk)
begin
Sgt <= ~W6_2 & (Str | Sgt);
end
always @(posedge PClk)
begin
Str <= ~(Sgt | W6_2);
end
Это красивый и правильный путь, понятный нативно самой ПЛИС и инженеру-цифровику. Однако, многие из вас простые люди, либо программисты. Поэтому, вы, скорее всего, запишете вот так:


wire W6_2; // Входной сигнал
reg Str; // Синхронный триггер
reg Sgt; // Синхронная защелка
always @(posedge HClk)
begin
if (Str) Sgt <= 1'b1;
else if (W6_2) Sgt <= 1'b0;
end
always @(posedge PClk)
begin
Str <= ~(Sgt | W6_2);
end
Так, конечно, стало более понятно простому человеку, однако синтезатор начнет городить огород: закольцованные мультиплексоры. Вроде вот таких:
http://savepic.net/10213466.png
Схема остается строго синхронной. Макроблоки, создаваемые синтезатором (мультиплексоры, сумматоры и прочее), как правило, имеют оптимизацию на стадии компиляции под выбранное семейство ПЛИС, однако, если у вас примитивное CPLD, это может отобрать целую ячейку, когда простая ручная комбинаторика OR-AND укладывается в стандартную логическую матрицу даже примитивного по нынешним меркам семейства MAX3000. Так что мозги и правильное решение иногда позволит работать вашему проекту там, где обычные индусы будут требовать жирную FPGA.

Вывод из этого поста следующий: если вы собираетесь профессионально писать для ПЛИС, постарайтесь вникнуть в философию логики, изучайте состав сложных макроблоков. Они всегда описывались в советских справочниках и даже в зарубежной библии от TI - у меня есть такая, просто мегакнижка по х4ххх серии. Например, тот же мультиплексор это всего-лишь 2AND-OR цепочка, которая сможет быть свернута оптимизатором в один LUT гарантированно.

Vslav
12.11.2016, 17:22
Где-то опечатка, строго говоря:

Sgt <= ~W6_2 & (Str | Sgt);

Не эквивалентно:

if (Str) Sgt <= 1'b1;
else if (W6_2) Sgt <= 1'b0;

HardWareMan
12.11.2016, 18:13
Я же говорил, что некоторым будет не очевидно. Но давай разберем. Условия задачи таковы: если W6_2 = 1 то триггер сбрасывается (запись 0), если синхронный триггер Str = 1, то устанавливаться. Всего возможно 4 комбинации:

Str W6_2 Sgt
0 0 Хранение
0 1 0
1 0 1
1 1 Неопределенное состояние
Тут есть нюанс: четвертое состояние никогда не произойдет потому, что синхронный триггер срабатывает после деактивации W6_2. К тому же, у W6_2 есть приоритет: элемент AND стоит ближе к триггеру. Т.е., если использовать логическую функцию, то мы получаем инверсия W6_2 должна AND'иться с функцией Str OR Sgt. Или ~W6_2 & (Srt | Sgt); С другой стороны, если использовать if блок, то будем иметь каскад из двух условий, причем дефолт значение можно не писать, синтезатор сам настроит его на хранение.

И да, второй пример не совсем функционально аналогичен первому в виду того, что первый if блок имеет приоритет. Т.е., их следует поменять местами:


if (W6_2) Sgt <= 1'b0;
else if (Srt) Sgt <= 1'b1;

Вот тут я согласен, спасибо что поправил. Однако в рамках нашей модели будут работать оба варианта, ибо синхронный триггер имеет лог.1 только 1 такт, сразу за деактивацией W6_2, что является результатом цикла записи ядра 6502 на частоте ~1,7МГц и он не успеет сформировать второй, т.к. ядро PPU работает на частоте ~5,2МГц.

PS Я не буду поправлять исходный вариант, чтобы данные сообщения имели смысл.

Vslav
12.11.2016, 20:06
Хорошо бы картинку осциллограмм из симулятора добавить. Будет нагляднее, кмк.

SegaBoy
12.11.2016, 21:43
... однако синтезатор начнет городить огород: закольцованные мультиплексоры ...


Есть предположение, что мультиплексоры появляются только в отображении RTL Viewer, тогда как Technology Map Viewer показывает совершенно идентичную картинку. В обоих случаях расходуются две логические ячейки с одинаковыми LUT и даже Fitter размещает их в одном и том же месте. Получается, различные варианты кода из примера выше синтезируются одинаково и разницы на осциллограмме быть не должно.

Поправьте, если я ошибаюсь.

58722

HardWareMan
13.11.2016, 00:05
Я закончил преобразовывать схемный ввод модели PPU в синхронную модель. Теперь я готов выкладывать все узлы сюда, с пояснениями. Моделька работает отлично, я даже убрал артефакт, присущий аппаратной реализации, правда он виден только если телевизор правильно настроен. Это узкая (1-1,5 пикселя) белая полоска слева от растра, на границе экрана. Вот как было => стало:
http://savepic.net/10222685.pnghttp://savepic.net/10216541.png
Процесс шел так: сначала я покромсал каждый блок в схемном вводе, приводя его к синхронному виду и избавляясь от второй фазы пиксельклока. Затем перевод в Верилог. Очень сложным оказался узел формирования адреса VRAM. Там лихо закручен сюжет со счетчиками, которые по совместительству еще и регистры. И вот хитросплетение переносов между разрядами счетчика в схемном вводе не вызывает сомнений у Quartus'а - варнингов вообще нет. А как только я описал их в Верилоге, так ТаймКвест сразу поругался на 5 цепей, что они якобы образуют комбинаторное кольцо. Попробуем проанализировать эту проблему позже. А сейчас отдыхать!

Titus
13.11.2016, 00:06
Моделька работает отлично, я даже убрал артефакт, присущий аппаратной реализации, правда он виден только если телевизор правильно настроен. Это узкая (1-1,5 пикселя) белая полоска слева от растра, на границе экрана
Не уход ли это от потактновой идентичности?)

HardWareMan
13.11.2016, 00:22
SegaBoy, 9й Квартус вот такой код:

if (W6_2) W6Req <= 1'b1;
else if (W6Done) W6Req <= 1'b0;
Развернул вот так (RTL):
http://savepic.net/10190941.png
http://savepic.net/10192989.png
А в карте технологии вот так:
[Изображение утеряно]
Красный трейс это выход W6Req, он на другой странице (Q9 разбивает схему мельче, чем Q10+). А выход открытого LUTа идет на его вход. И комбинация AND-OR это уже классический мультиплексор, который формируется вот так (MX4x1):
http://savepic.net/10204253.png
Быть может более свежий Квартус умнее, другого объяснения я не могу найти. Или выбрано не то семейство ПЛИС (правила меняются от семейства к семейству).

- - - Добавлено - - -

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

Titus
13.11.2016, 00:24
Titus, она меня раздражала. Но на растактовку патч не влияет - я просто синхронизировал выходной поток пикселей: часть сигналов гашения оказалось идет асинхронно и из-за небольшого лага просачивается пиксель с серым цветом.

Скриншоты есть? Это только в NTSC или в PAL тоже?

HardWareMan
13.11.2016, 00:31
Есть. Да везде, в том числе и китайских 6538. Правда ширина ее колеблется от модели к модели. Вот полные (я вставлял маркер в левый верхний угол тайла и смотрел как поплывут относительно него спрайты, это очень помогло при выравнивании фаз тактирования):
http://savepic.net/10216540.png
http://savepic.net/10215516.png
http://savepic.net/10217564.png
http://savepic.net/10162269.png
Сейчас все примерно вот так:
http://savepic.net/10159197.png
http://savepic.net/10158173.png
На цвета не обращайте внимания: сейчас там кривая быстрая RGB палитра. Про формирование настоящего выхода я расскажу в разделе про видео ЦАП.

Titus
13.11.2016, 01:14
Есть. Да везде, в том числе и китайских 6538. Правда ширина ее колеблется от модели к модели. Вот полные (я вставлял маркер в левый верхний угол тайла и смотрел как поплывут относительно него спрайты, это очень помогло при выравнивании фаз тактирования)
Странно, я такой полосы на своем клоне не помню. Хотя долго возился с ним, когда изучал Денди. Может забыл просто) Хотя, как такую забудешь)

HardWareMan
13.11.2016, 09:26
А вот ты меня заинтересовал. Она точно есть на оригинальной 2C02E (NTSC):
http://savepic.net/10204252.png
Ее нет на оригинальной 2C02G (NTSC):
http://savepic.net/10206300.png
Ее нет на клоне UM6528 (NTSC):
http://savepic.net/10205276.png
Она еле заметна на клоне UM6538 (PAL):
http://savepic.net/10202204.png
Она еле заметна на клоне HA6538 (PAL):
http://savepic.net/10211420.png
Вот такой не однозначный результат тестов. Так что нет: убрать полосу не есть отклонение от тактовой точности. :)

Vslav
13.11.2016, 10:01
убрать полосу не есть отклонение от тактовой точности. :)
+1, я бы сказал даже что это аналоговый артефакт, возникает вследствие неидеальности цифровой схемы.

HardWareMan
13.11.2016, 10:17
На самом деле, он возникает на стыке строки, где идет подготовка к сбросу горизонтального счетчика. Особенность PPU в том, он считывает графику спрайтов непосредственно перед отображением строки. А до этого, он делает поиск по списку своей памяти спрайтов и ищет те, что принадлежат следующей строке (т.е. должны выводиться на ней). А растактовка сделана так, что координаты сканирующих счетчиков 0:0 соответствуют левому верхнему углу отображаемого растра, а 255:239 нижнему правому. Превышение этих координат является служебной областью (гашение и синхронизация). Но в отличии от наших компиков, у рендера более сложный узел сдвига графики, т.к. имеется поточечный скроллинг. Я немного забежал вперед, все это вы узнаете позже. Очень простые и красивые решения, я вам скажу. Но это порождает необходимость переноса части циклов чтения VRAM до сброса счетчика. Добавьте еще то, что длина строки не кратна количеству циклов обращения - вот и вылазят аналоговые артефакты, который образуются из иголок от задержек.

Между прочим замечу один факт: у PPU работает конкретное состояние, потому что используются латчи. Т.е., например, счетчик должен иметь 4 состояния, они берут число 4 (3'b100) и когда счетчик его достигает - сбрасывают его. Счетчик не строго синхронный, ибо он на латчах, поэтому это ближе к нашим ИЕ5м, примененным в наших компиках. Схему сброса располагают поближе к счетчику, но все равно есть время распространения сигнала и задержки в элементе сравнения. В итоге есть иголочка. А если разрядов 9, как у PPU, то иголочка может быть приличной. Когда мы делаем полностью синхронный счетчик с синхронным сбросом, то если мы хотим чтобы он имел только 4 состояния, нам следует "заказывать" сброс на числе 3 (3'011), т.к. новое состояние применится только на следующем такте. В этом фундаментальное отличие между синхронной схемой и асинхронной.

Поэтому, по идее, следует скорректировать все цифры координат сигналов у PPU, но оно вроде и так работает, хотя это чревато добавлением лишнего такта в строку. Именно поэтому, у меня полоска была заметно шире чем в оригинале. Все это будем разбирать ниже.

Titus
13.11.2016, 10:38
Почему же тогда на некоторых клонах ее нет?
А на клонах на картинке она в разных местах?

HardWareMan
13.11.2016, 10:44
Клон отличается от оригинала. Хотя бы техпроцессом. Нет, ее позиция всегда в одном и том же месте относительно картинки. На тюнере она чуть смещается из-за переключения в режим PAL - там пропорции другие же.

Titus
13.11.2016, 11:08
Нет, ее позиция всегда в одном и том же месте относительно картинки. На тюнере она чуть смещается из-за переключения в режим PAL - там пропорции другие же.
На NTSC (первая твоя картинка) и PAL (остальные 2 с полосами) она принципиально в разных местах.

HardWareMan
13.11.2016, 11:19
В PALе, возможно, она перекочевала в CLIP_B область. В любом случае, это издержки схемы на прозрачных защелках с паразитной емкостью. В полностью синхронной схеме ее быть не должно.

Titus
13.11.2016, 11:23
В PALе, возможно, она перекочевала в CLIP_B область. В любом случае, это издержки схемы на прозрачных защелках с паразитной емкостью. В полностью синхронной схеме ее быть не должно.

Думаю, что в абсолютно точном клоне можно было бы предусмотреть опциональную ее реализацию)

Кстати, по твоим скриншотам стало понятно, как визуально сразу отличить PAL от NTSC. У PAL штриховка шахматная, у NTSC искосочная)

HardWareMan
13.11.2016, 12:02
Кстати, по твоим скриншотам стало понятно, как визуально сразу отличить PAL от NTSC. У PAL штриховка шахматная, у NTSC искосочная)
Я тебе больше скажу: у PAL поднесущая статична а у NTSC она постоянно ползет. Буржуи называют ее Dot Crawl (https://en.wikipedia.org/wiki/Dot_crawl). Только вот Crawl оно только в NTSC...

Titus
13.11.2016, 12:07
У PAL crawl видно, когда идет скроллинг) Тогда он очень Crawl)

HardWareMan
13.11.2016, 12:26
Не верно. Сетка поднесущей PAL стабильна относительно растра (так уж получилось, хотя по стандарту она должна изменяться на противоположную каждый кадр для компенсации искажений). А окрашенные точки это как вырезанные дырки, через которую эту сетку и видно. Таким образом, при перемещении большого подкрашенного объекта искажаются только его вертикальные грани. Маленькие же объекты искажаются практически полностью, т.к. ширина точки меньше ширины периода поднесущей PAL: соотношение 4,43/5,32. Таким образом, мы просто видим как искажаются все грани на картинке (любые комбинации переходов между цветами с участием хотя-бы одного оттенка цвета), но только в движении. Без движения все искажения статичны и не цепляют глаз (но они есть).

У NTSC он всегда crawl, поэтому искажения вертикальных линий почти не заметны, хотя там отношение еще больше: 3,58/5,25.

Titus
13.11.2016, 12:38
Ну так я про то и говорю, что на PAL этот муар от Dot Crawl, или как его назвать применительно к PAL'у еще, идет только в момент движения обьектов.

Думаю, что сетка стабильна на PAL, потому что вместо двух разных полукадров (четные/нечетные строки), чип выдает всегда один и тот же полукадр. Оно и к лучшему для глаз.

Vslav
13.11.2016, 14:59
Там схема в LogiSim нарисована, это вообще жесть, представляю сколько оно рисовалось :)

HardWareMan
13.11.2016, 15:12
Именно. Я помню в детстве у меня был вот такой ЧБ телевизор "Кварц":
http://s1921687209.narod.ru/00/tw/kwarc40tb306_4.jpg
Он максимально тупой и когда его кинескоп был новым показывал просто отменную по четкости картинку. И действительно, те Денди, что у меня были, а так же Спектрум показывал на нем без черезстрочности. Т.е., как сейчас модно говорить: 240р. Это когда оба поля одинаковые. Чтобы поля отличались, нужно чтобы количество строк в каждом полуполе отличалось. У нас есть сейчас только NTSC версия и там есть вот такой узел:
http://savepic.net/10172508.png
Я не знаю, зачем сделано именно так, но если запретить перекидываться триггеру по V[8] то NTSC тоже перестает crawl! :) Вот чему равен LINE5:
http://savepic.net/10167388.png
Основной: 1 0101 0100, корректирующий: 1 0101 0011, т.е. разница буквально на 1 пиксель.

- - - Добавлено - - -

Опять же, там стоит AND, и сократиться на 1 пиксель только строка пререндера, на которую указывает сигнал RESCL... Причем, в каждом втором кадре. Но эффект есть.

- - - Добавлено - - -

Vslav, это рандомная логика ядра 6502.

Vslav
13.11.2016, 15:17
Vslav, это рандомная логика ядра 6502.
Да неважно, я на нее просто посмотрел - у меня голова закружилась :) Просто мало с LogiSim работал, решил что нужно взять инструмент потолще. Но этап схемы в виде логических вентилей я обычно пропускаю. В-общем, использование LogiSim - новое слове в реверсе :)

HardWareMan
13.11.2016, 15:22
Vslav, это что, они вон первозыч (http://forum.emu-russia.net/viewtopic.php?f=13&t=4106&start=280) туда пихают... Но это уже оффтопик, хоть и близко к реверсу.

HardWareMan
15.11.2016, 23:03
Сегодня поговорим о первом блоке PPU: выбор регистра для чтения или записи. Почему он? Он единственный который в качестве входа использует внешние пины (со стороны процессора) и формирует внутренние сигналы. Вот так он выглядит в оригинальном схемном вводе:
http://savepic.net/10218591.png
Здесь: N_DBE это строб обращения, R_W это направление обращения (лог.0 - запись в PPU), A[2..0] - жгут адресных линий. Сюда же следует добавить вот эту защелку, которая сохраняет записываемые данные для внутренних нужд:
http://savepic.net/10162268.png
Собственно, здесь все просто. Адреса поданы на дешифратор, который преобразует 3х битный код в 8 сигналов. Эти 8 сигналов смешиваются с сигналами управления (N_DBE и R_W), от чего получается набор сигналов Rx и Wx. Первый означает чтение из регистра а второй запись в него. Не все регистры полноценны: некоторые доступны только на чтение а некоторые только на запись. Узел вверху на мультиплексорах это обычная перекидушка на эквивалентах защелок (помните, мультиплексор на 4х транзисторах?). Он устанавливается в конкретное состояние при чтении из регистра #2 - по сигналу R2, а перекидывается при обращении к регистрам #5 и #6, по сигналам R5_x и R6_x. Это двойные регистры, первый (#5) регистр прокрутки а второй (#6) регистр адреса VRAM для обращения процессора. Особенность PPU в том, что для рендера и для обращения процессором к VRAM используется один и тот же счетчик, так что обращаться к VRAM следует только во время кадрового гашения либо при отключенном рендере, иначе результат не предсказуем.

После чистки схема этого узла получается следующей:
http://savepic.net/10165340.png
В принципе, она практически не отличается от исходной. Однако она будет немного отличаться в Верилоге. Я объясню. Дело в том, что входные сигналы являются полностью асинхронными к внутренним сигналам и поэтому их надо синхронизировать. Как говорят в книжках: перевести в локальный (рабочий) тактовый домен. Так как сигналы полностью асинхроны к частоте ядра, то привязывать их можно только к главному мастерклоку - самой быстрой доступной частоте. Это гарантирует, что ядро не пропустит входящий запрос. В Верилоге это будет выглядеть так:

// Управление регистрами PPU со стороны CPU
module PPU_REG_SEL(
// Входные цепи
input Clk, // Тактовая последовательность
input [2:0]Adr, // Адрес регистра
input RnW, // Направление обращения R/W
input nSTB, // Строб обращения к PPU
input [7:0]DIn, // Входные данные
// Выходные цепи
output reg W0, // Запись в регистр #0
output reg W1, // Запись в регистр #1
output reg R2, // Чтение из регистра #2
output reg W3, // Запись в регистр #3
output reg R4, // Чтение из регистра #4
output reg W4, // Запись в регистр #4
output reg W5_1, // Запись в регистр #5/1
output reg W5_2, // Запись в регистр #5/2
output reg W6_1, // Запись в регистр #6/1
output reg W6_2, // Запись в регистр #6/2
output reg R7, // Чтение из регистра #7
output reg W7, // Запись в регистр #7
output reg [7:0]DOut // Выходные данные
);
// Внутренние регистры
reg [2:0]AdrR;
reg RnWR;
reg nSTBR;
reg Sel;
reg FlipR;
wire Flip;
assign Flip = W5_1 | W5_2 | W6_1 | W6_2;
// Логика работы проста
always @(posedge Clk) begin
// Синхронизируем сигналы
AdrR[2:0] <= Adr[2:0]; RnWR <= RnW; nSTBR <= nSTB;
// Декодируем
W0 <= ~AdrR[2] & ~AdrR[1] & ~AdrR[0] & ~RnWR & ~nSTBR;
W1 <= ~AdrR[2] & ~AdrR[1] & AdrR[0] & ~RnWR & ~nSTBR;
R2 <= ~AdrR[2] & AdrR[1] & ~AdrR[0] & RnWR & ~nSTBR;
W3 <= ~AdrR[2] & AdrR[1] & AdrR[0] & ~RnWR & ~nSTBR;
R4 <= AdrR[2] & ~AdrR[1] & ~AdrR[0] & RnWR & ~nSTBR;
W4 <= AdrR[2] & ~AdrR[1] & ~AdrR[0] & ~RnWR & ~nSTBR;
W5_1 <= AdrR[2] & ~AdrR[1] & AdrR[0] & ~RnWR & ~nSTBR & ~Sel;
W5_2 <= AdrR[2] & ~AdrR[1] & AdrR[0] & ~RnWR & ~nSTBR & Sel;
W6_1 <= AdrR[2] & AdrR[1] & ~AdrR[0] & ~RnWR & ~nSTBR & ~Sel;
W6_2 <= AdrR[2] & AdrR[1] & ~AdrR[0] & ~RnWR & ~nSTBR & Sel;
R7 <= AdrR[2] & AdrR[1] & AdrR[0] & RnWR & ~nSTBR;
W7 <= AdrR[2] & AdrR[1] & AdrR[0] & ~RnWR & ~nSTBR;
// Выбор регистра из пары
if (R2) Sel <= 1'b0;
else if (FlipR & ~Flip) Sel <= ~Sel;
FlipR <= Flip;
// Запоминаем данные
if (~nSTB & ~RnW) DOut[7:0] <= DIn[7:0];
end
// Конец модуля
endmodule

Для начала мы наберем наш PPU в виде отдельных блоков-модулей, а потом объеденим их под одной крышей, чтобы не плодить сущностей. Я думаю тут комментировать не надо, это действительно самый простой из модулей.

Titus
16.11.2016, 01:25
Особенность PPU в том, что для рендера и для обращения процессором к VRAM используется один и тот же регистр, так что обращаться к VRAM следует только во время кадрового гашения либо при отключенном рендере, иначе результат не предсказуем.
Можно поточнее про непредсказуемость? Что конкретно непредсказуемо, и какие могут быть результаты?

HardWareMan
16.11.2016, 11:59
Рендер начинает брать данные с другого места, а в моменты перезагрузок счетчиков восстанавливать некоторые адреса, мешая собственно самому CPU.

Titus
16.11.2016, 13:39
Рендер начинает брать данные с другого места, а в моменты перезагрузок счетчиков восстанавливать некоторые адреса, мешая собственно самому CPU.
Такая непредсказуемость будет у тебя в точности повторена в клоне?

HardWareMan
16.11.2016, 14:49
Titus, ессно, мы же повторим внутреннюю логическую структуру.

Titus
16.11.2016, 15:01
Titus, ессно, мы же повторим внутреннюю логическую структуру.
Ну мало ли, какие ты изменения вносишь)
Например, переводя все узлы схемы на синхронное выполнение, может чего и теряется индивидуалистичное)

HardWareMan
16.11.2016, 21:43
А как наличие общего счетчика может пострадать от перевода с двухфазной модели на однофазную синхронную?

s_kosorev
16.11.2016, 22:15
Убедил :) самого себя

OrionExt
17.11.2016, 22:52
А я бы начал с инициализации сего хитрого девайса. Это очевидно для профи. А чайники потом будут репу чухать. Тем более будет не лишним описать с чего, все стартует. И о блоках(чипа) немного.

Вроде по делу. Простите за мой ломаный английский.

HardWareMan
23.11.2016, 17:21
Сегодня мы разберем системные регистры. Это два регистра, с индексами 0 и 1, которые задают режим работы всего PPU. Собственно, регистры как регистры, сохраняют входящие от CPU данные, синхронизируют их с ядром PPU и выдают их этому ядру. Назначение бит этих регистров следующее:
Регистр #0:
D7 - VBL Разрешение генерации на ноге #19 сигнала низкого уровня после отрисовки растра, которая подключена ко входу NMI CPU (прерывание VBlank).
D6 --- Отсутствует
D5 - O8_16 Высота спрайтов, если 0 то 8 точек, если 1 то 16 точек.
D4 - BGSEL Старший бит адреса знакогенератора для тайлов фона (0ххх/1xxx).
D3 - OBSEL Cтарший бит адреса знакогенератора для спрайтов (0xxx/1xxx).
D2 - I1_32 Приращение адреса при достпуе к VRAM: 0 - 1, 1 - 32 (для рисования горизонтальных или вертикальных линий).
D1, D0 Выбор старшего адреса для таблицы имен тайлов фона (номер экрана), эти биты обрабатываются в формирователе адреса VRAM.
Регистр #1:
D7 - EmB Приглушение синих оттенков, буржуи называют это эмпфазисом, подробнее о нем будет при разборе видео ЦАП.
D6 - EmG Приглушение зеленых оттенков, буржуи называют это эмпфазисом, подробнее о нем будет при разборе видео ЦАП.
D5 - EmR Приглушение красных оттенков, буржуи называют это эмпфазисом, подробнее о нем будет при разборе видео ЦАП.
D4 - OBE Включение отображения спрайтов.
D3 - BGE Включение отображения фона.
D2 - OBCLIP Гашение столбца из левых 8 точек на плоскости спрайтов.
D1 - BGCLIP Гашение столбца из левых 8 точек на плоскости фона.
D0 - B_W Отключение вывода оттенков (Ч/Б вывод изображения).
Оригинальная схема "влоб":
http://savepic.net/10201183m.png (http://savepic.net/10201183.png)
Оптимизированная синхронная схема:
http://savepic.net/10212447m.png (http://savepic.net/10212447.png)
Функциональный аналог Verilog:

// Системные регистры 0 / 1
module PPU_SYS_REGS(
// Системные входы
input Clk, // Тактовая частота
input PClk, // Пиксельклок
// Управляющие входы
input W0, // Запись в регистр 0
input W1, // Запись в регистр 1
input [7:0]DBIN, // Данные
// Выходы
output reg I1_32, // Увеличение адреса +1/+32 (H/V)
output reg OBSEL, // Старший бит адреса знакогенератора спрайтов
output reg BGSEL, // Старший бит адреса знакогенератора фона
output reg O8_16, // Высота спрайтов (0 - 8 точек, 1 - 16 точек)
output reg VBL, // Разрешение прерывания VBlank
output reg B_W, // Режим Ч/Б (обнуление младших 4х битов индекса цвета)
output reg BGCLIP, // Гашение левого столбца 8 точек у фона
output reg OBCLIP, // Гашение левого столбца 8 точек у спрайтов
output reg BGE, // Включение фона
output reg OBE, // Включение спрайтов
output reg EmR, // Эмпфазис красного цвета
output reg EmG, // Эмпфазис зеленого цвета
output reg EmB // Эмпфазис синего цвета
);
// Промежуточные регистры
reg [4:0]W0R;
reg [7:0]W1R;
// Логика
always @(posedge Clk) begin
if (PClk) begin
// Запись значения в промежуточные регистры
if (W0) W0R[4:0] <= {DBIN[7],DBIN[5:2]};
if (W1) W1R[7:0] <= DBIN[7:0];
// Обновление значений
if (~W0) {VBL,O8_16,BGSEL,OBSEL,I1_32} <= W0R[4:0];
if (~W1) {EmB,EmG,EmR,OBE,BGE,OBCLIP,BGCLIP,B_W} <= W1R[7:0];
end
end
// Конец
endmodule

Обратите внимание, что я не использую тактовый сигнал PClk (позитивный пиксельклок) как сигнал чувствительности always блока. Промежуточная модель его именно так и использовала, но в строго синхронной модели этого быть не должно. Тактовая частота должна быть одна во всем дизайне. PClk же становится сигналом разрешения, длительностью строго в 1 такт главной тактовой частоты Clk и периодичностью нужные нам 4 такта для NTSC PPU (или 5 тактов для PAL PPU). Эта же тенденция будет сохраняться и для остальных блоков.

HardWareMan
18.12.2016, 16:57
Savepic сдох. Прежде чем перейти к следующему блоку, я попытаюсь восстановить картинки.

HardWareMan
21.12.2016, 13:47
Сэйвпик ожил, дублирую фотки себе, в теме буду хостить у себя на всякий случай.

HardWareMan
25.01.2017, 19:08
Руки дошли, схоронил все картинки. Готовлю следующую тему по мере сил и времени.

HardWareMan
21.10.2017, 10:07
Давно я ничего сюда не постил, а время то летит....

Блоки, входными сигналами которых были только внешние сигналы, закончились. Сегодня поговорим о сердце PPU: о синхрогенераторе. Это "сердце" PPU, он дирижирует остальными блоками.

Входные сигналы:
Clk - Главный тактовый сигнал
OBCLIP - Обрезание левой части экрана спрайтов
BGCLIP - Обрезание левой части экрана фона
BGE - Активация фона
OBE - Активация спрайтов
VBL - Разрешение запроса прерывания VBlank
R2 - Чтение регистра 2
nRES - Общий сброс PPU

Выходные сигналы:
PClk - Пиксельклок
ALEGate - Гейт ALE
[5:0]HNN - Синхронизированное атомарное состояние PPU
S_EV - Запуск процесса просмотра списка спрайтов
CLIP_O - Гашение левого столбца из 8ми точек экрана для спрайтов
CLIP_B - Гашение левого столбца из 8ми точек экрана для фона
O_HPOS - Запуск счетчиков координаты X спрайтов (позиция 0 спрайтов)
EVAL - Сброс счетчика OAMT и начало процесса обработки OAMT
E_EV - Инициализация схемы адреса для вычитания графики спрайтов
I_OAM2 - Сигнал очистки OAMT
PAR_O - Вычитывание графики спрайтов
VIS - Маска активного растра (графика выводится на экран)
F_NT - Чтение Name Table
F_TB - Чтение второго байта
F_TA - Чтение первого байта
N_FO - Сигнал разрешения вывода графики фона
F_AT - Чтение атрибутов из Name Table
SC_CNT - Запуск счетчика адресов при включении растра и/или фона
BURST - Маска вывода вспышки синхронизации поднесущей цвета
SYNC - Синхросмесь видеосигнала
PICTURE - Маска выводимого изображения
N_INT - NMI прерывание по VBLANK
R2B7 - Чтение флага NMI
BLNK - Гашение
RESCL - Строка пререндера (сброс всех схем выборки)
[7:0]V - Выход вертикального счетчика (для спрайтовой машины)
HSYNC - Выход строчной синхронизации
VSYNC - Выход кадровой синхронизации

Синхрогенератор содержит 2 счетчика: горизонтальный и вертикальный. Горизонтальный считает пиксели (по пиксельклоку) а вертикальный - строки растра. Каждый сигнал имеет четкую координату Пиксель:Строка, которая в оригинальной схеме задана обычной матрицей:
http://savepic.net/10175377.png
http://savepic.net/10179473.png
Я не буду более детально расписывать каждый вырабатываемый сигнал. Это лучше сделать при описании модулей, где конкретный сигнал используется.

По традиции, схема "влоб":
http://savepic.net/10188703m.jpg (http://savepic.net/10188703.jpg)

Оптимизированная схема:
http://savepic.net/10178463m.jpg (http://savepic.net/10178463.jpg)

Verilog код:

// Главный счетчик таймингов PPU
module PPU_HV_COUNTER(
// Системные входы
input Clk, // Главные такты
// Входные цепи
input OBCLIP, // Обрезание левой части экрана спрайтов
input BGCLIP, // Обрезание левой части экрана фона
input BGE, // Активация фона
input OBE, // Активация спрайтов
input VBL, // Разрешение запроса прерывания VBlank
input R2, // Чтение регистра 2
input nRES, // Общий сброс PPU
// Выходные цепи
output reg PClk, // Пиксельклок
output reg ALEGate, // Гейт ALE
output reg [5:0]HNN, // Синхронизированное атомарное состояние PPU
output reg S_EV, // Запуск процесса просмотра списка спрайтов
output reg CLIP_O, // Гашение левого столбца из 8ми точек экрана для спрайтов
output reg CLIP_B, // Гашение левого столбца из 8ми точек экрана для фона
output reg O_HPOS, // Запуск счетчиков координаты X спрайтов (позиция 0 спрайтов)
output reg EVAL, // Сброс счетчика OAMT и начало процесса обработки OAMT
output reg E_EV, // Инициализация схемы адреса для вычитания графики спрайтов
output reg I_OAM2, // Сигнал очистки OAMT
output reg PAR_O, // Вычитывание графики спрайтов
output reg VIS, // Маска активного растра (графика выводится на экран)
output reg F_NT, // Чтение Name Table
output reg F_TB, // Чтение второго байта
output reg F_TA, // Чтение первого байта
output reg N_FO, // Сигнал разрешения вывода графики фона
output reg F_AT, // Чтение атрибутов из Name Table
output SC_CNT, // Запуск счетчика адресов при включении растра и/или фона
output reg BURST, // Маска вывода вспышки синхронизации поднесущей цвета
output reg SYNC, // Синхросмесь видеосигнала
output PICTURE, // Маска выводимого изображения
output N_INT, // NMI прерывание по VBLANK
output reg R2B7, // Чтение флага NMI
output BLNK, // Гашение
output reg RESCL, // Строка пререндера (сброс всех схем выборки)
output [7:0]V, // Выход вертикального счетчика (для спрайтовой машины)
output reg HSYNC, // Выход строчной синхронизации
output reg VSYNC // Выход кадровой синхронизации
);
// Переменные
reg [1:0]ClkDiv; // Предделитель тактов
reg [8:0]HCnt; // Строчный счетчик
reg [8:0]VCnt; // Кадровый счетчик
reg V8R; //
reg Odd; // Чет/нечет
reg VB; // Вертикальное
reg FPORCH;
reg BPORCH;
reg N_HB;
reg BREN;
reg VSNC;
reg PEN;
reg [2:0]IFIFO;
reg IREQ;
reg R2R;
reg BLNKR;
// Комбинаторика
assign SC_CNT = ~N_HB & (BGE | OBE);
assign PICTURE = ~PEN & ~BPORCH;
assign N_INT = ~(IREQ & VBL);
assign BLNK = BLNKR | ~(BGE | OBE);
assign V[7:0] = VCnt[7:0];
// Логика
always @(posedge Clk) begin
// Синхронизация
R2R <= R2; V8R <= VCnt[8];
// Запрос прерывания
if (~IFIFO[0] & ~IFIFO[2]) IREQ <= 1'b1;
else if (R2R | RESCL) IREQ <= 1'b0;
// Флаг прерывания
if (~R2R & ~R2) R2B7 <= IREQ;
// Флаг Odd
if (V8R & ~VCnt[8]) Odd <= ~Odd;
// Делитель частоты
ClkDiv[1:0] <= ClkDiv[1:0] + 2'h1;
// Активация пиксельклока строго на 1 такт
PClk <= ClkDiv[1] & ClkDiv[0];
// Маска сигнала ALE
ALEGate <= ~ClkDiv[1];
// Пиксельклок
if (PClk) begin
// Синхронизация
HNN[5:0] <= HCnt[5:0];
// Счетчик строк
if (~nRES | (HCnt[8:0] == 9'd340) | (Odd & (HCnt[8:0] == 9'd339) & RESCL)) begin
// Строка досчитала, обрабатываем
HCnt[8:0] <= 9'd000;
// Счетчик кадров
if (~nRES | (VCnt[8:0] == 9'd261)) VCnt[8:0] <= 9'd000; else VCnt[8:0] <= VCnt[8:0] + 9'd001;
end else HCnt[8:0] <= HCnt[8:0] + 9'd001;
// Сигнал N_FO - Переключение между графикой и служебной информацией
N_FO <= ~(BLNK | (HCnt[8] & (~HCnt[6] | HCnt[5] | HCnt[4])));
// Сигнал S_EV
S_EV <= ~BLNK & (HCnt[8:0] == 9'd065);
// Сигналы отсечения
CLIP_O <= ~OBCLIP & (~(HCnt[8] | VB) & ~HCnt[7] & ~HCnt[6] & ~HCnt[5] & ~HCnt[4] & ~HCnt[3]);
CLIP_B <= ~BGCLIP & (~(HCnt[8] | VB) & ~HCnt[7] & ~HCnt[6] & ~HCnt[5] & ~HCnt[4] & ~HCnt[3]);
// Сигнал позиции
O_HPOS <= ~BLNK & (HCnt[8:0] == 9'd339);
// Сигнал EVAL
EVAL <= ~BLNK & ((HCnt[8:0] == 9'd339) | (HCnt[8:0] == 9'd063) | (HCnt[7:0] == 8'd255));
// Сигнал E_EV
E_EV <= ~BLNK & (HCnt[7:0] == 8'd255);
// Сигнал I_OAM2
I_OAM2 <= ~BLNK & ~HCnt[8] & ~HCnt[7] & ~HCnt[6];
// Сигнал PAR_O
PAR_O <= ~BLNK & HCnt[8] & ~HCnt[7] & ~HCnt[6];
// Сигнал VIS
VIS <= ~VB & ~HCnt[8] & ~BLNK;
// Сигнал F_NT - Чтение таблицы символов
F_NT <= ~BLNK & ~HCnt[2] & ~HCnt[1];
// Сигнал F_TB - Чтение второго байта графики
F_TB <= ~(BLNK | (HCnt[8] & (~HCnt[6] | HCnt[5] | HCnt[4]))) & HCnt[2] & HCnt[1];
// Сигнал F_TA - Чтение первого байта графики
F_TA <= ~(BLNK | (HCnt[8] & (~HCnt[6] | HCnt[5] | HCnt[4]))) & HCnt[2] & ~HCnt[1];
// Сигнал F_AT - Чтение атрибутов
F_AT <= ~(BLNK | (HCnt[8] & (~HCnt[6] | HCnt[5] | HCnt[4]))) & ~HCnt[2] & HCnt[1];
// Сигнал HSYNC
HSYNC <= FPORCH;
// Сигнал VSYNC
VSYNC <= ~VSNC & ~N_HB;
// Сигнал SYNC
SYNC <= FPORCH | (~VSNC & ~N_HB);
// Сигнал BURST
BURST <= BREN & (FPORCH | (~VSNC & ~N_HB));
// Сигнал PEN
if (VCnt[7:0] == 8'd241) PEN <= 1'b1;
else if (VCnt[8:0] == 9'd261) PEN <= 1'b0;
// Сигнал BPORCH
if (HCnt[8:0] == 9'd270) BPORCH <= 1'b1;
else if (HCnt[8:0] == 9'd328) BPORCH <= 1'b0;
// Сигнал VB
if (VCnt[8:0] == 9'd261) VB <= 1'b0;
else if (VCnt[7:0] == 8'd239) VB <= 1'b1;
// Сигнал BLNKR
if (VCnt[8:0] == 9'd261) BLNKR <= 1'b0;
else if (VCnt[7:0] == 8'd240) BLNKR <= 1'b1;
// Сигнал FPORCH
if (HCnt[8:0] == 9'd256) FPORCH <= 1'b1;
else if (HCnt[8:0] == 9'd279) FPORCH <= 1'b0;
// Сигнал N_HB
if (HCnt[8:0] == 9'd279) N_HB <= 1'b1;
else if (HCnt[8:0] == 9'd304) N_HB <= 1'b0;
// Сигнал BREN
if (HCnt[8:0] == 9'd308) BREN <= 1'b1;
else if (HCnt[8:0] == 9'd323) BREN <= 1'b0;
// Сигнал VSNC
if (N_HB) begin
if (VCnt[8:0] == 9'd244) VSNC <= 1'b1;
else if (VCnt[8:0] == 9'd247) VSNC <= 1'b0; // FIFO запроса прерывания
end
IFIFO[2:0] <= {~IFIFO[1],IFIFO[0],~(VCnt[7:0] == 8'd241)};
// Сигнал RESCL
RESCL <= (VCnt[8:0] == 9'd261);
end
end

// Конец
endmodule

HardWareMan
22.10.2017, 10:16
Блок формирования управляющих сигналов локальной шины PPU.

Локальная шина PPU это отдельное адресное пространство для памяти, которая хранит текущее состояние картинки. Она состоит из младшего байта адреса и данных, мультиплексированных между собой в сигналы PPU_AD[7..0], старших 6ти бит адреса PPU_A[13..8] и сигналов управления: PPU_ALE для защелкивания адреса на шине PPU_AD[7..0], ~PPU_RD для строба чтения данных и ~PPU_WR для строба записи данных. Направление указано со стороны PPU. Для упрощения, я их буду называть так: PAD[7..0], PA[13..8], ALE, PRD и PWR (на схемах RD и WR соответственно).
- 2 знакогенератора, младшие 8 КБайт: 0000-0FFF и 1000-1FFF.
- 4 т.н. "таблицы имён" (Name Tables, это название появилось из-за тайлового метода формирования изображения PPU: в "таблице имен" заносится код символа из знакогенератора, который потом и отображается на текущем месте тайла, совсем как текст у ВГ75), по 1 КБайту на страницу: 2000-23FF, 2400-27FF, 2800-2BFF и 2C00-2FFF. В каждой странице есть сама страница тайлов x000-x3BF и таблица атрибутов 0x3C0-x3FF.
- 4 палитры фона: 3F00-3F0F
- 4 палитры спрайтов: 3F10-3F1F
Остальные неуказанные области просто не используются. Причем, так как ОЗУ палитры находится внутри PPU то генерация внешних сигналов PRD и PWR не производится, при обращении к области 3F00-3FFF, но область 3000-3EFF программно доступна через регистр #7. Вот схема "влоб":
http://savepic.net/10200834m.jpg (http://savepic.net/10200834.jpg)
Сигналы обращения к регистру #7 проходят через синхронизатор и формирователь нужного тайминга для локальной шины PPU. Каждое обращение к регистру #7 формирует строб увеличения счетчика адреса TSTEP, который может влиять на счетчики даже если происходит вывод растра (тот самый конфликт при обращении к VRAM за пределами кадрового гашения). Сигнал DB_PAR сопровождает сигнал записи PWR и сигнализирует о том, что необходим проброс данных с шины CPU D[7..0] на локальную шину PAD[7..0]. Сигнал PD_RB указывает на чтение с шины PAD[7..0] внутрь PPU, и, в зависимости от источника запроса (R7 или синхрогенератор) перенаправляет данные на шину CPU D[7..0] (на это указывает сигнал XRB) или в рабочие регистры или счетчики растра PPU. Сигнал THX_MUX вырабатывается если текущий адрес PA[13..8] равен 3F (обращение к внутреннему ОЗУ палитры) и блокирует внешний сигнал записи PWR а так же сигнал XRB.
Оптимизированная схема:
http://savepic.net/10205954m.jpg (http://savepic.net/10205954.jpg)
Здесь появился новый входной сигнал ALEGate, который был введен в рамках организации синхронного дизайна проекта, так как в оригинальной схеме сигнал ALE для режима синхрогенератора (чтение данных растра) организовано как OR сигнала атомарного состояния PPU H0n и инвертированного тактового сигнала PCLK. В синхронной схеме сигнал ALEGate заменяет инвертированный тактовый сигнал PCLK, делая схему строго синхронной. Verilog код модуля:

// Управление модулями по адресу
module PPU_ADR_CONTROL(
// Системные входы
input Clk, // Системные такты
input PClk, // Такты пикселей
input ALEGate, // Формирователь сигнала ALE
// Управляющие входы
input W7, // Запись в регистр 7
input R7, // Чтение из регистра 7
input H0n, // Слот обращения
input BLNK, // Картинка погашена
input PA8, // Адрес PA8
input PA9, // Адрес PA9
input PA10, // Адрес PA10
input PA11, // Адрес PA11
input PA12, // Адрес PA12
input PA13, // Адрес PA13
// Выходы
output PWR, // Активация записи
output TSTEP, // Счет развертки
output DB_PAR, // Данные на шину PPU
output PD_RB, // Данные в защелку
output ALE, // Сигнал ALE
output PRD, // Активация чтения
output XRB, // Данные на шину CPU
output TH_MUX // Обращение в палитру
);
// Переменные
assign TH_MUX = BLNKR & PA8 & PA9 & PA10 & PA11 & PA12 & PA13;
reg [1:0]W7Req; // Очередь запроса записи
reg [1:0]W7Queue; // Очередь сигнала записи
reg [1:0]R7Req; // Очередь запроса чтения
reg [1:0]R7Queue; // Очередь сигнала чтения
reg BLNKR; // Регистр гашения
// Выход записи
assign DB_PAR = W7Queue[1] & ~W7Queue[0];
assign PWR = TH_MUX | ~DB_PAR;
// Выход чтения
assign PD_RB = R7Queue[1] & ~R7Queue[0];
assign PRD = ~(PD_RB | (H0n & ~BLNKR));
// Выход шага счетчика растра
assign TSTEP = DB_PAR | PD_RB;
// Выход ALE
assign ALE = (~W7Queue[1] & W7Queue[0]) | (~R7Queue[1] & R7Queue[0]) | (ALEGate & ~H0n & ~BLNK);
// Данные на шину CPU
assign XRB = R7 & ~TH_MUX;
// Логика
always @(posedge Clk) begin
// Синхронизация
W7Req[0] <= W7; R7Req[0] <= R7;
// Запросы
if (W7Req[0] & ~W7) W7Req[1] <= 1'b1;
else if (W7Queue[1]) W7Req[1] <= 1'b0;
if (R7Req[0] & ~R7) R7Req[1] <= 1'b1;
else if (R7Queue[1]) R7Req[1] <= 1'b0;
// Пиксельклок
if (PClk) begin
// Ротация очереди
W7Queue[1:0] <= {W7Queue[0],W7Req[1]};
R7Queue[1:0] <= {R7Queue[0],R7Req[1]};
// Синхронизация
BLNKR <= BLNK;
end
end
// конец модуля
endmodule


- - - Добавлено - - -

Блок мультиплексирования шины данных PPU.

Это маленький блок, который работает при чтении внешним CPU внутреннего состояния PPU или его локальной шины. Схемы не было, он был сразу реализован в виде комбинаторного мультиплексора.
http://savepic.net/10210073.png
Я же его просто синхронизировал. Объяснять его работу, думаю, не требуется.

// Мультиплексор шины при чтении
module PPU_BUS_MUX(
// Секция входов
input Clk, // Такты
input PClk, // Пиксельклок
input PD_RB, // Строб моста шины VRAM
input XRB, // Выбор чтения VRAM
input [7:0]PAD, // Данные VRAM
input R2, // Выбор чтения R2
input [7:0]R2DB, // Данные R2
input R4, // Выбор R4
input [7:0]OB, // Данные R4
input RPIX, // Выбор пиксельного вывода
input [7:0]PIX, // Данные пиксельного вывода
input RnW, // Выбор направления данных
input nDBE, // Строб данных
// Секция выходов
output [7:0]Q // Выход
);
// Комбинаторика
assign Q[7:0] = (RnW & ~nDBE) ? D[7:0] : 8'hZZ;
// Внутренние переменные
reg [7:0]ADR;
reg [7:0]OBR;
reg [7:0]D;
// Логика работы мультиплексора
always @(posedge Clk) begin
// Синхронизация регистра данных обьектов (спрайтов)
if (PClk) OBR[7:0] <= OB[7:0];
// Синхронизация данных чтения VRAM
if (PD_RB) ADR[7:0] <= PAD[7:0];
// Мультиплексор
if (XRB) D[7:0] <= ADR[7:0];
else if (R2) D[7:0] <= R2DB[7:0];
else if (R4) D[7:0] <= OBR[7:0];
else if (RPIX) D[7:0] <= PIX[7:0];
else D[7:0] <= 8'h00;
end
// Конец модуля
endmodule

Titus
25.12.2019, 14:43
Несколько вопросов к HardWareMan:

1. Можно восстановить картинки? Все протухли.
2. Еще не сфоткан PAL-овский чип от Dendy 6538 (2C07)?
3. Что изменилось за 2 года?

HardWareMan
26.12.2019, 11:21
1. Нельзя, да и желания нет.
2. Нет, и скорее всего не будет.
3. Ничего, со всех сторон прокинули, так что проект закрыт.

evgs
26.12.2019, 11:28
Денди-чип отфоткан (http://hwm.us.to/emustuff/Decap/UMC_UA6538/) со всех слоев:
https://zeptobars.com/en/read/UMC-UA6538-Dendy-NES-Nintendo-PPU

C остальными чипами (NES PAL PPU, 6527P Dendy CPU) нас декаперы (Zeptobars и VSLAV) опрокинули.
И с сегой тоже.
Обещали-обещали, много лет завтраками кормили, а воз и ныне там.

Titus
26.12.2019, 11:30
Денди-чип отфоткан со всех слоев:
https://zeptobars.com/en/read/UMC-UA...S-Nintendo-PPU

C остальными чипами нас декаперы (Zeptobars и VSLAV) опрокинули.
Вот это хорошая новость)

Про опрокинули поподробнее можно?

- - - Добавлено - - -


1. Нельзя, да и желания нет.
2. Нет, и скорее всего не будет.
3. Ничего, со всех сторон прокинули, так что проект закрыт.
Чего же так пессимистично?
Может кто-то подхватит эстафету.
Нельзя хоронить готовые наработки.

evgs
26.12.2019, 11:38
Про опрокинули поподробнее можно?
В прямом смысле. В 2015 я собрал все нужные чипы. Комплект Dendy, PAL NES, Sega MD1.
Собрали с ХВМом донат.
Сначала я отдал проект Зептобарсу из Москвы. Он сказал что проблемы: нужен автоматизированный столик на сервоприводах,
чтобы точно позиционировать чип перед головкой микроскопа. А без этого оборудования фотки кривые и бракованные выходят.
Обещал и клялся что вот-вот сделает. К концу 2017 это все надоело, и мы передали проект Вячеславу (VSLAV) с этого форума.
Vslav говорил что уж теперь 1000% сделает, и столик соберет. Корпуса даже растворил в кислоте. Но история повторилась 1:1.
Он просто забил и на связь толком не выходит.

Итог: с 2015 года Михаилом сделан только Dendy PPU 6538.
На дворе почти 2020.
С Новым Годом, лол.

Titus
26.12.2019, 11:43
Обещал и клялся что вот-вот сделает. К концу 2017 это все надоело, и мы передали проект Вячеславу (VSLAV) с этого форума.
На этот раз говорил что 1000% сделает, и столик соберет. Но история повторилась 1:1.

Итог с 2015 года Михаилом сделан только Dendy PPU 6538.

Vslav, надеюсь, все же сфоткает. В другой ветке он писал, что в декабре к нему пришел микроскоп и он займется тем, что накопилось. У нас там тоже в очереди ХМ1515 от УКНЦ стоят.

Самое главное, что 6538 есть.
Может я немного выпал из темы, но ведь 6527P - это и есть 2A03, который ковырял товарищ ORG на эмураше?
Только там фотки тоже протухли.

evgs
26.12.2019, 11:46
По сути чип 6527P - это тот же 2А03, но с другим делителем входной частоты (/15 вместо /12)
и рассчитанный под другой кварц (26.60 вместо 21.47 МГц).
И некоторые модели 6527/6527P еще и скважность попутанную имели.

Можете в моей подписи тему глянуть, там подробно расписано.
Только про сами модели чипов информация пока разбросана по форумам:

https://forums.nesdev.com/viewtopic.php?f=3&t=17213#p216082

https://wiki.nesdev.com/w/index.php/User:Lidnariq/Known_CPU_revisions
https://wiki.nesdev.com/w/index.php/User:Lidnariq/Known_PPU_revisions

Titus
26.12.2019, 11:57
Только про сами модели чипов информация пока разбросана по форумам.
Где есть информация еще по декапу чипов от NES и фотки?

- - - Добавлено - - -


По сути это 2А03 с другим делителем входной частоты (/15 вместо /12).
Значит для точной эмуляции Денди этого уже достаточно, только делитель поменять и все.

- - - Добавлено - - -

Хм... про 2A03 написаны какие-то неприятные вещи. Правда, непонятно, что они значат:

M2 duty cycle is 3/4 instead of 5/8. Lacks tonal noise mode. Has broken and disabled programmable interval timer on-die. Other differences?

evgs
26.12.2019, 12:00
https://www.qmtpro.com/~nes/chipimages/#rp2a03
https://www.qmtpro.com/~nes/chipimages/#rp2c02

https://www.qmtpro.com/~nes/chipimages/visual2a03/
https://www.qmtpro.com/~nes/chipimages/visual2c02/

2C02 (NES NTSC PPU) и 2С07 (NES PAL PPU) не равны 6538 (Dendy/Hybrid PPU)
В нем понамешаны тайминги от NTSC и PAL и PAL'овская палитра соответственно.
В CYCLE REFERENCE CHART (https://wiki.nesdev.com/w/index.php/Cycle_reference_chart), это дело расписано.
Только не написано какие параметры относятся к CPU, а какие к PPU, но это и так совершенно понятно ящитаю.

Эмуляция денди щас хорошая. Тайминги правильные. И эмуляторы отличные.
Но на более низкий уровень мы не смогли спуститься из-за отсутствия декапа.

Titus
26.12.2019, 12:06
Эмуляция денди щас хорошая. Тайминги правильные. И эмуляторы отличные.
Но на более низкий уровень мы не смогли спуститься из-за отсутствия декапа.
Ну так вот же фотка 6538 есть.
А 2A03 практически идентичен 6527P. Что останавливает?

evgs
26.12.2019, 12:15
Что останавливает?
ХВМ впал в депрессию потому что СЕГУ хотели очень. Даже в приоритет ее первой поставили на декап.
А она накрылась медным тазом. Без декапа там - полный кирдык.
А раз нету сеги, значит и нету у ХВМа мотивации к денди.

А я "томат" - сисадмин-эникейщик и в этих дебрях нифига не шарю.

Titus
26.12.2019, 12:17
ХВМ впал в депрессию потому что СЕГУ хотели очень.
А она накрылась медным тазом. Без декапа там - полный кирдык.
А раз нету сеги, значит и нету у ХВМа мотивации и к денди.

А я "томат" - сисадмин-эникейщик и в этих слоях нифига не шарю.

Нельзя. Рано или поздно получится сфоткать. А если сложить ручки, твою мечту реализует кто-то другой. И это будет его мечта, а не твоя)

Еще пара вопросов:
1) Есть инструкция по реверсу n-моп'овских чипов? (я реверсил только кмоповские).
2) Есть ли потранзисторная или поэлеметная схема других чипов от NES?

evgs
26.12.2019, 12:24
Вот тут не знаю.

Titus
26.12.2019, 12:48
Вот тут не знаю.
Жалко, когда люди делают что-то, потом забрасывают проект, ссылки протухают, а многое приходится начинать заново, если вообще приходится начинать. Это я не только про эту ветку, а так же про тему на эмураше.

- - - Добавлено - - -

Кстати говоря, чем тогда хардвареман лучше опрокинувших декаперов, которые обещали и не сделали?
Он тоже обещал в этой теме восстановить фотки) А теперь не буду, не хочу)

- - - Добавлено - - -


Денди-чип отфоткан со всех слоев:
Самая лучшая фотка металла в папке metal_photo1, отсутствует в максимальном разрешении.

evgs
26.12.2019, 12:53
Самая лучшая фотка металла в папке metal_photo1, отсутствует в максимальном разрешении.
Говорим спасибо Zeptobars/Михаилу. В тех папках лежит всё, что было доступно. Ничего другого - нет.
И я подозреваю, что эти фотки кривоваты. Без столика делались. Руками клеились.
Поэтому и три подхода было.

Вот ветка, я топикстартер:
https://forums.nesdev.com/viewtopic.php?f=3&t=13185

Titus
26.12.2019, 13:03
Говорим спасибо Zeptobars/Михаилу. В тех папках лежит всё, что было доступно. Ничего другого - нет.
И я подозреваю, что эти фотки кривоваты. Без столика делались. Руками клеились.
Поэтому и три подхода было.

Во всяком случае слой кремния выглядит идеально)
А вот металл значительно хуже) Может лучше и не бывает, я же не настоящий н-моп'овец, я просто каску нашел)

evgs
26.12.2019, 13:19
В сухом остатке мы имеем:
- 5 лет коту под хвост.
- Полностью подорванное доверие к обоим декаперам.
- Распотрошенный комплект чипов, которые осели где-то в/на Украине. Теперь уж на глазок не опознать, кто из них кто.

Выводы:
- Начинать всё по новой, собирать чипы, убить очередные оригинальные PAL NES и SEGA MD1 на потроха.
- Искать кого-то на Западе вслепую, без связей без знакомств, за конские деньги. Иными словами - играть в очередную лотерею.
- Мы лохи, просравшие и чипы, и килобакс доната (по старым ценам).

Так-то.
ХЗ короче.
А у вас на нашем месте была бы мотивация после такого (не побрезгую этим жаргонным словом) "кидалова"?

Titus
26.12.2019, 13:34
А у вас бы на нашем месте была мотивация после такого (не побрезгую этим жаргонным словом) "кидалова"?
Я смотрю на это гораздо оптимистичнее:

1. Vslav отфоткал множество чипов, и некоторые отреверсил, что здорово продвинуло науку в области PDP.
2. Все чипы для Денди отфотканы. 6538 есть. 2A03 (почти 6527P) тоже есть. Чего еще надо для реверса?
3. Остальное дофоткается в будущем, я думаю. И ваша Сега тоже.

evgs
26.12.2019, 13:43
Наверное вам повезло. Нам Vslav не отфоткал ни одного чипа с 2017.
При этом не посылал в сад, а говорил, что вот уж сейчас (весной/летом/осенью) УЖ ТОЧНО БУДЕТ.
Прошло 2 года. Иногда он вылезал с очередной порцией завтраков, сделал сам декап (снятие корпусов).
А потом он просто изчез из конференции скайпа в июне. Попытки достучаться через ЛС были:


- Здравствуйте. А вы в скайп-беседу вообще больше не заходите?
- Здравствуйте, да - нечасто, когда только домашний компьютер включаю и не каждый раз.
Иными словами: с Новым Годом - пшёл нафиг.
Сорян конечно за вынесение сора из избы. Это некрасиво и все дела.
Но какие мне прикажете делать выводы?

Бугурт ХВМа мне весьма понятен.
Он перестал ХОТЕТЬ что-то делать после такого.

Titus
26.12.2019, 13:49
Иными словами: с Новым Годом - пшёл нафиг.
Сорян конечно за вынесение сора из избы. Это некрасиво и все дела.
Но какие мне прикажете делать выводы?
Тут остается только подождать, или найти другого декапера.
У человека могут быть свои обстоятельства тоже.

Vslav
26.12.2019, 13:51
Но какие мне прикажете делать выводы?
Вы прислали сразу 16 чипов. Я должен их все вручную фотать?
На маленький чип уходит половина рабочего дня. На большой и целый день может уйти.
А времени нет совсем, работа сложная, вечером и в выходные я никакой, на свои-то проекты сил нет.
Естественно, я захотел это дело автоматизировать, вот занимаюсь.

evgs
26.12.2019, 13:59
Можно было бы хоть ради приличия сюда (http://hwm.us.to/emustuff/Upload/vslav.png ) написать.
Но вы просто исчезли, а нам ничего не оставалось, кроме как сделать соответствующие выводы.
Логично? Логично. Без обид, ничего личного.

Vslav
26.12.2019, 14:05
Можно было бы хоть ради приличия сюда (http://hwm.us.to/emustuff/Upload/vslav.png ) написать.
Но вы просто исчезли, а нам ничего не оставалось, кроме как сделать соответствующие выводы.
Логично? Логично. Без обид, ничего личного.
Прошу прощения, конечно. Я домашний комп (где у меня скайп) раз в месяц включаю, а тот скайп на нем еще реже запускаю.

HardWareMan
26.12.2019, 15:26
Ну так можно было предложить другой вид связи, хоть РМ на форуме. Хотя, Женя через него и выходил на связь.

Короче, это тема декапа и она оффтопиком тут. Пусть админы её отрежут куда-нибудь. Что касается картинок, то я их восстановлю, когда форум обзаведётся своим хостингом картинок, если найду их у себя на компе. А пока тему кроем.

CodeMaster
26.12.2019, 22:40
когда форум обзаведётся своим хостингом картинок
Эээ, так сейчас сайт хостится у SuperMax'а, а у него есть хостинг файлов (правда там макс. 100 МБ на файл, но вроде должно хватить для обработанного декапа). Типа, бинго, выпал приз! ;-)

HardWareMan
29.12.2019, 12:25
Эээ, так сейчас сайт хостится у SuperMax'а, а у него есть хостинг файлов (правда там макс. 100 МБ на файл, но вроде должно хватить для обработанного декапа). Типа, бинго, выпал приз! ;-)
Ну и как это отразиться на евреях?

SoftWareGuy
29.12.2019, 13:08
А чем google диск не вариант - 15 гигабайт бесплатно, доступ есть отовсюду.

evgs
01.07.2021, 10:14
Официальное обращение:

Здравствуйте Вячеслав.
Так как с проектом не вышло, не могли бы вы выслать чипы HWM'у пожалуйста?
Мне nesdev подсказал контакты на зарубежного декаппера.
Очередной год прошел, результатов нет - я думаю, что нет больше смысла мучать Вас этим проектом.

https://imgur.com/QiSLGke

Vslav
01.07.2021, 12:49
Официальное обращение:
М-м-м-м? Мы же все распилили и открыли. С Игорем посмотрели в микроскоп вместе, открытые кристаллы уже 2-3-го
поколений - нормы очень мелкие, много слоев металла. Самый простой чип с самыми крупными нормами отсняли,
сырые снимки выложены, а влазить в реверс я изначально не брался. Что еще мы можем сделать?

Пытаться шлифовать и снимать на крупном разрешении считаю бесполезным, прямой реверс маловероятным,
достаточно посмотреть как оно идет, например, с чипами PS1. Там шлифовка и снимки на х40 от "зарубежного декапера",
красивые, но оно несильно помогает. Но попробовать, конечно, можно. Я вышлю открытые кристаллы, куда скажете.

evgs
01.07.2021, 13:29
М-м-м-м? Мы же все распилили и открыли. С Игорем посмотрели в микроскоп вместе, открытые кристаллы уже 2-3-го
поколений - нормы очень мелкие, много слоев металла. Самый простой чип с самыми крупными нормами отсняли,
сырые снимки выложены, а влазить в реверс я изначально не брался. Что еще мы можем сделать?

Пытаться шлифовать и снимать на крупном разрешении считаю бесполезным, прямой реверс маловероятным,
достаточно посмотреть как оно идет, например, с чипами PS1. Там шлифовка и снимки на х40 от "зарубежного декапера",
красивые, но оно несильно помогает. Но попробовать, конечно, можно. Я вышлю открытые кристаллы, куда скажете.

Я может что-то пропустил, тогда прошу извинить.
Но вроде как были проблемы со склейкой фрагментов фотографий в единый файл, в итоге дело ничем не закончилось.
Я точно не видел целой фотографии, как например тут: https://zeptobars.com/en/read/UMC-UA6538-Dendy-NES-Nintendo-PPU


С Игорем посмотрели в микроскоп вместе
Наверное это было в приватной беседе, я это пропустил.

Возможно ли вашими силами сделать 6527Р (CPU Dendy) или RP2C07-0 (PAL NES PPU)?
Они по идее, самые "простые" и имеют самые крупные нормы, из всего того, что у нас было.

RP2C07-0 пытался вскрывать Зептобарс примерно в то же время, когда делал фотки 6538.
Но возникли какие-то проблемы непонятного характера, тоже с автоматикой склейки

Vslav
01.07.2021, 13:53
Наверное это было в приватной беседе, я это пропустил.

Да, по Скайпу общались. Я отснял ~400 снимков на x20 и выложил, договорились что панораму вы сами собирать будете.
https://www.1801bm1.com/files/retro/SEGA/sega_nums.jpg
Снимали чип 05 - SEGA 315-5309 6046 9048 AEAD, как имеющий хоть какие-то перспективы для анализа.

- - - Добавлено - - -



Возможно ли вашими силами сделать 6527Р (CPU Dendy) или RP2C07-0 (PAL NES PPU)?

Список чего открыто и идентифицировано:

1. SEGA 315-5313 7101 9036 LAGD 208
2. RP2C02H-0
3. UMC UA6527P
4. SEGA 315-5476A 1LD41
5. SEGA 315-5309 6046 9048 AEAD
6. SEGA 315-5364 6045C 9049 ABAD
7. TA-05 9604 1548124064
8. SEGA 315-5477 9202 Q63
9. TA-06W 9606 1549458051
10. RP2A03H/TA-03NP1
11. TA-04 6604 1547596063
12. YAMAHA JAPAN YM2612 9037 IAGB
13. Fujitsu 2C31??

Видно что UA6527P имеет уже масштабированный кристалл. То есть, написано-то 6527, а внутри уже переразведенка по новому тех-процессу.
RP2C07-0 - есть отдельный кристалл, его Михаил открывал, вроде же он фото и делал?
Могу посмотреть и переснять, насчет склейки подумаю, если и там 400 кадров - то пока нет, мне надо multiblend переписать, а то Hugin неделю собирать будет.

evgs
01.07.2021, 13:53
Очередной год прошел, результатов нет
Тогда извиняюсь.

RP2C07-0 - (PAL NES PPU) крайне важный кристалл, его Зептобарс точно открывал, но ничего не сделал из-за возникших проблем.
Для международного сообщества это важный чип, который пока никто не декапил. Разобрали по косточкам только его NTSC-предшественника
на совершенно иных таймингах: https://www.qmtpro.com/~nes/chipimages/visual2c02/
Но и помимо таймингов, там есть изменения, о чем писал Fiskbit (см.скрин в первом сообщении)

Из сферы NES он самый приоритетный, так как (по неофициальным данным) именно на его основе UMC делала UA6538, где также меняла тайминги.

Titus
02.07.2021, 02:13
Из сферы NES он самый приоритетный, так как (по неофициальным данным) именно на его основе UMC делала UA6538, где также меняла тайминги.

А с чего тогда я начинал делать реверс (https://zx-pk.ru/threads/31200-revers-inzhiniring-chipov-ot-dendy-(nes).html)?

evgs
02.07.2021, 14:36
И прежде всего мне интересен видео-чип UA6538 отфотканный zeptobars'ом.
Слой кремния выглядит качественным. Фотографий слоя металла целых три, но у первой фотки нет высокого разрешения, а третья совсем мутная. Остается вторая, которая тоже не подарок, но вполне понятная, во всяком случае в части тех фрагментов схемы, которые я смотрел.
Тут (https://hwm.us.to/emustuff/Decap/UMC_UA6538/) тоже мутное? Здесь в принципе все дубли, что были, я сюда собрал.


А с чего тогда я начинал делать
Это UA6538, PPU денди. Его вскрыл Зептобарс.
RP2A03, RP2C02 - CPU и PPU NTSC NES/Famicom - вскрыты давно зарубежными товарищами, на его основе написан visual simulator

RP2C07-0 это PPU официального PAL NES. Там тайминги другие, отличные и от денди, и от NTSC.
Судя по документам суда между UMC и Nintendo, умца делала 6538 именно на основе RP2C07-0
(Косвенно это подтверждается фактом, что у палнес и денди перепутаны красный и зеленый emphasis bits, чего не наблюдается у NTSC-чипов)
PAL NES PPU никто никогда не вскрывал. Миша пытался, но не вышло.

ЦПУшку (RP2A07) тоже еще не вскрывали, но у меня нет мёртвого донора.
Единственный PAL NES, что я имею, нельзя пускать на потроха. Он для тестов нужен.

Стоит отметить, что сами тайминги всех трех регионов сняты осциллом. И всё довольно точно эмулируется везде.
Но есть некоторые белые пятна, помимо таймингов, именно у PAL NES и Dendy чипов. И без этого - хрен сделаешь FPGA-версию, чтобы поддерживала NTSC/PAL/Dendy полностью.
NTSC-чипы буржуи изучили уже вдоль и поперек.

Titus
02.07.2021, 14:42
RP2A07 - PPU NTSC NES/Famicom - вскрыт давно зарубежными товарищами, на его основе написан visual simulator
Вскрыт, но, на сколько я понял, логической схемы или хотя бы повентильной (прям в виде схемы) скачать нигде нельзя?

evgs
02.07.2021, 15:00
В общем, важные невскрытые чипы это:
PAL NES PPU (RP2C07-0) - в очереди.
PAL NES СPU (RP2А07) - нету в наличии. потрошить мою единственную PAL NES очень нежелательно
CPU Dendy (UA6527P) - в очереди.

Интересными бы были клоны других производителей:
TA-03NP1 (CPU Dendy), TA-02NP (PPU Dendy) и финальные ревизии NTSC-чипов, использовавшихся только в последней версии фамикома.
Они есть у Вячеслава, но тут важно не гнать коней. ХВМ хотел сегу, а с ней все еще тяжелее. Надо расставить приоритеты.

Дискуссия в скайпе показала, что клеить фотки крайне желательно только руками. Не автоматически.

evgs
02.07.2021, 20:10
RP2С02 - PPU NTSC NES/Famicom - вскрыт давно зарубежными товарищами, на его основе написан visual simulator
Вскрыт, но, на сколько я понял, логической схемы или хотя бы повентильной (прям в виде схемы) скачать нигде нельзя?

http://breaknes.com/download
https://github.com/ogamespec/breaks/tree/master/Docs/PPU
http://wiki.breaknes.com/ppu

org
02.11.2021, 15:47
Привет, случайно узнал про этот тред в дискорде emu-russia.

RP2A07 (PAL APU):

https://drive.google.com/drive/folders/17tl0-CY6gGMZEBJe4ZxIZ_b5cpO6CX0H?usp=sharing

RP2C07 (PAL PPU):

https://drive.google.com/drive/folders/1nA9thbA0Vy0MzFepm7ZRhWfzq0dq9eZ1?usp=sharing

Проект на нашем гитхабе по сравнению PAL и NTSC версий чипов:

https://github.com/orgs/emu-russia/projects/2

and1981
15.11.2023, 09:10
Продолжаются работы по созданию FPGA модели APU 2а03(2а07). На данный момент уже пытается работать 6502 и спрайтовая ДМА.
Тестовый стенд
https://i.ibb.co/C2gHhWv/rn-image-picker-lib-temp-b65acf7c-219f-4b11-b6af-0b7250b84c4d.jpg (https://ibb.co/C2gHhWv)
Результат
https://i.ibb.co/kHB724X/rn-image-picker-lib-temp-89358f07-62ac-4470-812a-c6f102ff63bc.jpg (https://ibb.co/kHB724X)

and1981
07.07.2024, 00:57
Небольшой видео отчет о проделанной работе над тактово точным аппаратным клоном NES APU 2A03G. За основу принципиальной схемы были взяты материалы из нашей Вики на гитхабе Emu-Russia https://github.com/emu-russia/breaks/tree/master/BreakingNESWiki. На данный момент работы вышли на завершающую стадию, потрачена уйма времени на поиск и устранение ошибок. Данный тестовый стенд проходит большинство тестов как для встроенного ядра 6502, так и для остальной части АПУ (DMA, LFO, DPCM, и т. д.). Звук пока выводится при помощи двух простейших R2R цапов, в дальнейшем возможно будут DSD выходы для каждого из 5-ти каналов звука. Огромное спасибо комрадам из дискорд сервера emu-russia за помощь и поддержку (Org, Evgs, Nukeykt, HardWareMan).

https://www.youtube.com/watch?v=xtj7G8qB2oU
:v2_dizzy_roll:

and1981
20.07.2024, 15:12
Выложил на гитхаб своё вериложное ядро MOS6502 (NMOS), данное ядро было спроектированно на основе реверса оригинального чипа. Более подробно про внутреннее устройство оного можно почитать на нашей вики https://github.com/emu-russia/breaks/tree/master/BreakingNESWiki/6502.
На данный момент работают все официальные опкоды, из недокументированных судя по тестам остался только один опкод AB (ATX), который пока мне не удалось победить. Данное ядро с отключенной десятичной коррекцией (BCD) также было проверено в составе FPGA клона NES APU 2A03G, результаты его работы вы можете посмотреть в предыдущем моем сообщении.
Ссылка на репозиторий: https://github.com/andkorzh/BREAKS6502/

Titus
20.07.2024, 19:19
На данный момент работают все официальные опкоды, из недокументированных судя по тестам остался только один опкод AB (ATX), который пока мне не удалось победить.
Не удается победить в каком смысле? Если все основано на реверсе, то должно работать один к одному?

AlexG
20.07.2024, 21:25
всю тему я вряд ли прочитаю. однако в чём прикол "очердного" варианта ядра 6502 ? Его даже на транзисторах спаяли...

and1981
20.07.2024, 23:01
В данном случае этот опкод работает с учетом физики, нежели электроники и логики, используется электрическая емкость шины и постоянная времени, с которой эта шина разряжается, но это частный случай, есть некоторые опкоды, которые например драйвят на шину несколько источников одновременно и кто победит в этом случае? разумеется земля. :v2_dizzy_biggrin2: Эти нюансы не учитывали разработчики, поэтому эти моменты весьма нестабильны и используются на свой страх и риск, плюс огромная зависимость от температуры кристалла. Об этом в частности можно почитать здесь: https://www.masswerk.at/6502/6502_instruction_set.html
Вот к примеру цитата про "магическую константу"
Highly unstable, do not use. A base value in A is determined based on the contets of A and a constant, which may be typically $00, $ff, $ee, etc. The value of this constant depends on temerature, the chip series, and maybe other factors, as well. In order to eliminate these uncertaincies from the equation, use either 0 as the operand or a value of $FF in the accumulator. В CMOS версии 65С02 этих нестабильных опкодов в принципе нет, потому как там уже эти особенности NMOS не работают.

По поводу 6502 на транзисторах, очень забавная поделка, отличная наглядная модель, однако это больше показометр, нежели процессор, ибо граничная тактовая частота если и будет 100 - 200 килогерц - то это хорошо. Его например в денди не встроишь, иначе устанешь ждать когда он отработает.:v2_dizzy_botan: Да, есть множество других HDL ядер 6502 и на основе нетлиста также, я их много перепробовал разных, но собрать нормально у меня не получилось, ибо оно на Д-латчах и Квартус сыпет стопицот ворнингов. Либо ядро написано тупо по описанию из вики и при попытке собрать занимает в три раза больше ресурсов в сравнении с ядром на основе реверса. Меня данные факты в корне не устраивают, как и парней с emu-russia, поэтому мы и начали проект по реверсу данного чипа, только вот конечные цели у нас немного разные, кто-то хочет создать тактово - точный эмулятор для PC, а мне нужна была точная реализация на FPGA на столько, насколько это позволяет программная среда разработки и аппаратное обеспечение ALTERA Cyclone.

Titus
21.07.2024, 01:40
В данном случае этот опкод работает с учетом физики, нежели электроники и логики, используется электрическая емкость шины и постоянная времени, с которой эта шина разряжается, но это частный случай, есть некоторые опкоды, которые например драйвят на шину несколько источников

Все понятно)
Но тогда на ФПГА никак не сэмулировать плавающую аналоговую систему) Разве что симитировать поведение примерно.

and1981
21.07.2024, 13:18
Так точно, аналогичная ситуация и с ППУ, там используется так называемая открытая внутренняя шина данных, иными словами если CPU в PPU не пишет данные, то некоторое время шина за счет емкости хранит последнее состояние. Можно поставить регистр и хранить это сотояние в нем, однако тесты возражают, мол у вас шина за одну секунду примерно должна гарантированно уже забыть всё, а у вас она помнит, :smile: как так? непорядок. Была мысль поставить счетчик отдельный и если никто в течении секунды не обращается к шине обнулять по переполнению счетчика этот регистр, но это уже костыли и уход от оригинальной схемы. Аналогично можно вспомнить и как корраптится ОАМ, если не рефрешить его. Даже тест был на определение данного факта "OAM Decay".

Titus
21.07.2024, 13:45
Аналогично можно вспомнить и как корраптится ОАМ, если не рефрешить его. Даже тест был на определение данного факта "OAM Decay".

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

А PPU делался на CMOS чипах? Или всегда был NMOS?

and1981
21.07.2024, 14:05
NMOS, как и APU. CMOS уже были клоны всё в одном, типа 1818P или 6561 и т д

Titus
21.07.2024, 14:35
CMOS уже были клоны всё в одном, типа 1818P или 6561 и т д
Кто-нибудь проводил тесты отличия клонов от оригинала?

and1981
21.07.2024, 14:41
Я запускал тесты CPU от Blargg-а, на 1818Р, результаты показывают, что вероятно в этом ядре включена BCD коррекция и нестабильные неоф. опкоды 6502 не проходят тест, оно и понятно ибо это уже CMOS, а по поводу BCD видимо тайванцы просто не стали заморачиватся с отключением оной.

Titus
21.07.2024, 16:02
BCD коррекция и нестабильные неоф. опкоды 6502 не проходят тест
А в принципе, какие-нибудь игры с NES используют BCD или же недокументированные опкоды?

HardWareMan
21.07.2024, 17:16
А в принципе, какие-нибудь игры с NES используют BCD или же недокументированные опкоды?
В старых мульках был крыжик "halt on invalid opcode". Я ставил, но ни разу не срабатывал из тех игр, что я запускал. Но я не запускал 100% ромсета.

and1981
21.07.2024, 17:39
NESDEV пишет такое:

Игры, использующие неофициальные опкоды
Использование неофициальных опкодов редко встречается в играх NES. Похоже, что это происходит в основном в поздних или нелицензированных играх:

В «Красавице и чудовище» (E) (1994) используется $80 (2-байтовый NOP). [2]
Disney's Aladdin (E) (декабрь 1994) использует $07 (SLO). Это порт игры Game Boy от Virgin, которая сама является портом игры Genesis, а не какой-либо из пиратских оригиналов .
Dynowarz: Destruction of Spondylus (апрель 1990 г.) использует 1-байтовые NOP $DA и $FA на первом уровне, когда ваш динозавр бросает свой кулак.
Истребитель-невидимка F-117A использует $89 (2-байтовый NOP).
文字广场+排雷(в GoodNES романизировано как кантонское «Gaau Hok Gwong Cheung (Ch)»): После выбора левой игры (排雷) из этого мультикартриджа 2-в-1, глючный переключатель банков на 32 КБ заставляет ЦП теряться в некодовом пространстве ПЗУ, и только при правильной эмуляции неофициальных кодов операций, включая $8B (немедленный XAA), он в конечном итоге достигнет инструкции BRK, которая правильно переходит к обработчику сброса этой игры.
Infiltrator использует $89 (2-байтовый NOP).
Puzznic (все регионы) (выпуск в США — ноябрь 1990 г.) использует $89 (2-байтовый NOP).
Super Cars (U) (февраль 1991 г.) использует $B3 (LAX).
Домашние игры
Музыкальный движок MUSE, используемый в Driar и STREEMERZ: Super Strength Emergency Squad Zeta , использует $8F (SAX), $B3 (LAX) и $CB (AXS). [3]
Зона атрибутов использует $0B (ANC), $2F (RLA), $4B (ALR), $A7 (LAX), $B3 (LAX), $CB (AXS), $D3 (DCP) и $DB (DCP).
Порт Zork на Famicom использует несколько неофициальных кодов операций.
Эйра, Дева-Воронья использует несколько неофициальных кодов операций.
https://www.nesdev.org/wiki/CPU_unofficial_opcodes

Titus
21.07.2024, 19:10
Игры, использующие неофициальные опкоды
Использование неофициальных опкодов редко встречается в играх NES. Похоже, что это происходит в основном в поздних или нелицензированных играх:

В принципе логично, т.к. фирмы вряд ли хотели, чтобы игра не пошла на каком-то левом клоне.

CodeMaster
21.07.2024, 19:40
фирмы вряд ли хотели, чтобы игра не пошла на каком-то левом клоне.
Наоборот, как-раз, логичнее.

Titus
21.07.2024, 21:38
Наоборот, как-раз, логичнее.

Фирмы продают картриджи, и им важно, чтобы их не подделывали. А приставки пофигу какие.

CodeMaster
21.07.2024, 21:48
Фирмы продают картриджи, и им важно, чтобы их не подделывали. А приставки пофигу какие.
С чего чел купивший клон, будет покупать оригинальные картриджи.

HardWareMan
22.07.2024, 09:03
С чего чел купивший клон, будет покупать оригинальные картриджи.
А почему бы и нет? Одно другому не мешает + в 90х никто не думал про "оригинальность" приставок, однако даже у нас ходила пара десятков картриджей на Сегу и Денди, которые как я потом узнал в интернете вполне себе оригинально-лицензионные.

CodeMaster
22.07.2024, 10:03
А почему бы и нет?
Так же как и с клоном. Нет денег?

and1981
23.07.2024, 00:07
Результат запуска тестов CPU от Blargg на Денди Джуниор, процессор капля UMC UM6561BA.
Однако результат другой, нежели у Лифы sm-882 на процессоре 1818Р, у капли UMC BCD видимо таки отключена, но так как это уже CMOS, то нестабильные опкоды уже не работают. И присутвует этот злосчастный ATX, который я у себя в FPGA клоне так и не победил, хотя здесь есть и ASR, но с ним все оказалось проще :) , он просто выдаёт на выход АЛУ одновременно XOR и SR (ROL). Такая вот наркомания :)
https://pic.maxiol.com/thumbs2/1721681855.2994280316.img3084.jpg (https://pic.maxiol.com/?v=1721681855.2994280316.img3084.jpg&dp=2)

and1981
23.07.2024, 16:24
Выложил свой верилог АПУ RP2A03(7) на гит, ссылка на репозиторий тут: https://github.com/andkorzh/RP2A03-7-
Представляет собой мультисистемный дизайн, содержит в себе как NTSC, так и PAL тайминги, переключение осуществляется пином (PAL). Скоро думаю добавлю еще делитель клока для Денди (Сlk/15). Все PLA упакованы в блоки M4K (M9K) c соответсвующими файлами инициализации. Частоты для клока классические 21.477 МГц и 26.601 МГц . Каналы имеют непосредсвенный выход каждого и отдельный выход суммированных SQA, SQB, TRIA, NOISE. Планирую заняться проектированием платки заменителя APU, для использования в родном окружении.

Titus
24.07.2024, 13:18
Немного офтопа, но в тему реверса.

Что это за транзистор, у которого база соединена с плюсом питания (обведен оранжевым).
Это не простая подтяжка, а что тогда?

https://pic.maxiol.com/images2/1721816274.531452181.example.png

ALS
24.07.2024, 13:59
Это же полевые транзисторы. В таком включении они могут быть источником тока.

Titus
24.07.2024, 14:29
Это же полевые транзисторы. В таком включении они могут быть источником тока.

Но он включен не так, как другие транзисторы в роли резисторов в данной схеме. Не может же быть, чтобы одновременно и обедненные и обогащенны Н-Мопы применялись?

HardWareMan
24.07.2024, 15:17
Могут. Это нормальная практика для несимметричного каскада. Позволяет экономить кристалл. Полноценный push-pull делают только там, где это действительно необходимо.

Titus
25.07.2024, 05:00
Но это не обьясняет, почему в T9442 затвор соединен одним образом, а в T2442, затвор идет на плюс питания.
Чем отличаются оба этих включения, если и там, и там, транзистор представляет из себя фактически резистор.

HardWareMan
25.07.2024, 08:20
Но это не обьясняет, почему в T9442 затвор соединен одним образом, а в T2442, затвор идет на плюс питания.
Чем отличаются оба этих включения, если и там, и там, транзистор представляет из себя фактически резистор.
Картиночке из инторнета - верить! Вот и всё объяснение.

and1981
31.07.2024, 12:30
Добавил на гитхаб свой вариант верилога мультирегионального ППУ 2С02(7) https://github.com/andkorzh/RP2C02-7- . Как и APU, данный дизайн был выполнен на основе реверса оригинальных чипов NES (Famicom) NTSC и PAL регионов, однако для большей совместимости c играми в режиме PAL оставлен тайминг прерывания как у UA6538. Выход осуществялется в RGB на видео ЦАП. Эмфазис пока еще не реализован. Возможно будет добавлен скандаблер, чтобы можно было использовать для вывода в VGA. Опционально можно использовать вывод и в композит, если добавить композитный кодер от HardWareMan, либо в S-Video.
Фото прототипа RGB_PPU я уже публиковал ранее:
https://pic.maxiol.com/thumbs2/1722418054.1389483554.rgbfpga.png (https://pic.maxiol.com/?v=1722418054.1389483554.rgbfpga.png&dp=2)
:v2_dizzy_roll:

and1981
06.08.2024, 18:48
В далёком 2012 году на заре начала реверса 6502 org сваял своё вериложное ядро, все эти годы оно лежало в репе непроверенное. Вот решил я его таки довести до ума. :) Там у него с верхней половиной процессора все было без особых замечаний, но вот с низом (ALU, PC, Buses, Reg) - беда. Ну ничего, пришил я свои модули из своего вериложного 6502 ядра к его верху, после недолгих безуспешных попыток его запустить оно таки стартовало. Однако тесты проходило с ошибками. Буквально за полчаса все ошибки были выловлены и наказаны. :) Благо есть готовое окружение в виде FPGA клона APU NES (Famicom) куда можно пришить ядро и изголяться :D над ним пока оно не начнет нормально работать. По итогу оно даже вместилось в CPLD ALTERA EPM570. Что очень хорошо, так как не нужно тратить более дорогой Циклон.

8108681121

and1981
13.08.2024, 10:30
Поскольку тесты для платформы NES (Famicom, Dendy) не отражают в полной мере работоспособность всех модулей процессора, таких например как модуль десятичной коррекции (BCD), было решено дополнительно верифицировать свое верилог ядро 6502 с помощью функционального теста Клауса Дормана. https://github.com/Klaus2m5/6502_65C02_functional_tests
Тест занимает 96241361 циклов и проходил на частоте 2.5 МГц примерно за 40 секунд. Но и здесь не обошлось без подводных камней, :) были обнаружены нескольно недочетов в АЛУ, которые мешали полностью завершить тест, но после непродолжительного дебага все они были устранены и тест завершился успешно. Тестирование проходило на китайской девборде на базе ALTERA Cyclone IV EP4CGX150DF27I7. Очень богатый ресурсами камушек, одних LUT 150 тысяч, но главное это объем памяти М9К, который позволил разместить на внутренних ресурсах FPGA - ОЗУ емкостью 64килобайта, ибо тестирование проходит c ОЗУ инициализированным начальными значениями. Стоит эта девборда на aliexpress относительно дешево, что и определило её выбор в качестве тестового стенда. Успешное прохождение теста фиксировалось зажиганием светодиода, который был забинден на адрес $3469. Кроме того, состояние адресной шины процессора дополнительно отслеживалось с помощью 16-ти канального логического анализатора DSLogic Plus.
https://pic.maxiol.com/thumbs2/1723534169.1389483554.test3.jpg (https://pic.maxiol.com/?v=1723534169.1389483554.test3.jpg&dp=2)

https://pic.maxiol.com/thumbs2/1723534383.1389483554.test1.png (https://pic.maxiol.com/?v=1723534383.1389483554.test1.png&dp=2)

https://pic.maxiol.com/thumbs2/1723534421.1389483554.test2.png (https://pic.maxiol.com/?v=1723534421.1389483554.test2.png&dp=2)

and1981
14.01.2025, 22:39
Приехали из китая платки ФПГА заменителя NES APU 2A03
Всё запаяно и как и ожидалось всё работает. :v2_dizzy_snowball:
https://pic.maxiol.com/thumbs2/1736883450.2994275145.img3719.jpg (https://pic.maxiol.com/?v=1736883450.2994275145.img3719.jpg&dp=2)
https://pic.maxiol.com/thumbs2/1736883483.2994275145.img3721.jpg (https://pic.maxiol.com/?v=1736883483.2994275145.img3721.jpg&dp=2)

Небольшой видео отчётец https://www.youtube.com/watch?v=RvPh_PWV7ng

Добавлено 09.06.2025 Выложил в репу на гите гербер файлы и принципиальные схемы прототипов на ФПГА. Все желающие могут ознакомиться и собрать.:v2_dizzy_botan:
https://github.com/andkorzh