Важная информация

User Tag List

Страница 1 из 9 12345 ... ПоследняяПоследняя
Показано с 1 по 10 из 88

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

  1. #1
    Guru Аватар для HardWareMan
    Регистрация
    26.02.2011
    Адрес
    г. Павлодар, Казахстан
    Сообщений
    4,395
    Спасибо Благодарностей отдано 
    304
    Спасибо Благодарностей получено 
    594
    Поблагодарили
    440 сообщений
    Mentioned
    10 Post(s)
    Tagged
    0 Thread(s)

    По умолчанию Потактовый клон Денди на FPGA

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

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

    2. Вся фундаментальная информация взята с нашего проекта BreakNES, за что особая благодарность Org'у - он сделал львиную долю по распознаванию транзисторной схемы. Можно посмотреть записи стримов, чтобы узнать, как он это делал. Без него этого проекта бы не было.

    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. На стадии обкатки модель будет прогоняться вот в этой приставке:

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

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

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

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

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

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

    В сети гуляет вот такая картинка, выдранная из патента:

    На ней абстрактно показаны самые важные узлы PPU. Я буду придерживаться данной блок-схемы, насколько это возможно.

    Блок #1: Выбор регистра PPU.
    Блок #2: Системные регистры PPU.
    Блок #3: Синхрогенератор PPU.
    Блок #4: Управление локальной шиной PPU. / Мультиплексор шины данных PPU.
    Последний раз редактировалось HardWareMan; 22.10.2017 в 10:17.

  2. Этот пользователь поблагодарил HardWareMan за это полезное сообщение:

    Titus (25.12.2019)

  3. #1
    С любовью к вам, Yandex.Direct
    Размещение рекламы на форуме способствует его дальнейшему развитию

  4. #2
    Guru Аватар для HardWareMan
    Регистрация
    26.02.2011
    Адрес
    г. Павлодар, Казахстан
    Сообщений
    4,395
    Спасибо Благодарностей отдано 
    304
    Спасибо Благодарностей получено 
    594
    Поблагодарили
    440 сообщений
    Mentioned
    10 Post(s)
    Tagged
    0 Thread(s)

    По умолчанию

    PPU это Picture Processing Unit. Т.е. видеоадаптер, если упростить. Изготавливается в корпусе DIP40. УГО для PAL/NTSC PPU можно нарисовать вот так:

    Здесь, условно слева это сигналы связи видеопроцессора с центральным процессором системы, а справа это сигналы связи с личным адресным пространством 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; 20.10.2017 в 19:13.

  5. #3
    Guru Аватар для HardWareMan
    Регистрация
    26.02.2011
    Адрес
    г. Павлодар, Казахстан
    Сообщений
    4,395
    Спасибо Благодарностей отдано 
    304
    Спасибо Благодарностей получено 
    594
    Поблагодарили
    440 сообщений
    Mentioned
    10 Post(s)
    Tagged
    0 Thread(s)

    По умолчанию

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

    Так вот, логику мы опустим. Мы будем рассматривать ключевой момент - хранение состояния, в народе триггеры. Построение триггера сильно зависит от технологии. Что такое триггер? Это элемент с двумя устойчивыми состоянии. В простейшем случае это кольцо из двух инверторов:

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

    Это простейший RS триггер. Он уже может быть полезен, например, для подавления дребезга ответственной кнопки. Однако, у него есть недостаток: если активировать оба входа управления возникает неопределенное состояние. Поэтому, к нему добавляется простейшая схема управления:

    И триггер обретает сигнал строба. Это позволяет ввести нечувствительность RS триггера к изменению на входах R или S во время изменения сигнала. Замечу, что это не тактируемый тригер, а обычная прозрачная защелка, поэтому, во время активного сигнала управления неопределенное состояние все еще может возникнуть. Поэтому, сигналы R и S объединяют через инвертор и получается D триггер:

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

    Теперь, ведомый получит сигнал от мастера тогда, когда мастер станет нечувствительным ко входу. И наоборот, ведомый будет не чувствителен к изменению состояния мастера когда мастер управляется извне. Это классический тактируемый триггер (Т триггер). Если объединить R и S входы через инвертор, как это сделано у D триггера, то получаем тактируемый D триггер. Если нам нужен тактируемый D триггер с ассинхронными входами сброса и установки, то нужно вводить дополнительные ведущие RS триггеры:

    Вот так сложно дается базовый элемент синхронной схемы на технологии ТТЛ. Вот этот же примитив в схемном вводе Quartus'а:

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

    Всего два разнополярных транзистора позволяют организовать Z состояние выхода (электронный ключ):

    Причем, при определенных условиях питающего напряжения, это позволяет коммутировать даже аналоговый сигнал. Яркий пример - К561КП2 в Вега МП122 или К176КТ3. Даный ключ (на картинке блок "КК") позволяет очень просто построить триггер:

    Действительно, нет ничего проще, чем просто разорвать кольцо из инверторов. Это схема полноценного тактируемого D триггера с асинхронными входами сброса или установки. Если они не нужны, то вся схема упрощается до 2х инверторов и 2 ключей на каждый RS триггер (всего 8 транзисторов на RS триггер). Сравните с ТТЛ вариантом.

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

    Действительно, если допустить, что паразитной емкости затвора достаточно для хранения заряда в пределах периода тактовой частоты и недостаточно, чтобы исказить (затянуть фронт) форму сигнала при переключении, то транзистор с оторванным затвором можно рассматривать как элементарную ячейку DRAM, которую периодически следует регенерировать. А если еще допустить то, что нам не требуется, чтобы ток тек в обоих направлениях, то управляющий ключ упрощается до одного транзистора. Таким образом, мы получаем триггер-защелку всего из трех транзисторов (транзистор разрывающий затвор ключевого транзистора, сам ключевой транзистор и транзистор-нагрузка, если не требуется ОС):

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

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

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

    Реконфигурируемые ПЛИС выдвигают определенные требования к дизайну (так называется проект функциональной схемы, описываемой на языках xHDL либо схемным вводом). Особенность ПЛИСин в том, что они состояит из базовых блоков, в состав каждого входит один (или несколько) триггеров, логическая программируемая матрица (в старых CPLD и FGPA) или LUT (Look-Up Table в новых CPLD и FPGA) и несколько вспомогательных схем, вроде схемы выбора тактирования триггера или ускоренного переноса для организации сумматоров и счетчиков. LUT позволяет "запаковать" целый кусок логической комбинаторной схемы по построенной синтезатором таблице истинности, что положительно сказывается на "вместимости" микросхемы ПЛИС. Вот так выглядит ячейка у CPLD семейства MAX3000:

    А вот так у FPGA семейства Cyclone IV:

    Все ячейки связаны между собой магистралями. Это 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 позже.

    Надеюсь, теперь многое станет понятней.
    Последний раз редактировалось HardWareMan; 20.10.2017 в 17:10.

  6. #4
    Guru Аватар для Vslav
    Регистрация
    31.03.2013
    Адрес
    г. Киев
    Сообщений
    2,413
    Спасибо Благодарностей отдано 
    132
    Спасибо Благодарностей получено 
    755
    Поблагодарили
    353 сообщений
    Mentioned
    86 Post(s)
    Tagged
    0 Thread(s)

    По умолчанию

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

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

  7. #5
    Guru Аватар для HardWareMan
    Регистрация
    26.02.2011
    Адрес
    г. Павлодар, Казахстан
    Сообщений
    4,395
    Спасибо Благодарностей отдано 
    304
    Спасибо Благодарностей получено 
    594
    Поблагодарили
    440 сообщений
    Mentioned
    10 Post(s)
    Tagged
    0 Thread(s)

    По умолчанию

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

  8. #6
    Guru
    Регистрация
    08.10.2005
    Адрес
    Москва
    Сообщений
    13,550
    Спасибо Благодарностей отдано 
    1,213
    Спасибо Благодарностей получено 
    1,748
    Поблагодарили
    680 сообщений
    Mentioned
    67 Post(s)
    Tagged
    1 Thread(s)

    По умолчанию

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

  9. #7
    Junior
    Регистрация
    28.04.2016
    Адрес
    г. Новосибирск
    Сообщений
    15
    Спасибо Благодарностей отдано 
    3
    Спасибо Благодарностей получено 
    2
    Поблагодарили
    2 сообщений
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    По умолчанию

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

  10. #8
    Guru Аватар для HardWareMan
    Регистрация
    26.02.2011
    Адрес
    г. Павлодар, Казахстан
    Сообщений
    4,395
    Спасибо Благодарностей отдано 
    304
    Спасибо Благодарностей получено 
    594
    Поблагодарили
    440 сообщений
    Mentioned
    10 Post(s)
    Tagged
    0 Thread(s)

    По умолчанию

    Небольшое дополнение к посту про синхронность.

    Правильный синхронный дизайн, задуманный сразу таким, как правило не вызовет каких-либо подозрений у синтезатора и он не будет ругаться. И даже если фиттер раскидает его по всему кристаллу, он все равно будет работать при разных условиях, если рабочая частота будет ниже той, что рассчитает TimeQuest в отчете FMax Summary. Однако, бывают ситуации, когда применение латчей в синхронном дизайне неизбежны, особенно, когда проект переносится с железа, вроде нашего случая. Здесь нам поможет гейтирование тактового сигнала - особой схемы внутри логического элемента ПЛИС:

    Этот узел можно увидеть на картинках логических элементов выше. Он сделан специально и имеет защиту от метастабильности. В Верилоге этот вывод задействуется, если в списке чувствительности блока always будет более одного элемента. Однако, лично я не люблю когда always блок содержит что-то еще кроме тактовой частоты. Старайтесь обходиться только одним параметром. Так вот, мы можем использовать этот вывод как вход LE защелки, единственное условие это наличие более высокой тактовой частоты. В этом нам повезло: ядро PPU работает на частоте пиксельклока, что ровно в 4 раза меньше от входной частота для NTSC PPU и 5 раз выше для PAL версии. Таким образом, вот так мы эмулируем прозрачную защелку в синхронном дизайне:

    Так же, в реальном мире используются часто RS триггеры из прошлого поста. Почему? Как правило, это сделано для синхронизации внешнего события к внутреннему распорядку схемы, которая живет строго по тактовой последовательности. В случае с PPU это интерфейс CPU. Действительно, даже при общей главной тактовой частоте, делители для ядра PPU и ядра CPU изначально разные. Каждое ядро работает на своей частоте и строго не синхронно на своем уровне. При этом, более медленное может пропустить событие от более быстрого. И вот здесь выручает RS триггер, который срабатывает практически мгновенно от внешнего сигнала и сохраняет свое состояние, пока внутреннее ядро не опознает сигнал и не среагирует на него. Оно же и снимает запрос с триггера. Выглядит это примерно вот так:

    Здесь: зеленый это фронт тактовой частоты ядра, красный - ее спад. А набор 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'у это не нравится:

    И это справедливо: мы нарушаем закон синхронности дизайна. А при этом корректная работа схема не гарантируется. Она может работать, но будет зависеть от фазы луны: чуть что-то добавил или исправил и все тайминги поехали. Когда я делал схемную интерпретацию схемы PPU влоб, чтобы получить хоть что-то наглядное и работоспособное, иногда приходилось вставлять задержку в одну ячейку (примитив LCELL), заставляя удлинять путь сигнала, чтобы тот приходит тогда, когда надо. Это не правильный путь, но это пока и не требовалось. Далее, схема потихоньку кромсалась, переводя тайминги в синхронный режим. И комбинаторное кольцо выше с помощью трюка повышенной частоты (напомню, у нас есть 4х или 5ти кратная частота от ядра) этот узел стал вот таким:

    Здесь, зеленый все тот же позитивный пиксельклок, синий это повышенная частота. Функционал схемы работает так: пока 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
    Так, конечно, стало более понятно простому человеку, однако синтезатор начнет городить огород: закольцованные мультиплексоры. Вроде вот таких:

    Схема остается строго синхронной. Макроблоки, создаваемые синтезатором (мультиплексоры, сумматоры и прочее), как правило, имеют оптимизацию на стадии компиляции под выбранное семейство ПЛИС, однако, если у вас примитивное CPLD, это может отобрать целую ячейку, когда простая ручная комбинаторика OR-AND укладывается в стандартную логическую матрицу даже примитивного по нынешним меркам семейства MAX3000. Так что мозги и правильное решение иногда позволит работать вашему проекту там, где обычные индусы будут требовать жирную FPGA.

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

  11. #9
    Guru Аватар для Vslav
    Регистрация
    31.03.2013
    Адрес
    г. Киев
    Сообщений
    2,413
    Спасибо Благодарностей отдано 
    132
    Спасибо Благодарностей получено 
    755
    Поблагодарили
    353 сообщений
    Mentioned
    86 Post(s)
    Tagged
    0 Thread(s)

    По умолчанию

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

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

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

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

  12. #10
    Guru Аватар для HardWareMan
    Регистрация
    26.02.2011
    Адрес
    г. Павлодар, Казахстан
    Сообщений
    4,395
    Спасибо Благодарностей отдано 
    304
    Спасибо Благодарностей получено 
    594
    Поблагодарили
    440 сообщений
    Mentioned
    10 Post(s)
    Tagged
    0 Thread(s)

    По умолчанию

    Я же говорил, что некоторым будет не очевидно. Но давай разберем. Условия задачи таковы: если 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 Я не буду поправлять исходный вариант, чтобы данные сообщения имели смысл.

Страница 1 из 9 12345 ... ПоследняяПоследняя

Информация о теме

Пользователи, просматривающие эту тему

Эту тему просматривают: 1 (пользователей: 0 , гостей: 1)

Похожие темы

  1. Потактовый клон i8080 на FPGA/CPLD
    от HardWareMan в разделе Разработка электроники
    Ответов: 471
    Последнее: 06.07.2020, 19:39
  2. AY-3-8910 in FPGA
    от VELESOFT в разделе Звук
    Ответов: 18
    Последнее: 25.12.2015, 22:13
  3. ZX 48/128 FPGA
    от Александр Бухаров в разделе Несортированное железо
    Ответов: 6
    Последнее: 21.04.2015, 17:04
  4. Dendy on FPGA?
    от Ewgeny7 в разделе Nintendo
    Ответов: 29
    Последнее: 04.11.2009, 17:55
  5. Atari ST(E) на FPGA...
    от ILoveSpeccy в разделе Atari
    Ответов: 6
    Последнее: 26.08.2008, 20:55

Ваши права

  • Вы не можете создавать новые темы
  • Вы не можете отвечать в темах
  • Вы не можете прикреплять вложения
  • Вы не можете редактировать свои сообщения
  •