Формирование VGA изображения с использованием NIOS II


В своей предыдущей статье я рассказывал о подключении индикатора от телевизора к отладочной плате DE0-NANO. Однако получившаяся конструкция достаточна сложна и неудобна в работе — куча проводов, несколько источников питания, в том числе и 12В. Кроме того, из-за экзотичности индикатора, статья получилась не очень полезной. Поэтому далее в своих экспериментах я решил использовать обычный ЖК-монитор. О том, как подключить его к DE0-NANO — эта статья.


Во многих дорогих и сложных отладочных платах для ПЛИС VGA интерфейс уже имеется. В используемой DE0-NANO его нет, так что реализовывать его приходится самому.
VGA — аналоговый интерфейс. Информация о цвете в нем передается по трем линиям (R,G,B) амплитудой сигнала. Кроме того, имеются две линии для передачи сигналов синхронизации. Для формирования цветного сигнала с градациями яркости нужен ЦАП. Можно обойтись и без него, подавая сигнал с выводов ПЛИС прямо на линии цветов, но при этом можно формировать только 8 цветов. Именно такой способ формирования сигнала, как самый простой, я и выбрал.
При этом данные о цвете в памяти будут храниться в 8-битном формате.
Схема подключения монитора к отладочной плате:


Внешний вид конструкции:


Программирование ПЛИС.
В принципе, формировать VGA сигнал можно так же, как это делалось ранее для LCD от телевизора. Различия — только в настройках формирователя видеосигнала Video Sync Generator. Однако, как оказалось, есть более подходящий способ, найденный на испанском сайте: sites.google.com/site/semilleroadt/home/open-pcb
Основное отличие — при программировании Nios там используют специальную библиотеку от Altera, описанную здесь: AN 527: LCD Controller Replacement. В этом же документе описываются компоненты SOPC, требуемые для формирования изображения. Из-за большого объема библиотеки, не удается разместить всю программу для Nios в On-chip ram. Поэтому как код программы Nios, так и переменные программы и видеобуфер приходится располагать в SDRAM, что несколько замедляет выполнение программы.
Использование библиотеки упрощает написание программы для Nios, причем изображение формируется намного стабильней, чем в случае прямого управления периферией, как это было сделано у меня ранее с LCD от телевизора.
Испанский проект показался несколько избыточным, так что я его несколько изменил.

Отмечу, что используется разрешение изображения 640x480, с частотой 60 Гц.
Не буду приводить все настройки компонентов SOPC, укажу лишь используемые компоненты:
  • timer1 — Interval Timer. Можно использовать для измерения производительности, но в данном проекте таймер не используется;
  • cpu — теперь это более производительный Nios II/f;
  • sdram — хранит все данные процессора и два видеобуфера;
  • pll — формирует 4 тактовые частоты. Две частоты 100 МГц для большей части системы, включая cpu и sdram, 80 МГц для порта GPIO, 25 МГц — для видеосистемы;
  • jtag_uart — предназначен для передачи данных из Nios в IDE;
  • lcd_sgdma — Scatter-Gather DMA Controller. DMA c расширенным функционалом;
  • lcd_ta_sgdma_to_fifo — Avalon-ST Timing Adapter. Позволяет управлять латентностью сигнала;
  • lcd_pixel_fifo — буфер FIFO с двумя входами тактовой частоты. Так как частота процессора и видеосистемы различается, то для передачи данных в видеосистему нужен FIFO;
  • lcd_ta_fifo_to_dfa- — еще один Avalon-ST Timing Adapter;
  • lcd_64_to_8_bits_dfa — Avalon-ST Data Format Adapter. Так как FIFO выдает данные в 64-битном виде, а формирователь видеосигнала принимает их в 8-битном, используется этот преобразователь форматов;
  • video_sync_generator_0 — формирователь видеосигнала. Он формирует сигналы горизонтальной и вертикальной синхронизации, и управляет идущим на него потоком данных, приостанавливая его во время передачи синхроимпульсов;
  • led_pio — GPIO, 8-битный порт, настроенный на вывод, для управления светодиодами;
  • sysid — System ID Peripheral. Используется для контроля при записи программы Nios.
Вид SOPC системы:


В Quartus система выглядит еще проще, чем в предыдущей статье — так как нет второго PLL:


Программирование Nios
Как я уже упоминал выше, для управление графической системой используется специальная библиотека, написанная в Altera.
Все функции, связанные с управлением SGDMA, находятся в файле «alt_video_display».
Наиболее важная — инициализация, вот пример ее использования:
alt_video_display_init( LCD_SGDMA_NAME,//название SGDMA, располагается в "system.h"
                              640,//разрешение по горизонтали
                              480,//разрешение по вертикали
                              8, //глубина цвета, бит на пиксель
                              ALT_VIDEO_DISPLAY_USE_HEAP, //указатель на положение видеобуферов
                              ALT_VIDEO_DISPLAY_USE_HEAP, //указатель на положение дескрипторов sgdma
                              2 );//число видеобуферов

