FPGA VGA Buffer. Как читать и писать?

8

У меня есть доска Altera DE2 и я пытаюсь рисовать спрайты. У меня возникли проблемы с реализацией экранного буфера.

У меня есть объект отображения, который с частотой 25 МГц выводит пиксели для отображения VGA.

Я надеялся реализовать буфер в SDRAM. Первоначальная идея заключалась в том, чтобы загружать пиксели в следующий пиксель со скоростью 25 МГц из SDRAM. Это работает, но я не могу записать пиксели в SDRAM с такой скоростью и не могу очистить экран достаточно быстро для каждого нового кадра. На запись данных у меня уходит 2 часа, и моя плата работает на частоте 50 МГц, поэтому у меня достаточно времени, чтобы выполнить полное чтение.

Я бы предположил, что я делаю что-то ужасно, ужасно неправильно. Как такой холст для рисования обычно реализуется в VHDL?

Самое близкое, что я могу найти, - это использовать цветовую схему 2-3-3 (RGB) для извлечения каждого пикселя и записи в оперативную память холста в течение времени VGA «крыльца» (гашения). Это означает, что на каждой частоте 25 МГц я могу обновлять только 15% экрана, и мне как-то нужна моя схема, чтобы знать, какие 15% она обновляет?

Я не могу понять, как использовать двойную буферизацию, потому что я не могу понять, как записывать данные в память во время чтения. Есть ли способ избежать битового протокола? Как этот парень делает это?

введите описание изображения здесь

Михаил
источник
@ davidcary, с некоторыми подробностями о том, как подходить к двойной буферизации, вы ответили на вопрос. Я понимаю, что это требует времени, и я не могу бросать камни, потому что он часто дает быстрое замечание в качестве комментария, чтобы помочь пользователю решить его проблему, пока кто-то не сможет написать качественный ответ.
Кортук
3
Когда вы говорите: «Есть ли способ избежать битового взрыва протокола?», Я предполагаю, что это означает, что вы сами не написали контроллер SDRAM. Я рекомендую сделать это, это хорошее упражнение, и вы поймете больше о том, как работает SDRAM и как использовать ее время.
понедельник,

Ответы:

3

Пара подходов, которые могут быть полезны для некоторых стилей отображения, состоит в разделении панели отображения на плитки и

  1. ограничьте использование каждого тайла небольшим набором цветов, что позволяет использовать менее 8 бит на пиксель, или
  2. используйте один или два байта из каждой плитки, чтобы выбрать место, из которого следует читать растровые данные.
Первый подход может уменьшить скорость чтения данных из памяти дисплея. Например, если один из них использует плитки размером 16x16 и может иметь четыре цвета, выбранные из набора 256, то без использования дополнительной ОЗУ в ПЛИС можно уменьшить количество операций чтения памяти на 16 пикселей до восьми (четыре значения цвета, плюс четыре байта для растрового изображения). Если добавить к ПЛИС буферизацию / ОЗУ (*) на 160 байт, можно уменьшить число операций чтения памяти на 16 пикселей до четырех, используя дополнительные 160 операций чтения на каждые 16 строк сканирования для считывания следующего набора цветов листов. Если для каждой плитки требуется 16 цветов, то для второго подхода потребуются дополнительные 640 байт оперативной памяти, если только не будут наложены некоторые ограничения на количество различных палитр, которые могут существовать в строке.

Второй подход, вероятно, скорее увеличит, чем уменьшит общую пропускную способность памяти, необходимую для создания дисплея, но уменьшит объем памяти, который должен быть обновлен для изменения дисплея - можно изменить один или два байта, чтобы обновить 8x8 или 16x16 площадь экрана. В зависимости от того, что вы пытаетесь отобразить, может быть полезно при использовании этого стиля подхода использовать одно устройство памяти для хранения форм листов, а другое - для выбора фрагментов. Например, можно использовать быструю оперативную память 32Kx8 для хранения пары карт тайлов 80x60 с двумя байтами на плитку. Если бы у ПЛИС не было никакой буферизации, она должна была бы читать один байт каждые четыре пикселя; даже при статической оперативной памяти 40 нс процессору будет достаточно времени для обновления дисплея (весь экран будет иметь только 9600 байт).

