NES, реализация на FPGA

Добрый день!

Я хочу рассказать о проекте игровой консоли Nintendo Entertainment System (NES) в реализации на FPGA. На постсоветском пространстве она известна как Dendy.

NES на ПЛИС
Желающих посмотреть видео и поностальгировать прошу под кат.

Думаю, большинство людей моего возраста хорошо помнят эту игровую приставку. Была она и у меня. В 90-е годы денег в нашей семье было не очень много, поэтому у меня была даже не Денди, а совсем китайский клон Subor. Надо сказать, что работал он без каких-либо нареканий, если не считать часто ломающиеся джойстики, которые приходилось ремонтировать много раз. Конечно, спустя непродолжительный период я не смог удержаться от соблазна и разобрал приставку. Она была выполнена на двух печатных платах, одна – ВЧ модулятор и источник питания на LM7805, установленная без радиатора она сильно нагревалась, и вторая процессорная плата, которая, к большому сожалению, была выполнена на одной бескорпусной микросхеме – «капле». Насколько помню, больше на ней, кроме кварца, пары конденсаторов и разъема картриджа ничего не было. В те далекие времена очень трудно было найти какую-либо информацию, и я даже не знал, на каком процессоре работает Денди. Всего один раз я видел NES в «дискретной» реализации у соседа — радиолюбителя.

Чуть более полугода назад я заказывал на eBay отладочную плату на STM32 и увидел относительно недорогие комплекты ПЛИС Altera Cyclone II, недолго думая, заказал и его. Вообще, судя по форумам и мнениям знакомых электронщиков, тема ПЛИС до сих пор остается окутанной ореолом неприступности и сложности работы с ней. Я тоже в свое время «повелся» на это заблуждение и не уделял теме ПЛИС должного внимания, как оказалось, совершенно зря. Я влюбился в ПЛИС с первого взгляда! Труднодоступные для обычного радиолюбителя, занимавшегося микроконтроллерами, вещи, вдруг, стали реальностью. Например, полноценная работа со SDRAM, подключение ноутбучной матрицы с интерфейсом LVDS (а частоты там просто убойные). Аппетиты росли, и я купил себе плату Altera DE2-115, которая и используется для проекта NES. Теперь я очень жалею, что не занялся темой ПЛИС лет так 10 назад, не повторяйте моих ошибок, ПЛИС – это весело и вовсе не так сложно!

Помигав светодиодом (кстати, в отличие от того же STM32, где для этого надо настроить кучу периферии, на ПЛИС это делается до неприличия просто), монитором и поиграв со звуком, я решил сделать что-то посерьезнее.

Для чего все это? Как говориться, Just for fun. Конечно, кто-то может сказать, что это уже очень древняя платформа и особого смысла воссоздавать ее на ПЛИС нет, однако лично для меня было очень приятно заниматься этим проектом и увидеть конечный результат. Это, если так можно выразиться, как случайно найти и восстановить игрушку из своего детства, с которой связаны теплые воспоминания.

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

На русском языке в сети можно найти описание архитектуры NES, например, здесь.

В принципе, описание достаточно неплохое, однако создать работающий эмулятор по нему нельзя, так как в той статье очень поверхностно описаны регистры PPU — опущены очень важные моменты.

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

Перед вами электрическая принципиальная схема Nintendo Famicom:

Схема Famicom
Изображение с сайта nesdev.com

Ядро процессора A203 (U6) основано на базе восьмиразрядного микропроцессора MOS Technology 6502. На одном кристалле с 6502 находится контроллер DMA и аудиопроцессор.

На микросхеме 74LS139 (U3) выполнен декодер адреса CPU. Шина адреса 16-разрядная, поэтому процессор может адресовать до 64 КБ. Адресное пространство распределено следующим образом.

Адресное пространство CPU

Графический процессор (PPU) 2C02 – микросхема U5. Для экономии выводов PPU, младшие 8 бит шины адреса мультиплексированы с шиной данных, поэтому на доступ к памяти он тратит два такта. Для демультиплексирования адреса используется микросхема U2 — регистр-защелка 74LS373 (наш аналог ИР22).

Для хранения одной видеостраницы требуется 1 КБ памяти (изображение фона составлено из блоков (тайлов) 8x8 пикселей, а на экране помещается 30 рядов по 32 тайла). Архитектура PPU предусматривает использование 4-х видеостраниц, однако на самой NES установлено всего 2КБ видеопамяти (микросхема U4), а недостающие 2 КБ при необходимости использования всех 4-х страниц должны располагаться на картридже (отражение страниц и адресное пространство PPU будет рассмотрено ниже). Честно говоря, для меня, как инженера, это выглядит немного дико. Понятно, что во время разработки приставки на такие меры пошли из маркетинговых соображений и удешевления приставки ценой повышения стоимости картриджа. Я не знаю, сколько в то время стоили 4 КБ SRAM, но, возможно, из-за этого игр использующих 4 страницы совсем не много.

Задающий генератор выполнен на транзисторах Q2, Q3 и генерирует частоту 21.47727 МГц для NTSC версии и 26.6017 MГц для PAL. Ядро ЦП работает на частоте около 1.79 МГц, а пиксельная частота PPU в три раза выше частоты ЦП и приблизительно равна 5.37 МГц. Относительно высокая частота генератора – 24.47727 МГц требуется для кодирования цветовой информации в композитном видеосигнале и генерации «вспышки» цветовой поднесущей.

Эмуляция картриджа


Первоначально я хотел найти оригинальные картриджи NES и использовать их, однако это мне не удалось и это хорошо, потому что пришлось делать эмуляцию картриджа. В самом простом варианте картридж – это просто две микросхемы ПЗУ — память программы CPU (PRG ROM) и память знакогенератора PPU (CHR ROM), в этом случае максимальный объем PRG ROM – 32 КБ, а CHR ROM – 8 КБ. Так можно запустить простые игры типа Super Mario Bros.1, Lode Runner, Popeye и т.д. Конечно, 32 КБ крайне мало для более-менее серьёзной игры, поэтому применяются специальные решения (мэпперы) для переключения банков памяти, которые позволяет расширить доступный объем до нескольких мегабайт. Вариантов мэпперов существует огромное множество, как на дискретной логике 74 серии, например, мэппер UxROM построен на счетчике 74HC161, который используется как защелка и 74HC32 – 4 элемента ИЛИ, так и специализированные ASIC решения, например MMC3. Сейчас в проекте реализованы только эти два мэппера. MMC3 выбран не случайно, так как именно на нем была выпущена основная масса всеми любимых игр.

