Jump to content

    

Recommended Posts

Здравствуйте. Я новичок в этой теме. При интеграции VGA интерфейса в MIPSfpga, возникла проблема.

VGA я реализовал следующим образом:

 

module mipsfpga_ahb_vga (

input wire pixel_clock, //тактирующий сигнал

input wire [11:0] rgb_ahb, // цвет который нужно вывести на экран

 

output reg hsync, // синхроимпульсы

output reg vsync, // синхроимпульсы

output reg [11:0] rgb, //цвет который выводится на экран

//output reg [11:0] char_count,

output reg visible, //флаг указывающий находится ли

 

output reg [11:0] line_count_out, // номер строки которая выводится

output reg [11:0] pixel_count_out, // номер пикселя в строке который выводится

);

 

Считываются данные с vga-модуля с помощью шины AHB, считываются pixel_count_out, line_count_out, visible. Исходя из этих данных на шину уже записывается цвет который нужно записать по нужным координатам. Программу я написал на языке С. Где просто считывал по шине где сейчас происходит отрисовка, и записывал нужный цвет. Частота для vga-блока 25MHz, частота ядра MIPS 50MHz. Плата на которой было реализовано это DE0-CV.

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

C360_2016_05_02_17_42_37_org.jpg

Код программы.

if(MFP_PIXEL_COUNT>200 && MFP_PIXEL_COUNT<250){

if(MFP_LINE_COUNT>200 && MFP_LINE_COUNT<250)

MFP_VGA_RGB = 0x00F;

else

MFP_VGA_RGB = 0x0F0;

}

MFP_PIXEL_COUNT - координаты рисуемого пикселя в строке и MFP_LINE_COUNT - координаты рисуемой строки. Мне кажется это из за того что есть очень большая временная разница между координатами которые нужно записать и получением цвета который мы и запишем в блок.

Как реализовать этот блок что бы избежать этого?

Share this post


Link to post
Share on other sites
Делаете-ли какую-то двойную буферизацию?

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

Share this post


Link to post
Share on other sites
Как выполнить буферизацию в таком проекте? Я вижу только один способ ядро накидывает в модуль vga нужные для отображения данные когда массив для его хранения заполняется vga модуль начинает считывание их и отображение?

 

Перечитал Ваше первое сообщение более внимательно, и понял, что вопрос с двойной буферизацией был лишним - я его задал на автомате.

 

Про тайминги вы всё-таки ответьте, потому что лучше было бы, если бы они укладывались ;)

 

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

 

Ммм, а почему бы не узнать какая задержка между координатами и получением цвета?

Например, просимулировать в ModelSim'e? MIPSfpga можно симулировать или там зашифрованный код?

Если нельзя, то почему бы не глянуть эту задержку в SignalTap'e?

 

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

 

Как реализовать этот блок что бы избежать этого?

Как я понял, у вас плата DE0-CV, и судя по даташиту у нее четырехбитных VGA.

640 * 480 * ( 3 (RGB) * 4 (bits) ) = 3686400, что многовато, а, следовательно, если мы хотим такое изображение выводить, то нам нужно использовать внешнюю память.

 

На этой плате стоит внешняя 64MB SDRAM, чего должно нам хватить с лихвой.

 

Я бы сделал так:

1. Использую какую-то готовую корку от Альтеры (уверен, что в примерах к этой плате она идет, названия сейчас не скажу), которая позволяет писать/читать через интерфейс Avalon-MM в эту память.

2. Подключаю эту память к MIPSfpga, делаю какие-то функции/макросы которые позволяют писать/читать в эту память (т.е. просто чтение по какому-то оффсету).

3. Беру готовые альтеровские IP-ядра Frame Reader и Clocked Output из Altera VIP. Подключаю в систему.

4. Смотрю драйвер для Altera Frame Reader, портирую оттуда функции altvipfb_start_hw и altvipfb_disable_hw.

5. Настраиваю через Avalon-MM (csr) Altera Frame Reader, чтобы он начал читать например с нулевого адреса внешней памяти.

6. Через Avalon-MM с помощью функций, разработанных в п.2 пишу нужные мне цвета в нужных пикселях (адресах). Они отобразятся на экране.

 

В таком подходе вы используете готовые компоненты, однако по ресурсам (FPGA) это будет дорогое удовольствие :)

 

Двойной буферизации в таком варианте нет, и если у вас будет картинка быстро динамически менятся, то эти эффекты возможно будут видны. Я примерно всё это проделывал, когда поднимал VGA на плате с Cyclone V SoC в linux'e (т.е. делал линуксовый фреймбуфер), и там этих эффектов не заметил, хотя выводил и GUI (window manager).

 

UPD:

Схему приложил в аттаче.

Стрелки идут от мастера к слейву.

post-73371-1462612172_thumb.png

Edited by johan

Share this post


Link to post
Share on other sites
Ммм, а почему бы не узнать какая задержка между координатами и получением цвета?

Например, просимулировать в ModelSim'e? MIPSfpga можно симулировать или там зашифрованный код?

Если нельзя, то почему бы не глянуть эту задержку в SignalTap'e?

 

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

post-87592-1462970181_thumb.jpg

Share this post


Link to post
Share on other sites
Спасибо за ответ, видимо предстоит много работы.

 

Ну, некоторую работу можно сократить.

Можно, например, начать с того, чтобы не делать полноценный VGA, а сделать чернобелый терминальный режим 80x25 (или 80x30).

 

Это позволит вам выводить текст с использованием 80 * 25 * 8 (бит на символ) = 16000 бит, что легко умещается в блоки памяти в самой FPGA.

 

Тогда получается вот такая схема:

mips_vga_term.jpg

 

Т.е:

1. VGA контроллер отдает vsync/hsync и номер пикселя (x/y в 640x480), который сейчас надо выводить.

2. По номеру пикселя понимаем какой ряд и строчку надо выводить (char_x/char_y в 80x30), и сдвиг в этом символе.

3. Отправляем их на charbuffer, который нам выдает то, какой именно символ надо выводить.

4. Отправляем номер символа на font RAM, которая хранит все возможные символы (типа, алфавит).

5. По сдвигу в символе (см. п.2) и той информации, что хранится в font RAM понимаем, нам надо выводить пустоту или закрашивать пиксель (если у нас чернобелый режим).

6. Выводит это на экран. Параллельно с этим всем конвеером сигналы vsync/hsync задерживаются на нужное количество тактов, для того что бы это всё было выровнено. Хотя скорее всего правильнее тащить эти сигналы (vsync/hsync) через конвеер, для того, чтобы точно не было расхождения, если вы добавите где-то задержку в конвеере, но не учтете это в другом месте.

 

Подобную схему я делал когда делал тетрис (исходный код) для вывода строчек "Score, Lines, Level, New Game".

 

Процессор занимается только тем, что пишет в charbuffer те символы, которые он хочет чтобы были на экране через Avalon-MM или AXI.

Тем самым вы сможете писать "hello world from MIPSfpga" на экране :)

 

P.S. Скорее всего в интернете где-то есть готовые С-библиотеки, которые производят всю нудную работу по переносу строк, сдвигам для такого терминала и пр.

Edited by johan

Share this post


Link to post
Share on other sites
Можно, например, начать с того, чтобы не делать полноценный VGA, а сделать чернобелый терминальный режим 80x25 (или 80x30).

 

Большое спасибо за идею. Для начала попробую реализовать это.

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Sign in to follow this