Tang9k Speccy with HDMI sound
Привет!
Я - не новичок в железе и системном программировании, как и в сборке клонов спектрума в далекие 1987+, но впервые решил пощупать FPGA. Выбор Tang Nano 9k в заметной степени был определен как её возможностями и доступностью, так и наличием этого и подобных проектов. Хочу поделиться своими результатами.
TL;DR: собрал в GoWin IDE 1.9.11 (Linux) и завел звук через HDMI.
https://www.youtube.com/watch?v=T2YLFOwcp4Y
Кому интересны подробности - они ниже.
При попытке прошить готовую прошивку она точно также не завелась, как и у ряда других пользователей, судя по теме. Выводилось только debug OSD со значениями таймингов int и произвольное (больше черное) содержимое экрана спекки. Версию 1.9.8 IDE найти также не смог, зато нашел 1.9.9 и 1.9.11. Пересобирал обеими - не помогло, картинки не было вообще, зато повторилась та же ошибка, что не смогло сгенерировать cpuclk из-за содержимого SDC файла.
После комментирования этой строки в SDC файле и перегенерации GoWin IPs проект собрался и запустился! Не могу сказать, что он работал стабильно (особенно прошивка по F4, при ресетах глючащая местами на экране). Но большинство тестов всего прошли, ESXDOS с SD карты тоже поехал (взял последнюю версию), TAP игрушки грузятся, поют и играют. Это был успех!
USB клавиатуру купил самую простую (дома не оказалось, одни макбуки), подключил даже без резисторов, всё заработало и сразу. Погонял Quazatron - это была самая первая игра, которую я когда-то запустил на только что собранном львовском варианте.
Следующим желанием было вывести звук через HDMI, для чего пришлось поизучать матчасть, провести серию экспериментов и начать осваивать Verilog и VHDL. В целом результат ПОЧТИ достигнут, но именно почти, и тут я рассчитываю на помощь автора проекта, поскольку я сам - полный нуб в FPGA дизайне.
Что я сделал: я заменил реализацию HDMI SimpleVOut на альтернативную, которая умеет генерировать полноценный HDMI сигнал со служебной информацией и звуком. Однако, картинка не появилась. Чтобы высвободить часть ресурсов и улучшить тайминги, в самом этом HDMI проекте был заменен TMDS энкодер на альтернативную версию, реализующую pipeline при выводе, что снизило требования к времянкам. За ненадобностью временно отключил debug OSD overlay и Delta-Sigma DAC, поскольку при наличии HDMI он становится избыточным (хотя в целом-то и не мешает). По ресурсам FPGA в отключении потребности нет - всего хватало. Проблемы вылезли там, где не ожидались.
И вуаля - у меня появилась картинка и пошел звук по HDMI. Почти… В рабочем состоянии обновленного проекта картинка на экране не синхронизировалась с началом кадра, а звук по HDMI был очень тихий. И вроде бы ясно, что надо сделать, но любой шаг вправо-влево в коде приводит к потере сигнала (железка перестает работать).
Дело в том, что альтернативная реализация HDMI не получает hsync/vsync/blank, а сама их внутри генерирует и использует. Наружу она предоставляет готовые счетчики пикселов x/y для привязки отображаемых данных. Текущая реализации Speccy сама вычисляет как синхронизацию, так и ведет счетчики позиций. И нужно было исключить избыточность и как-то связать HDMI и video модуль проекта. Попытка это сделать тем или иным путем (заменить счетчики в модуле video, либо просто сбрасывать их в нули при нулях в HDMI) приводила к потере сигнала. Изначально я полагал, что что-то не понимаю в VHDL или Verilog. Но позже стало ясно, что проблема в таймингах. Отсюда, вероятно, и все известные проблемы: нестабильный старт, невозможность простого внесения изменений в проект… Даже простой сдвиг выхода аудио-миксера влево на несколько разрядов (чтобы нормализовать HDMI звук) ломает всё. А нужно-то всего лишь завести внешние счетчики пикселей внутрь Video модуля, чтобы использовать их там готовые. Наоборот будет сложнее, так как к развертке привязана передача звука и других служебных данных HDMI.
На текущий момент вышло следующее:
- синхронизация картинки сделана через синхронный reset и унификацию размера фрейма, но постоянной привязки нет и в теории картинка может уплыть;
- звук через HDMI выводится тише, чем хочется, но любое изменение топологии также приводит к нерабочей конфигурации. Перепробовал несколько вариантов, но пока больше нет времени играться вслепую.
Как я писал, я не специалист в FPGA. Но посмотрев на временной анализ GoWin IDE, видно, что там множество проблем. То есть, отдельные пути прохождения сигнала не укладываются в требуемые ограничения, в результате оно может работать, а может и нет. Причем, без понимания деталей и/или опыта я не представляю, как можно повлиять на разводку, кроме как явно указать отдельные сигналы как clocks. Система очень чувствительна к содержимому SDC. Например, чтобы у меня завелось всё со звуком, пришлось закомментировать base clk_vga, и казалось бы, это должно ухудшить результат, а вот и наоборот- без него картинка есть, а с ним нет.
В целом мне кажется, что данная FPGA все же медленная для этого проекта, поскольку с таким поведением рассчитывать, что конкретный экземпляр вдруг заработает, не приходится. Либо я просто не знаю, как её готовить, что вполне вероятно с учетом моего нулевого опыта в этой сфере. При этом ресурсов в ней вполне хватает для сборки всего, что было, плюс HDMI звука в альтернативном модуле. Но вот с таймингами просто беда.
Есть вариант попробовать собрать всё это альтернативными тулами (Yosys и NextPNR), но я не уверен, что все нужные IPs он умеет, это надо проверять. Плюс, будет ли оно эффективнее фирменной реализации - тоже вопрос (в случае с TMDS энкодером похоже, что OpenSource версия заметно лучше, чем GoWin IP - во всяком случае, в тестовом примере последнее кушало больше ресурсов платы).
Я пока не публиковал форк проекта. Но если будут желающие с опытом работы с FPGA, чтобы помочь в решении названных проблем, то надо будет сесть, чуток причесать проект и все же выложить.