В среднем объем картриджа составляет около 256 КБ, картриджи, объемом более 1 МБ большая редкость. На плате DE2-115 установлено 2 МБ памяти SRAM (1M x 16) и 128 МБ SDRAM. Я решил, что 640 КБ хватит всем 2МБ для картриджа более чем достаточно и выделил 1 МБ для PRG ROM и 1 МБ для CHR ROM. Адресное пространство общее, в старшем байте слова хранятся данные PRG, а в младшем — CHR. Загрузка образов осуществляется с SD карты из файлов в формате iNES. Для обслуживания FAT и загрузки файлов я использовал процессор Nios II (в части самой NES все реализовано аппаратно, Nios не используется).

На диаграмме показан блок эмуляции картриджа:

блок эмуляции картриджа

Блок связан с процессором Nios II 4-х разрядной шиной адреса и 8-и битной шиной данных. Контроллер блока имеет 7 регистров управления, с помощью которых можно управлять состоянием NES – приостановить, произвести аппаратный сброс, задать опции отражения видеостраниц, тип мэппера, разрядность адресных шин PRG и CHR ROM. Для загрузки образа предусмотрены команды выбора области загрузки (CHR или PRG), сброса адреса. После записи очередного байта происходит автоинкремент адреса.

Так как шина адреса является общей для PPU и CPU, то блок мультиплексора работает на повышенной частоте, в моем случае это 32.22 МГц – в 6 раз выше частоты PPU. Далее, уже раздельные адресные шины заходят на блок мэпперов, где реализованы MMC3 и UxROM, а выбор активного мэппера задает состояние регистра управления. При необходимости, добавить поддержку любого другого мэппера очень легко.

Например, так выглядит реализация UxROM:

UxROM

В оригинальной NES, с аппаратной точки зрения, ничто не мешает в картридже вместо ПЗУ знакогенератора установить ОЗУ и инициализировать ее в процессе выполнения программы, производя запись через регистры PPU. Такие картриджи и игры существуют, например это Contra, Castlevania и множество других игр на UxROM. Этот подход имеет свои плюсы, например, часть икон знакогенератора может быть синтезирована программно, также можно хранить содержимое знакогенератора в сжатом виде и производить декомпрессию в CHR RAM, это здорово сэкономит пространство на картридже.

Так как я и так использую ОЗУ для хранения CHR, то эта функция получилась у меня по-умолчанию.

Ввод


В качестве устройства ввода используется USB джойстик. Обслуживание USB тоже осуществляется процессором Nios II:

Джойстик

Состояние всех кнопок джойстика упаковывается в слово и по параллельной шине заходит на блок сериализатора. Процессор NES, производя запись по адресу 0x4016, формирует стробирующий импульс, при этом происходит загрузка байта состояния (8 кнопок) в сдвиговый регистр. Далее, при обращении к 0x4016 (для первого джойстика) и 0x4017 (для второго) происходит сдвиг и считывание состояния очередной кнопки. Кнопки «Турбо» в оригинальной NES реализованы в самом джойстике и имитируют частое нажатие кнопок A/B, то есть на самом деле NES не различает какая кнопка зажата, «Turbo A» или «A». В проекте эта функция выполнена в блоке сериализатора, частота около 20 Гц.

PPU


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

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

Адресное пространство PPU распределено следующим образом:

Адресное пространство PPU

Видеостраницы располагаются таким образом, что, например, при горизонтальном или вертикальном скроллинге на экране будет видно содержимое сразу двух страниц, а при диагональном – четырех. Расположение страниц и координаты показаны на рисунке:

Видеостраницы

Как я уже писал выше, на самой NES под память страниц присутствует 2 КБ ОЗУ. Поэтому, если на картридже не установлена недостающая память, применяется отражение страниц. Вертикальное, когда вторая страница отражает нулевую, а третья – первую, и горизонтальное – первая страница отражает нулевую, третья – вторую.

В проекте на FPGA экономить 2 КБ нет никакого смысла, поэтому под видеопамять выделены все 4 КБ. Аппаратно отражение реализовано очень просто – в случае вертикального отражения у адресной шины ОЗУ оторвана от PPU и подключена к нулю линия, относящаяся к 11 биту, а в случае вертикального 11 и 10-я поменяны местами, а старшая линия тоже подключена к нулю:

Отражение страниц

Некоторые мэпперы могут динамически менять варианты отражения страниц, переключая линии шины адреса. В качестве примера можно привести игру Super Mario Bros. 2, где в самом начале игры при падении используется горизонтальное отражение, а потом производится переключение на вертикальное.

Регистры PPU


Для взаимодействия с PPU используется 8 регистров (имеется ввиду адресное пространство CPU).

Регистр 0x2000 (только запись)

Это регистр контролирует состояние PPU, например, задает размер спрайтов (8x8 или 8x16), страницу видеопамяти, и разрешение генерации прерывания NMI.

Регистр 0x2001 (только запись)

Регистр задает разрешение на отрисовку спрайтов и фона. Также с его помощью можно запретить отрисовку вообще, и тогда CPU сможет в любое время обращаться к областям памяти PPU, это используется играми при первоначальной инициализации страниц при смене игровой обстановки и заполнении CHR RAM, если вместо ПЗУ была использована ОЗУ. Без запрета, доступ к памяти PPU возможен только в VBLANK период, когда PPU не производит обращения к ней.

Регистр 0x2002 (только чтение)

В этом регистре находятся флаги состояния PPU. Это факт начала отрисовки первого непрозрачного пикселя нулевого спрайта, начало VBLANK периода и флаг, указывающий, что на текущую линию попадают более 8 спрайтов.

Регистр 0x2003 (только запись)

Задает адрес для последующей манипуляции с памятью спрайтов (Object Attribute Memory – OAM).

Регистр 0x2004 (запись/чтение)

