Вот так бывает, что возвращаешься к одному из "старых" проектов и вдруг выясняешь для себя, что не все в нем хорошо, кое что не работает правильно, и, что его можно и нужно улучшать. Так и случилось с моим проектом "теннис". Я его сделал довольно давно, пробовал его на парочке мониторов и он работал. Теперь появилась задумка сделать еще одну видео игру на плате Марсоход, я взял за основу тот проект "теннис", и.. встретился с некоторыми проблемами. Я решил сначала разобраться и сделать улучшенный вариант той же старой игры. Получилось вот что:
Что было сделано:
- исправлен генератор синхросигналов, в нем была ошибка;
- изменены некоторые назначения в проекте;
- игра сделана цветной;
- размеры мячика и ракетки сделаны побольше (16x16);
- логика игры синхронизирована с частотой вертикальной развертки.
Далее подробнее.
Итак.
Генератор синхросигналов.
Обнаружил, что не все мониторы отображают мою видео игру, иногда синхронизация срывается. Я думал все дело в нестабильном внутреннем генераторе микросхемы ПЛИС. Начал разбираться и оказалось, что в модуле hvsync.v есть ошибка - синхроимпульс кадровой VSYNC не совпадает по фронту c синхроимпульсом HSYNC. А ведь они должны совпадать - об этом сказано в спецификации VESA. Я переписал модуль hvsync.v и еще сделал к нему тестбенч для iverilog и gtkwave, что бы можно было внимательнее посмотреть, что же происходит на самом деле. Вот здесь смотрите, что получилось (кликните изображение, чтобы увеличить его):
На временной диаграмме видно, что HSYNC и VSYNC теперь синхронны. По сигналу visible понятно какие строки отображаются а какие нет. Четко видно, что я следую спецификации VESA для режима 800х600: идет 1 строка FrontPorch, 4 строки VSYNC, 23 строки BackPorch. Отображаемых строк 600 (последняя отображаемая под номером 599) всего строк 628 (последняя под номером 627).
Новые назначения в проекте.
Несмотря на новый синхрогенератор некоторые мониторы упорно отказывались показывать игру правильно и синхронизация все равно сбивалась. Решили, что, видимо, уровень сигналов слишком большой. Что бы как-то ограничить их мы пытались поставить последовательно с сигналами VSYNC и HSYNC резисторы ~200 Ом и похоже это помогает. У нас есть в запасе еще один более простой способ. HSYNC и VSYNC в предыдущем проекте теннис были выведены через группы выводных контактов F0[9..0] и F1[9..0] которые
традиционно мы в своих проектах используем для управления двигателями. Группирование контактов дает больший ток для моторов, но в этом проекте "теннис" нам это не надо. Поэтому из группы были оставлены только по одному выводу и им назначен "минимальный ток".
Оставшиеся выводы групп не используются, и поэтому для этого проекта они - высокоомные входы. Используем меню среды Quartus II, Assignments/Assignment Editor.
Игра в цвете.
Теперь цвет фона - синий, мяч - красный, а бордюр и ракетка - зеленые.
В новом проекте сигналы RGB выведены на разъем с названиями контактов F3, F4, F5 (второй блок контактов для "моторов"). Теперь нужно будет спаять новый шнурок для подключения к монитору в котором R, G и B идут отдельными проводами.
Цоколевка разъема VGA была описана в первом проекте. Впрочем, и со старым проводком, должно все работать в "черно-белом режиме", так как проект по идее сделан совместимым со старым шнурком (завтра это проверю).
Синхронизация логики игры по частоте вертикальной развертки.
Эта идея довольно хороша - внутреннее состояние игры меняется только в момент кадрового импульса. Значит на экране не будет дополнительных артифактов при движении мяча или ракетки. Кроме этого, использование довольно низкой частоты VSYNC сильно помогает экономить место внутри микросхемы. Ведь теперь мне не нужно ставить еще один счетчик для получения низкой частоты (используется для движения мяча или ракетки) из 5Мгц.
Ну вот собственно и проект для скачивания:
Проект сделан для платы Марсоход третьей версии - там есть кварцевый генератор 100Мгц. Эта частота в проекте делится на 20 и получаются стабильные 5Мгц. Если у вас плата без генератора, то все же попробуйте внутренний генератор из компонента ALTUFM_NONE - он уже стоит в проекте. Его вывод int5Mhz используйте как частоту всего проекта.
Надеюсь с новым улучшенным проектом проблем будет меньше.
Подробнее...