Так как в данном примере вместо указателей стоят константы «ALT_VIDEO_DISPLAY_USE_HEAP», то библиотека разместит и видеобуферы, и дескрипторы в heap-памяти.
Так как число видеобуферов — 2, то будет использоваться двойная буферизация — в то время, пока на экран выводится один буфер, другой можно изменять.
После инициализации система готова к работе — данные из буферов автоматически выводятся на экран.
Формирование изображения должно осуществляться таким образом:

alt_video_display * display;//структура, содержащая указатель на буфер, в который в данный момент можно записывать данные
.....
vid_draw_line(0, 0, 200, 200, 2, 2, display);//рисуем линию
.....
alt_video_display_register_written_buffer(display);//указывает, что буфер с записанными до этого данными можно начинать отображать
while ( alt_video_display_buffer_is_available( display ) != 0 ){ }//ожидаем, пока отображаемый буфер не освободится

//можно вновь записывать данные в display (там будет находится указатель уже на другой буфер)


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

Для вывода графических примитивов используется библиотека «simple_graphics.c ». Она показалась мне избыточной, кроме того, в ней не предусматривалась 8-битная глубина цвета изображения. Пришлось несколько модифицировать библиотеку, так что задачу свою она выполняет, хотя в некоторых местах могут оставаться проблемы с цветом.

Видео работы программы:

Сначала отображаются кружки, как и в прошлый раз, а потом — синусоида.
Так как видеобуферов два, то каждый кружок приходится отрисовывать дважды — в каждом буфере.
Синусоида отрисовывается каждый раз заново, перед каждой отрисовкой буфер очищается. Расчет значений синусоиды — на ходу.

Проект: www.dropbox.com/s/2xrh56rlf0x20jz/FPGA_VGA.zip?dl=0
  • +7
  • 03 июня 2014, 21:51
  • citizen

Комментарии (12)

RSS свернуть / развернуть
Хорошая статья, сохранил для своих студентов в закладки.
У нас на кафедре этой тематике целый курс по NIOS II посвящен.
А вот пример самих работ, которые делают ребята: www.youtube.com/watch?v=GsGsEOk6CPM
0
Спасибо.
Раньше уже встречал этот курс. Довольно хороший, хотя есть замечание — скриншоты не увеличиваются, так что некоторые сложно разглядеть.
На отладочных платах DE2-115 вообще много какой периферии стоит, так что есть широкий простор для экспериментов.
К слову — я хоть и студент, но специальность моего факультета — оптика.
0
Ну сайт поддерживается на энтузиазме)

Под DE2-115 я видел несколько проектов на сайте Корнелловского университета: people.ece.cornell.edu/land/courses/ece5760/FinalProjects/
Правда все на английском.
0
Веселые вещи в Вашем вузе делают=)) В моем было все уныло, хардкорный 51й, PIC16 и чучуть атмеги… Сейчас от TI комплекты получили (меня очень радует доступ к ним) и то… особо никто не крутит их… банальное — помигать светодиодом и все(((
0
Да народ в основном пассивный. Что в программе есть и не больше. У нас лежат постоянно без дела платы De1 — да не цитрус, но вполне годные для того, чтобы тестить и заниматься ими, и даже на дом можно взять. Так и лежат.
0
Для формирования цветного сигнала с градациями яркости нужен АЦП.
ЦАП, наверное.
Можно ведь и так:
0
Лучше R-2R. В принципе, проекты с такими ЦАПами попадаются.
0
У меня на отладочной платке с Cyclone II такая схема.
0
это довольно простой и достаточно точный способ преобразования цифры в аналог, но обладает некоторыми ограничениями:
а) амплитуда от лог «0» до лог «1»
б) работает хорошо только при подключении к системам с высоким входным сопротивлением и низкой емкостью
в) частота и форма сигнала не имеет триггера, то есть во избежание проявления каких либо гармоник нужно обеспечить одномоментность изменения сигнала логических уровней на всей шине (для ПЛИС это не проблема, проблема может быть для МК на высоких частотах, если в шине ноги с разных портов, соответственно имеются задержки между включениями разных битов шины)
г) резисторы должны быть точными, для соответствия уровней аналогового сигнала.
д) другие ограничения о которых я не знаю или помню…
вообще годный способ, особенно на скорую руку, использовал в генераторе заданных помех, на частотах до 20кГц отлично работал в связке с TDA2030
0
Спасибо, исправил текст.
В сети много проектов с резисторными ЦАП для формирования VGA сигнала. Я в данном случае захотел сделать конструкцию максимально простой.
0
Спасибо за статью, очень полезо. Я даже перед новым годом на али переходничок заказал что бы сделать вывод на экран. Но он гад 2 месяца ехал, а как приехал все времени нет занятся :-(
0
VGA не торт. Надо делать HDMI. deo nano это позволяет.
0
Только зарегистрированные и авторизованные пользователи могут оставлять комментарии.