Чтение и запись данных OAM. После операции происходит автоинкремент значения адреса. Обычно игры не пишут в OAM таким способом, а используют DMA.

Регистр 0x2005 (только запись)

Регистр скроллинга. При первой операции записи в регистр задается значение горизонтального скроллинга, при второй – вертикального.

Регистр 0x2006 (только запись)

Задает адрес для последующей операции с памятью видеостраниц. При первой операции задается старшая часть адреса, при второй – младшая.

Регистр 0x2007 (запись/чтение)

Чтение и запись данных из памяти видеостраницы. После операции происходит автоинкремент значения адреса на 1 (следующая колонка) или на 32 (следующая строка), это зависит от состояния бита 2 регистра 0x2000.

Регистры с двойной записью используют общий триггер, поэтому нельзя, например, произвести однократную запись в 0x2005, затем в 0x2006, а потом опять вернуться к 0x2005. Точнее, можно, но нужно при этом понимать, зачем это делаешь. Если состояние триггера неизвестно, можно прочитать регистр 0x2002, при этом происходит сброс триггера.

Звучит все просто! Но тут есть крайне важная особенность, которая не указана в упомянутом выше русскоязычном описании.

Дело в том, что перечисленные регистры, так сказать, не совсем независимые.

Существует два 15-битных регистра:
vVRAM – текущий адрес видеопамяти (далее просто «v»);
tVRAM – временный адрес (далее просто «t»);
и 3-х битный регистр «точного» скроллинга по X (fine X scroll). Задает скроллинг (0..7) в пределах 1 тайла.

Адреса v и t формируются следующим образом:

Формирование адреса

Таким образом, задание страницы путем записи в регистр 0x2000 изменяет биты 11,10 регистра t. Запись в регистр 0x2005 задает значение битов 4:0 и 9:5/14:12 регистра t и значение «точного» скроллинга по X. А вот записью в регистр 0x2006 можно вообще все испортить, так как таким образом можно поменять значение сразу всех битов регистра t, причем при второй операции записи происходит копирование v = t.

В процессе отрисовки строки, PPU увеличивает значения грубого скроллинга по X в регистре v и соответствующим образом меняет адрес видеостраницы при переполнении значения грубого скроллинга. В конце видимой строки (пиксели 256-257) PPU увеличивает значение Y и производит копирование компонентов, относящихся к горизонтальному скроллингу (v[4:0] = t[4:0] и v[10] = t[10]). Перед началом нового кадра (pre-render) производится копирование компонентов вертикального скроллинга (v[9:5] = t[9:5], v[14:12] = t[14:12], v[11] = t[11]). И все начинается заново.

Теперь понятно, как меняя значения регистров PPU можно получить различные эффекты разрыва фона.

Немного о формировании изображения


Цвет каждого пикселя выбирается из палитры. Для фона и спрайтов существуют отдельные палитры. Палитра – это область памяти, размером 16 байт. Нулевой элемент палитры фона задает цвет холста. При рендеринге пикселя фона формируется 4-х битный адрес, указывающий на элемент цвета в палитре. Два старших бита адреса являются значением атрибута группы тайлов, а два младших задаются изображением из знакогенератора. Меняя атрибуты группы можно менять цвет тайлов, используя один и тот же элемент знакогенератора.
Первые 960 байт видеостраницы (name table) задают адреса тайлов из знакогенератора CHR, находящихся на странице. Каждый из оставшихся 64 байтов видеостраницы (attribute table) задает атрибут группе из 16 тайлов (область 32x32 пикселя).

Для хранения изображения одной иконы в памяти знакогенератора используется 16 байт. Каждый пиксель, как уже было сказано выше, кодируется двумя битами. Первые 8 байт относятся к младшему биту пикселя, а следующие 8 байт – к старшему. То есть пара байтов 0+8, 1+9 и т.д. задают строки иконы.

Формирование изображения
Цвета в примере выбраны условно. Элементы, которые равны нулю, являются прозрачными и значение атрибута на них не влияет.

Атрибуты группы задаются следующим образом:

Атрибуты

За один такт PPU должен быть отрисован один пиксель. Надо понимать, что на оригинальной NES, за 2 такта PPU мы можем получить всего 1 значение из памяти. Поэтому перед началом строки в конце HBLANK периода осуществляется выборка данных для первых двух тайлов новой строки.

Выборка данных, необходимых для вывода строки тайла осуществляется за 8 тактов PPU. Сначала из видеопамяти получаем адрес тайла в знакогенераторе (2 такта), затем значение атрибута группы (2 такта), далее младший байт строки тайла из знакогенератора (2 такта), и, наконец, старший байт тайла (тоже 2 такта). И все начинается заново.

Так как я не мультиплексирую шину адреса с шиной данных, то в своем проекте могу получать данные на каждом такте PPU.

Спрайты


В разделе, описывающем регистры PPU, была упомянута область памяти спрайтов — Object Attribute Memory (OAM). Ее размер составляет 256 байт, она расположена на кристалле PPU в отдельном адресном пространстве, это означает, что к этой области возможен одновременный и независимый от, например, VRAM и CHR ROM доступ.

На каждый спрайт в OAM отводится 4 байта – поэтому одновременно на экране могут находиться не более 64-х спрайтов.

Изображения спрайтов также хранятся в знакогенераторе (CHR ROM).

Каждый спрайт на экране описывается его положением на экране по X и Y, адресом иконы в знакогенераторе, атрибутом (то же самое, что атрибут группы при отрисовке фона), флагами отражения спрайта по горизонтали и вертикали (для вывода симметричных объектов можно использовать половинки одной иконы знакогенератора) и флагом приоритета.

Спрайты могут иметь размер 8x8 и 8x16 пикселей.

Формирование изображения спрайта ничем не отличается от формирования изображения фона. Однако, в аппаратной реализации, опять же есть свои особенности.

Одновременно с отрисовкой строки производится поиск спрайтов, которые будут видимы (попадают) на следующую строку (in range evaluation). В PPU существует область памяти (secondary OAM), которая может хранить информацию о 8 спрайтах. Если при поиске окажется, что на следующей строке находятся более 8 спрайтов, то лишние спрайты игнорируются и в регистре PPU 0x2002 взводится флаг, сигнализирующий об этом.