Между прочим, если кто-то не хочет добавлять ОЗУ 32Kx8, но может добавить 320 байтов буферизации / ОЗУ (**) в ПЛИС, можно использовать подход карты тайлов, но при этом процессор или канал DMA подают 160 байтов в отображать каждые 8 ​​строк сканирования. Это несколько обременяет контроллер, даже если на дисплее ничего не меняется, но может упростить схему.

(*) Буфер может быть реализован как RAM или как последовательность из 32 сдвиговых регистров длиной 40 бит плюс небольшая логика управления.

(**) Буфер может быть реализован как две 160-байтовые ОЗУ или как две группы из шестнадцати 80-битных регистров сдвига.

Supercat
источник
5

Спрайты обычно не делаются с кадровым буфером (как я понимаю слово). Вместо этого вы сравниваете координаты x и y с xmin, ymin и xmax, ymax спрайта. Если текущая позиция сканирования находится внутри спрайта, выведите соответствующий цвет из памяти спрайта.

Если вы пытаетесь отобразить буфер кадров, наберитесь духа. Это был мой первый крупный проект FPGA. SDRAM не должен быть проблемой при 100 МГц (я впервые сделал это около десяти лет назад, а кремний теперь работает быстрее), поэтому увеличьте частоту 50 МГц. Написание собственного контроллера будет познавательным :)

Это дает вам достаточно пропускной способности для игры, тогда вы можете удвоить буфер, без проблем. Для 60 Гц VGA требуется в среднем 18 Мпикс / сек. Если у вас 16-битное устройство, пиковая пропускная способность составляет 200 МБ / с. Даже если вам удастся добиться эффективности только на 50% (что должно быть выполнимо), это 100 Мпикселей / сек @ 16 бит на пиксель или 50 Мпикселей / сек @ 32 бит на пиксель.

Например, может случиться так, что вашей оперативной памяти требуется 60 нс для настройки чтения, но после этого она может записать 8 слов за 80 нс - это 8 байт за ~ 140 нс. Если вы можете заставить свою оперативную память делать более длинные пакеты, это поможет уменьшить стоимость настройки чтения.

Исходя из вашего комментария, это ОЗУ со стороны байтов, это чуть более 50 МБ / с, всего 16 Мп / с при 24 битах на пиксель :( У вас просто недостаточно пропускной способности для отображения в реальном цвете, даже в VGA. можно было бы сделать 8 бит на пиксель довольно легко, но это только 2 или 3 бита на цвет - что может быть хорошо для вашего приложения, я не знаю, или вы могли бы сделать таблицу поиска с 256 цветами, как в старые времена - после читая из кадрового буфера, вы затем используете это значение для поиска во внутренних часах ОЗУ, чтобы получить 24-битные (или 18-битные, которые бы вписались в BRAM) цвета для вывода на монитор.

Двойная буферизация все еще работает:

Отобразите кадр с адреса 0 (просто прочитайте все пиксели по очереди, приостановив чтения во время интервалов гашения).

Запишите ваш следующий кадр в другое место. Для этой двойной буферизации ваш контроллер DRAM должен будет расставить приоритеты между конкурирующими требованиями каналов чтения и записи. Подсказка, расставьте приоритеты по чтению, так как они критичны по времени :)

Мартин Томпсон
источник
Как правило, лучше устанавливать приоритеты чтения или лучше читать данные в FIFO, давать приоритет записи, когда определенный объем данных находится в FIFO, и давать приоритет чтения, когда уровень FIFO становится слишком низким? Я обнаружил, что, по крайней мере, при управлении ЖК-дисплеями, имеющими тактовый сигнал, полезно, чтобы время считывания было «свободным» при условии своевременного смещения всех данных.
суперкат
Спасибо за ваш пост, я мог бы взглянуть на буферизацию. Но я думаю, что у меня уходит 2 часа (1/50 МГц) для чтения данных, и у меня также есть устройство 8-битной ширины.
Михаил
@supercat: да, это более продвинутое решение, которое может понадобиться при увеличении пропускной способности.
Мартин Томпсон
1
@Misha: Настройка чтения данных занимает некоторое время, но вы можете сразу прочитать большое количество данных.
Мартин Томпсон