Наконец то руки дошли и до VGA.
Глобальная идея такова — выбираете разрешение, которое нужно отрисовать, для себя я выбрал 800х600 72Hz. Далее ищем характеристики выбранного разрешения, хорошо гуглится по фразе «pixel clock vga».
Line: 1040 px
Front porch 56
Sync pulse 120
Back porch 64
Visible area 600
Front porch 37
Sync pulse 6
Back porch 23
Whole frame 666
Почему я выбрал именно такое разрешение? Потому что проверял на своей платке, о которой писал в прошлом посте. Так как там стоит CPLD EPM570 на нем нет PLL, поэтому пришлось исходить из того, что pixel clock (скорость отрисовки пикселя) будет равен тактовой частоте генератора. Если посмотреть на список стандартных разрешений и генераторов, которые можно свободно купить, то 50МГц более всего подходит.
Рисуется линия сама по себе достаточно просто, исходно на ногах h_sync и v_sync логическая единица. Вся линия 1040 пикселей, из них видимая часть 800. Поэтому нужно завести счетчик, который увеличиваем каждый тик генератора. От нуля до 800 рисуем все что нам нужно, просто выставляя на ногах RGB напряжение. В моем случае можно было получить только максимальную яркость одного канала, т.е. смешивая их можно получить максимум 8битное изображение, но если поставить ЦАП и изменяя напряжение от 0 до 0.7В можно менять яркость канала.
Начиная с 800 пикселя нужно выждать front porch, т.е. тупо ничего не делать в течение 56px, а затем в течение 120px нужно прижать к земле ногу h_sync. Затем снова поднять и 64 пикселя потупить. Все линия отрисована. Переходим к следующей и так пока не будет отрисовано 600 строк. Начиная с 600 тупим 37 строк, затем 6 строк v_sync и потом еще 23 тупежа. Все кадр отрисован. Естественно если вы выберете другое разрешение, то все цифры у вас будут другими, но общая суть не поменяется.
Схема подключения простая: сигналы RGB, т.е. 1, 2, 3 пин подключаем через резистор 270 Ом, при логическом уровне 3.3В. Пины 5, 6, 7, 8, 10 на землю 13 — hsync, 14 — vsync, т.е. от CPLD понадобится 5 ножек.
Мне не хотелось заморачиваться, поэтому для теста отрисовываем 200 строк красного, 200 зеленого и 200 синего. Если придумаете, что то лучше, то милости просим)
module vga_tst(clk, v_sync, h_sync, vga_r, vga_g, vga_b);
input clk;
reg [11:0]h_cnt;
output reg h_sync;
reg [10:0]v_cnt;
output reg v_sync;
reg h_en;
reg v_en;
output reg vga_r;
output reg vga_g;
output reg vga_b;
//блок синхронизации
always @ (posedge clk) begin
if ((h_cnt > 855) && (h_cnt < 976))
h_sync <= 0;
else
h_sync <= 1;
if ((v_cnt > 637) && (v_cnt < 643))
v_sync <= 0;
else
v_sync <= 1;
end
//Увеличение счетчиков по горизонтали и вертикали
always @ (posedge clk) begin
if(h_cnt > 1039) begin
h_cnt <= 0;
if(v_cnt > 665)
v_cnt <= 0;
else
v_cnt <= v_cnt + 1'b1;
end
else
h_cnt <= h_cnt + 1'b1;
end
//Разрешаем/запрещаем отрисовку вне видимой зоны
always @ (posedge clk) begin
if(v_cnt < 599)
v_en <= 1'b1;
else
v_en <= 1'b0;
if(h_cnt < 799)
h_en <= 1'b1;
else
h_en <= 1'b0;
end
//отрисовка линий
always @ (posedge clk) begin
if((v_en == 1) && (h_en == 1)) begin
if(v_cnt < 200) // красная
vga_r <= 1;
else
vga_r <= 0;
if(v_cnt > 200 && v_cnt < 400)
vga_g <= 1; // зеленая
else
vga_g <= 0;
if(v_cnt > 400 && v_cnt < 600)
vga_b <= 1; // синяя
else
vga_b <= 0;
else begin
vga_r <= 0;
vga_g <= 0;
vga_b <= 0;
end
end
endmodule



Самая долгожданная статья. Автор, респект тебе!!! теперь пора мне учиться работать с ПЛИС))
Спасибо большое !Побольше бы проектов с ПЛИС!!