Так как во время отрисовки строки шина CHR ROM занята, то выборка данных из знакогенератора о цвете пикселей этих 8 спрайтов происходит в HBLANK период.

NES формирует картинку разрешением 256x240 точек. Для вывода изображения я использую стандартное разрешение VGA 640x480. PPU производит рендеринг изображения в буфер кадров. Данные из буфера кадров поступают на блок, в котором происходит удвоение разрешения (upscaler). В будущем я хочу реализовать hq2x. Перед подачей данных на видео ЦАП происходит преобразование цвета в RGB.

Вывод изображения

Контроллер DMA


Для быстрого заполнения OAM, процессор NES может воспользоваться контроллером DMA. Контроллер DMA реализован очень просто. Перед началом операции копирования, CPU должен задать начальный адрес OAM (регистр 0x2003), точнее сбросить его в 0. Затем CPU производит запись по адресу 0x4014 значения начального адреса (0x??00) в адресном пространстве CPU. Контроллер DMA производит останов CPU и начинает копирование 256 байт из области 0x??00 – 0x??FF (где ?? – значение, заданное CPU) в регистр PPU 0x2004. PPU увеличивает адрес OAM на единицу при каждой операции записи. По окончании процедуры контроллер DMA возвращает управление CPU.

Приоритет и Sprite 0 Hit


Конечное значение цвета пикселя формируется следующим образом:

Слои изображения

Вполне возможна и часто случается ситуация, когда в одной области находятся более одного спрайта.

В этом случае на приоритет вывода на экран влияют два фактора – это значение адреса спрайта в OAM и флаг приоритета (0 – передний план, 1 – задний). Например, спрайт, у которого флаг приоритета указывает, что он относится к заднему плану, но при этом значение адреса в OAM меньше, чем у спрайта переднего плана, то спрайт заднего плана может закрыть спрайт переднего, что приведет к выводу пикселя фона, но только если он не прозрачный.

При отрисовке первого непрозрачного пикселя спрайта с адресом 0 (фон в этой точке тоже должен быть непрозрачный), в регистре 0x2002 взводится флаг, указывающий, что произошло событие Sprite 0 hit. В качестве примера применения этого флага можно привести игру Super Mario Bros. 1, в ней оно используется для разрыва экрана и отделения статичной информации об очках и времени от игровой области. В качестве фона выступает изображение монетки, а в качестве нулевого спрайта – ее тень. CPU периодически проверяет значение флага, и при возникновении события начинается вывод игрового поля.

Пример Sprite 0 Hit

Прерывание от мэппера MMC 3


Мэппер MMC3 имеет в составе счетчик строк, значение которого уменьшается при выводе очередной строки PPU. При достижении нуля счетчик перезагружается значением, которое может быть задано предварительной записью в соответствующий регистр мэппера и, если установлен флаг разрешения, возникает прерывание CPU. Достаточно оригинально организована линия тактирования счетчика – она подключена к адресной линии A12 графического процессора. Для хранения тайлов фона обычно используется младший банк (область 0x000 – 0x0FFF), а для спрайтов – старший банк (область 0x1000 – 0x1FFF). При отрисовке видимой строки PPU обращается к одному банку, а при выборке данных изображения спрайтов в HBLANK период – к другому. Поэтому частота на линии A12 будет соответствовать частоте вывода строк. Прерывания мэппера применяются в основном для разрыва экрана и переключения банка знакогенератора.

Примеры можете посмотреть на видео.

APU


Аудиопроцессор NES находится на одном кристалле с CPU. Функционально APU – это набор регистров управления, счетчик кадров и 5 блоков аудиоканалов.

С аппаратной точки зрения APU это куча счетчиков, подводных камней там нет, поэтому описание будет кратким.

Счетчик кадров формирует тактирующие импульсы частотой примерно 240 Гц, 120 Гц для блоков APU, а также прерывание IRQ для CPU. Генерацию прерывания можно отключить с помощью задания регистров APU. Не следует путать понятие «кадры», в данном случае никакого отношения к PPU оно не имеет.

Кстати, при разработке произошел неприятный случай, счетчик кадров APU был уже реализован и я напутал с флагом разрешения прерывания (он оказался инвертирован), поэтому прерывание генерировалось с частотой примерно 60 Гц. Внешне это проявилось очень неожиданно – в игре «Принц Персии» в левой части экрана не выводился проем двери с решеткой, причем это был единственный графический артефакт. Я голову сломал, пока нашел настоящую причину. Причем думал, естественно, на PPU – сто раз проверил код, смотря в ModelSim. Это было неприятно!

APU обходится пятью каналами:

Два прямоугольных канала, как видно из названия, они формируют сигнал прямоугольной формы, один треугольный канал, один канал шума и канал дельта-модуляции (DMC).

Прямоугольные каналы могут формировать сигнал с изменяемыми скважностью (4 градации) и периодом, с возможностью задания длительности, а также имеют блоки sweep и envelope. Блок sweep может изменять (последовательно увеличивать или уменьшать) период сигнала во времени, а блок огибающей (envelope) – уменьшать размах сигнала во времени с возможностью зацикливания, форма огибающей в этом случае – пилообразная.

Треугольный канал формирует сигнал треугольной формы с изменяемой частотой и длительностью, однако не имеет возможности регулировки громкости.

Канал шума генерирует псевдослучайный сигнал с изменяемой длительностью. Также, как и прямоугольный канал, канал шума имеет блок контроля огибающей (envelope).

Канал дельта-модуляции в проекте пока не реализован.

Микширование каналов производится табличным способом, чтобы не использовать «тяжелые» с точки зрения потребления LE операции.

После микширования сигнал поступает на блок синхронизации домена и фильтр, после чего через блок сериализатора по шине I2S уходит на аудиокодек WM8731.

Вывод звука

При реализации проекта я пользовался языком описания аппаратуры Verilog 2001.

Предвосхищая вопросы относительно исходного кода, могу сказать, что, так как это мой первый большой проект на ПЛИС, то наверняка я реализовал многие вещи очень неэффективным способом. К тому же это самая первая версия, код нужно оптимизировать и очищать, потому что многие блоки я переписывал несколько раз. Поэтому я бы не хотел предоставлять его в таком виде. Если я найду время, соберусь и приведу код в порядок, то, возможно он будет выложен под лицензией GNU GPL.



Спасибо за внимание!
Поделиться публикацией
AdBlock похитил этот баннер, но баннеры не зубы — отрастут

Подробнее
Реклама
Комментарии 77
  • 0
    молодца,

    как я понял, работает связка: NES -> Nios -> FPGA,
    где NES CPU -> С/С++ эмуляция на Nios
    или чистый Verilog?
    • +11
      Спасибо!
      Нет-нет, Nios II используется только для загрузки образов с SD и для USB джойстика. Думаю, поддержку FAT32 было бы немного неразумно делать аппаратно, когда есть Nios. Все остальное (CPU6502, PPU, APU и т.д.) Verilog.
      • 0
        да, логично

        >Канал дельта-модуляции в проекте пока не реализован.
        интересная задача…
    • 0
      Супер!
      Сам когда то заняться подобным но лень так и не дала.
      • +11
        Действительно, огромная работа! Удачи в дальнейших ваших начинаниях :)
        • –18
          image
          • 0
            но зачем вам эта приставка?
          • +11
            Я в восхищении! Автору высочайший респект и уважуха!

            Было бы ещё круто, если бы можно было сие повторить (т.е. ссылки где купить отладочную плату, скачать прошивку). Ибо, уверен, что даже относительно далёким людям будет интересно поиграть в Деньди. А потом, быть может эти далёкие люди начнут осваивать Verilog. И не будут бояться. Как в анекдоте:

            Мой кот боялся пылесоса. Но ничего, потом втянулся


            Так и люди, боятся ПЛИС, а потом втянутся. Так что было бы замечательно ещё статью-инструкцию, как это сделать самим :)
            • +4
              Спасибо большое!
              Так великолепная инструкция уже написана на nesdev.com. По своему опыту скажу, что в Verilog самое сложное — это начать «мыслит аппаратно», поначалу это действительно сложно, особенно если приходится каждый день скакать Verilog / процедурный язык типа C. Кстати, некоторые вещи вообще проще реализуются на Verilog. А, например, операции сдвига, «сборка адреса» tVRAM/vVRAM из примера в этой статье, так вообще одно удовольствие, ведь аппаратно это все равно что «провода» со смещением подключить — на ПЛИС это условно бесплатные операции.
              • 0
                Ну я имею в виду, что я бы малой кровью сделал бы себе такую Деньди, без разбирательства с верилогом (пока что) :).

                По своему опыту скажу, что в Verilog самое сложное — это начать «мыслит аппаратно», поначалу это действительно сложно, особенно если приходится каждый день скакать Verilog / процедурный язык типа C.


                Это да… Помню, для меня было просто взрывом мозга, что на компе все инструкции выполняются последовательно, а тут все СРАЗУ!
                • 0
                  Особенно круто совместить несовместимое и писать/симулировать железо не на Verilog или VHDL, а прямо на C++. Получается довольно страшно, и с синтезом пока серьезные проблемы, но как мост между истинным C и настоящим Verilog — вполне себе, как минимум со взрывом мозга от параллельности справиться помогает.
                  • +3
                    Во время стажировки в компании Aldec в Польше занимался такой задачей — трансляция VHDL в C++, для последующей компиляции и быстрой симуляции железа на PC. Насколько помню этот продукт у них называется Active-HDL. Сделал и я свой маленький вклад в него…
                    • 0
                      Active HDL работает через трансляцию VHDL в C++? Если честно ОЧЕНЬ удивлён, не ожидал, что они реализуют свой софт именно так…
                    • НЛО прилетело и опубликовало эту надпись здесь
                      • 0
                        На моем опыте SystemC не дает заметных преимуществ перед Verilog или VHDL, а синтезируемое подмножество оказывается даже сложнее.
                        Так что лучше сразу на Haskell. :-)
                • +10
                  Годнота! Жду сорцы на гитхабе.
                  • +4
                    Отлично.
                    Мой опыт работы с FPGA пока ограничивается синтезом и отладкой пары десятков очень простых программ на VHDL, используя Spartan-3A Starter Kit, поэтому такой проект выглядит очень сложным, но дико крутым.
                    Много времени заняла реализация?
                    • +6
                      Порядка 3-х месяцев работы по вечерам.
                    • +6
                      Очень круто! Объём проделанной работы впечатляет.
                      • +2
                        Курто! Ждем следующего релиза с ударными.
                        • +24
                          У меня для вас плохая весть… У Курта не будет больше релизов с ударными.
                          • 0
                            а жаль, очень жаль.
                        • +4
                          Очень круто не то слово.
                          ps: Увидел цену DE2-115 и немного погрустил Price: $595
                          • +3
                            а если на такой приставке реализовать еще и Sega mega drive II, и предел моих мальчишецких мечтаний — сони плейстейшн — то было бы оправданно по цене.
                            • 0
                              Обратите внимание, что у продавцов есть и академическая лицензия (для студентов, преподавателей и сотрудников). Можно попробовать заказать плату по этим каналам.
                              • +1
                                Я покупал по студенческой цене, спасибо другу, он работает в университете.
                                Кстати, есть варианты намного дешевле, например, можно купить модуль на Cyclone IV за 35 долларов и использовать его на самодельных ЛУТ платах. Зато можно поэкспериментировать и решить, хочешь продолжать или нет. DE2-115 хороша тем, что на борту куча периферии уже есть, но для начинающего, я думаю, сама FPGA там немного великовата (115k LE), хотя есть конечно и DE2/DE1.

                                У Terasic еще есть маленькая плата DE0-Nano за 60 USB для студента, но Terasic отправляет только экспресс-методами и цена доставки выходит дороже платы, невыгодно получается.
                                • 0
                                  Как вариант, можно использовать и готовые модули. На том же стартерките есть недорогие (порядка 2 т. р.) модули.
                              • +3
                                Найдите любой студак и купите за 300.
                                • +10
                                  И за что минусы? Терасику реально пофиг студент вы или нет, им нужно отчитаться перед Альтерой, что купил студент и они сделают вам скидку! Суть коммента состояла в том, что заказать со скидкой может любой человек.
                                • 0
                                  Попробуйте эту же плату от терасика или плату DE1 — возможностей меньше, но и цена более приятная. Если охота попробовать вкуснятину в виде CortexA9+FPGA ( Cyclone 5), то EBV уже выпустили socrates board, цена получается под 400 евро, но оно того стоит. Для совсем первоначального знакомства — закажите De0-nano, а чтобы не связываться с дхл и прочими курьерами, сделайте у наших поставщиков — у тойже терраэлектроники.
                                • 0
                                  Автору респект у самого в универе есть такие, но реализация NES только в планах… Если вам интересно, то на OpenCores есть реализация SoC, на которой можно запустить DOS/
                                  • 0
                                    Сколько ресурсов FPGA кушает проект? Можно ли его портировать на недорогое железо типа gameduino (микросхема XC3S200A-4VQG100C, Xilinx семейства Spartan-3A)?
                                    • 0
                                      Если не считать Nios, то около 4300 LE. Но это очень много — еще можно многое оптимизировать!
                                      Кстати, еще про память. В качестве CPU RAM (которая 2 КБ + 6 КБ) и PPU VRAM (4 КБ) я использую память на самом Циклоне (M9K).
                                      Но это не совсем оптимально, потому что так как память картриджа (PRG/CHR ROM) — внешняя SRAM, и учитывая, что CPU/PPU обращается к своим RAM и ROM не одновременно (шина-то у них общая), то можно подмэппить RAM и VRAM на ту же самую внешнюю память, где хранится образ картриджа, даже частоту поднимать не потребуется, тогда проект можно будет запустить на маленьких чипах.
                                      По поводу XC3S200A боюсь соврать, я с Xilinx не работал, но вроде бы при желании можно запустить. Я в комментариях упоминал модули CoreEP4CE10 (он на чипе EP4CE10F17C8N) и CoreEP4CE6 (на EP4CE6E22C8N) — вот на них 100% можно с внешней памятью.

                                    • 0
                                      Восхитительно!
                                      • 0
                                        Извиняюсь за глупый вопрос, но, можете вкратце описать разницу ПЛИС между, тем же микроконтроллером? Я как-то сложно представляю, как можно управлять/изменять железную структуру чипа програмно.
                                        • +13
                                          Сейчас объясню на пальцах.

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

                                          Вернемся опять к отдельным блокам. Если их соединить одним образом, получится одно устройство, другим — другое. Из набора достаточно универсальных блоков можно собрать почти что угодно. В один прекрасный момент нам стало лень перепаивать провода, и мы поручили электронике задачу перекоммутации. Все модули связываем в сеть, а электронные ключи соединяют их в нужном порядке.

                                          Теперь уже привычным способом уменьшим эту структуру и получим ПЛИС. Она состоит из большого числа одинаковых простых блоков, линий связи между ними, ключей, которые могут соединять или разъединять те или иные связи, и небольшой управляющей схемы, которая читает «прошивку» и управляет ключами.
                                          • 0
                                            При работе с ПЛИС, мы не привязываемся к архитектруным особенностям (в отличии от микроконтроллера). Если например мы делали прошивку для ПЛИС фирмы Altera, то мы без особого труда можем ее перенести на ПЛИС фирмы Xilinx. Главное при этом переназначить ноги (пины) конечной ПЛИС.
                                            • +6
                                              Если например мы делали прошивку для ПЛИС фирмы Altera, то мы без особого труда можем ее перенести на ПЛИС фирмы Xilinx
                                              Ну-ну… Нельзя просто так взять и перенести проект с Альтеры на Xilinx. У них разная организация логических блоков, разные наборы периферии. Даже стандарты языков Verilog и VHDL их трансляторы понимают немного по-разному. Да, после некоторых плясок с бубном перенести можно, но я не назвал бы это «без особого труда».
                                              • 0
                                                Прошу прошения, я с Вами полностью согласен. Я имел ввиду типовые простые проекты. Сталкивался пару раз, что после Альтеры Xilinx не хотел компилировать, но это решилось тем, что немного переписал код на Verilog'e на который ISE ругался и заработало.
                                              • 0
                                                Увы, все далеко не так просто, особенно последние годы с появлением специализированных аппаратных модулей различных у разных микросхем.
                                                • 0
                                                  Это есть. Я ходил на последнюю конференцию Xilinx. Они вообще стараются делать все так, чтобы Альтере тяжело было c них скопировать что-то в технологическом плане.
                                              • +1
                                                Дополню тех, кто писал выше. На ПЛИС вы можете написать микроконтроллёр и под него уже написать программу в этом преимущество ПЛИС. В данном посте как раз и рассмотрено написание микроконтроллёра (процессора Z80) со всей перефирией. Микронтроллёр такое не позволяет сделать. В некотором роде вы делаете прототип микросхемы ПЛИС для этого и создавались, прошивка ПЛИС может быть перенесена не только на другой ПЛИС, но и на ASIC (полностью заказной камень), для этого некоторые производители делаю ПЛИС, максимально похожие по структуре на ASIC, например серия ProASIC от Actel
                                                • –1
                                                  При всем уважении, но MOS 6502 ни разу не Z80. Это раз. Два — это что мешает создать эмуль любого проца на микроконтроллере? Тем более такого простого как 6502? Да ничто, пара-тройка десятков строк на си.
                                                  • +1
                                                    Думаю, человек просто торопился и ошибся по поводу Z80. Z80, кстати, используется как сопроцессор в приставке Sega Genesis (Mega Drive).

                                                    Вы меня тоже извините, но вот прямо таки любого, да на микроконтроллере? Не выйдет. Точнее с адекватной производительностью не выйдет. По-моему была статья, как Дмитрий загрузил Linux на AVR. Два часа загружался, эффективная частота всего несколько килогерц, а так ничего. И что вы подразумеваете под микроконтроллером? Ядро того же AVR не намного сложнее 6502.
                                                    Программная эмуляция как минимум потребует значительного (в несколько раз) увеличения тактовой частоты эмулирующей системы, а на ПЛИС — нет.

                                                    Конкретно вариант MOS6502 для NES можно при желании запустить на STM32, но я бы не сказал, что это прям так просто, по сравнению с эмулятором на PC, у которого производительность во много раз выше. Причем в любом случае придется возиться с «тактовой совместимостью» -учитывать за какое количество тактов выполняется каждая команда на реальном 6502. Иначе как минимум будут непредсказуемые эффекты на выводимой картинке из-за синхронной работы PPU-CPU (я про это говорил в статье).
                                                    • –2
                                                      А торопиться не надо. Нужно отделять мух от котлет, в смысле Z80 сюда никаким боком не причастен. Человек вот прямо пишет:
                                                      Микронтроллёр такое не позволяет сделать.
                                                      и это есть неправда. Не знаю, с какими вы там микроконтроллерами на килогерцах работаете, но я знаю с десяток общедоступных (читай по стоимости с пару бутылок пива) микроконтроллеров с частотой от 20 Мгц. И уж на 20 Мгц умудриться не сымулить 6502 это я не знаю, постараться надо. Наверное, действительно нужно запустить пару-тройку часов линупс, на нем за сутки поднять питон и на нем уже за год обработать один опкод 6502.
                                                      • –1
                                                        Я не говорб за всю перефирию типа PPU и процее. Я только за сам проц.
                                                      • 0
                                                        Извиняюсь, извиняюсь, думал о GameBoy писал о NES, это в GameBoy стоит модифицированный Z80, но сути это не меняет. Вы не можете на микроконтролёре сделать процессор, вы можете написать эмулятор процессора для микроконтролёра. А вот в ПЛИС вы может сделать процессор, если у вас есть его схема, то вы сделает клон, а не эмулятор, если схемы нет вы сделаете аналог с совместимой системой команд, а не эмулятор. Если у вас есть достаточно скила, то вы можете повторить не только архитектуру, но и микроархитектуру. Ещё раз говорю устраивать холивар между ПЛИС и микроконтроллёром занятие бессмысленное, ПЛИС нужны для прототипов цифровых микросхем или для того, что бы реализовать сложные вычисления определённого вида, т.е. если вам надо заточить железку под узкую задачу.
                                                        • 0
                                                          В ГБ стоит Sharp LR35902. Наши его называют «сильно упрощенным Z80», буржуи — «гибрид i8080 и Z80». Я его считаю «частично совместимым с Z80/i8080». Точном огу сказать только после декапа. К слову, декап 2A03 (или 6527 в случае клона) видно, что ядро CPU — полная копия кристалла 6502, за исключением 6 поправок, который отключают десятичный режим (защита от патента на 6502). Полную информацию можно взять здесь: www.breaknes.com

                                                          Кстати, китаец уже пару лет как создал Verilog модель точного PPU по работам BreakNES. forums.nesdev.com/viewtopic.php?f=9&t=10920

                                                          Китайцы уже стали делать клоны с FPGA вместо PPU. forums.nesdev.com/viewtopic.php?f=9&t=12578&p=149249

                                                          По NES теперь вообще нет белых пятен. Правда, полная схема только в транзисторах, но мы работаем над этим.
                                                  • 0
                                                    Круто, круто. Не думали туда реальный 6502 впилить, а все остальное — на плис?
                                                    • +2
                                                      Спасибо! В этом нет смысла. Можно и PPU (2C02) найти, но тогда это будет уже совсем неинтересно.
                                                      К тому же это надо искать CMOS версию 6502. И могут быть проблемы с недокументированными опкодами 6502, а в ПЛИС версии, при необходимости, можно добавить что угодно.
                                                    • +10
                                                      Вот какие должны быть статьи на хабре, ребята! А то я уже собрался из RSS вычеркивать, ибо тривиальщина и копипаст уже задрали. Автору респект. Почитал с удовольствием.
                                                      • –2
                                                        Не совсем понятно (а точнее, совсем не понятно), какие преимущества имеют такие FPGA по сравнению с микропроцессорами? Судя по характеристикам, они дороже, медленнее, ещё и программируются сложнее.
                                                        • –1
                                                          Основная сфера применения — цифровая обработка сигналов.

                                                          stackoverflow.com/questions/2909035/algorithms-fpgas-dominate-cpus-on

                                                          stackoverflow.com/questions/317731/cuda-vs-fpga
                                                          • +2
                                                            По поводу сложности в программировании, то наверное для людей далеких от FPGA — это так. Но «не боги горшки обжигают», как говорит пословица.

                                                            По поводу преимуществ, то мы можем реализовать абсолютно любую простую или сложную цифровую систему или устройство, просто описав логику работы каждой микросхемы входящей в устройство, используя языки описания аппаратуры Verilog / VHDL или делая все в виде схем (на уровне триггеров и регистров).

                                                            По поводу микропроцессора, то мне кажется он будет подороже чем FPGA. Если конечно Вы не подразумеваете микроконтроллер, то он действительно дешевле чем FPGA. Мы заказывали FPGA Altera Cyclone III в последний раз что-то около 1200 рублей за штуку, а микроконтроллер, мне кажется, будет стоить в пределах 300-500 рублей. Не учитывая сверхдорогие флагманские модели тех и других.
                                                            • –5
                                                              По поводу цены — вот в комментах писали, что $300 академическая цена. В то время, как например Raspberry Pi — $25/35.
                                                              • +3
                                                                Сравниваете теплое с мягким.
                                                                • +5
                                                                  Омг сравнение хуже некуда.

                                                                  RPi это самый дешевый дев борд на проце вообще, впринципе.
                                                                  На непонятно каком проце, без нормальных доков.
                                                                  Производитель(в данном случае Altera, terrasic делает платы по ее заказу), как правило, закладывает в свои отладки тех поддержку в отличие от RPi.
                                                                  Помимо официальной ТП у их на сайте есть куча how-to.

                                                                  Нужна недорогая борда?
                                                                  marsohod.org/index.php/prodmarsohod

                                                                  Более того, все пишут про эти $25, а реально то за эти деньги кто-нибудь ее купил?
                                                                  • 0
                                                                    В этом месте год назад покупал RasPi B за заявленные 35 у.е. + доставка не помню сколько. ps: цена указанная в магазине с учётом каких-то налогов, которые исчезали при указании страны РФ, и получалось 35.
                                                                    • +2
                                                                      Да вообще как можно сравнивать ПЛИС и процессор/микропроцессор!? У них у каждого своя область применения. Причем часто в реальных изделиях они работают в связке.

                                                                      Раз уж про RPi зашел разговор, то свое мнение про него выскажу. Конечно, у меня он тоже есть, я купил его за 44 доллара — дорого, но я кроме него заказывал много чего еще в одном месте, поэтому с доставкой вышло более-менее.

                                                                      Вообще, по моему мнению, RPi ужасен! Чего только стоят эти все разъемы, торчащие со всех сторон и выступающие на разную величину, даже SD карта, если стандарт брать, жутко выступает. Гнались за размером, а в итоге при подключении всего-то HDMI/power/USB получается краб, который занимает весь стол. А крепления… Это же ужас, в версии «А» их, вроде бы вообще нет, а на «B» два отверстия, расположенные как попало. Я не знаю точно, но предположу, что скорее всего и GPIO тоже многие не вывели из-за размера платы. Да пусть была бы больше по размеру, но все с одной или хотя бы с двух сторон и больше GPIO.

                                                                      RPi просто хорошо распиарен.
                                                                      Про процессор Вы точно сказали, Broadcom вообще славится своей манерой утаивать документацию, даже на маршрутизаторах и ADSL модемах на нем проблемы со сторонними прошивками — ни документации нормальной, ни драйверов.

                                                                      почти оффтоп: Юмор-реклама на тему FPGA EPC3 от Lattice Semiconductor.
                                                                    • –1
                                                                      Я имел ввиду 1200 рублей чисто за микросхему (а не за отладочную плату). Т.е. под нее разрабатываешь печатную плату и припаиваешь. Но больше паять Циклон 3 руками я не хочу — зрение сильно садится и глаза устают по сильнее чем от сидения за компьютером.
                                                                  • +5
                                                                    FPGA дают намного большую свободу программирования, т.к. здесь ты сам решаешь, какие вычислительные устройства у тебя будут и сколько их будет, и ограничен только количеством блоков в твоем FPGA.
                                                                    Нужен регистр — напиши регистр. Нужен сумматор — напиши сумматор. Нужно сто параллельно работающих сумматоров — напиши шаблон и тебе их синтезатор 100 сделает, лишь бы блоков хватило.
                                                                    Вот понадобился человеку для реализации игровой приставки процессор 6502 — и он написал его. Не эмуляцию грубую последовательную, а сам процессор, разные части которого работают параллельно.
                                                                    Или, скажем, придумалась тебе новая железка, которая делает какую-то простую, но важную задачу. От идеи до производства могут пройти годы, а на FPGA ее архитектуру можно начать отлаживать почти сразу.
                                                                    • 0
                                                                      CodeRush — отлично сказали. Прежде чем заводить продукт в серию. Можно протестировать и поэкспериментировать на ПЛИС.
                                                                    • 0
                                                                      Все делается апаратно и параллельно, можно сделать то, чего не реализовано в процессоре.

                                                                      Вы ведь не сравниваете грузовик и экскаватор. В экскаваторе в ковше тоже можно груз возить.
                                                                      • –2
                                                                        Что значит, «сделать то, чего не реализовано в процессоре»? Можно написать любой код, и процессор его выполнит. Есть преимущество в скорости? Так по данной статье это не понятно, т.к. эмуляторы NES уже давно можно даже на мобильниках запускать.
                                                                        • +3
                                                                          На процессоре вы не сделаете видеокарту. А на FPGA сделаете.
                                                                          Вообще, если кому интересно, реализация NES на FPGA уже была. danstrother.com/fpga-nes/
                                                                          А еще HardWareMan сделал флеш-картридж с FPGA для эмуляции почти всех мапперов.
                                                                          • +1
                                                                            Если упрощенно то:
                                                                            процессор выполняет ваши команды,
                                                                            из ПЛИС в просто делаете цифровую микросхему, любую, в том числе и процессор или 10.

                                                                            • 0
                                                                              ну и самый простой из примеров: делать логическое И/ИЛИ с 128 входов с частотой 100МГц
                                                                            • 0
                                                                              Любые цифровые видеофильтры ПЛИС выиграет у микроконтроллёра. Особенно те, что содеражат умножение.
                                                                          • +1
                                                                            FPGA дают преимущества там, где нужна параллельность. Процессор дает преимущества там, где нужна абсолютная гибкость.
                                                                            • +6
                                                                              На FPGA можно сделать процессор и получить абсолютную гибкость в квадрате. ПЛИС кроет любой процессор по универсальности как бык овцу, но стоит значительно дороже.
                                                                              • +3
                                                                                Чтобы полученный на FPGA процессор имел более-менее терпимую производительность( ясно, что это будет именно процессор, а не микроконтроллер, причем не шибко старый процессор) прийдется забыть о Cyclone/Spartan и чесать в сторону Virtex/Stratix, а у них цены не просто значительно, а конкретно значительно выше. Хотя если хочется супергибкости — Zynq/Cyclone V с двумя A9 вёдрами на борту. От альтеровской реализации я вообще кипятком ссу, идеальный вариант получился.
                                                                                • +1
                                                                                  С процессором сложно. Получить частоты выше 400 МГц на ПЛИС очень сложно даже на самых крутых и дорогих. Для Циклона вообще 200 МГц уже предел мечтаний для более менее реального проекта, поэтому я согласен с JerleShannara, Cyclone 5 и Aria очень интересное решение от Altera, когда нужен прцоессор.
                                                                                  • 0
                                                                                    Ну понятно, что это в теории. Естественно железно отлитое решение будет работать быстрей и стоить дешевле.
                                                                            • –4
                                                                              Не хочу обижать, но разве не проще-ли было реализовать симуляцию поверх существенной архитектуре — например поверх ARM или MIPS. Было-бы быстрее и проще. (см. пример с PS1 и PS one)
                                                                              • 0
                                                                                Люблю электронику и NES, и тут такой замечательный пост. Автор, спасибо! Статья — кладезь информации, я её ещё перечитывать буду на выходных. Кинамана посматриваете?
                                                                                • +2
                                                                                  Александр, большое спасибо за замечательную статью! Вы меня прям вдохновили и я тоже заказал себе FPGA от Altera, буду пробовать!
                                                                                  • 0
                                                                                    Спасибо за статью! Проделанная работа очень впечатляет!

                                                                                    Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.