VGA signalo generavimas

Internete yra gana daug viskiausių VGA signalo generatorių schemų FPGA čipams. Vienos geriau, kitos mažiau suprantamos. Tačiau radau vieną aiškinimą kuris man pasirodė labiausiai suprantamas ir lengvai realizuojamas.

Pradžiai reikia pažiūrėti į paveikslėlį:

FPGA VGA VESA timing

Tai visas video signalo vaizdas- balta zona tai tas ką męs matom ant ekrano, kitos dalys- nematomos, bet labai svarbios.
VESA numato visą eilę standartinių video siganalų ir raiškų variantų. Mane domina tik patys populiariausi- naudojami LCD ekranuose (native resolution) ir paprastieji VGA režimai kurie buvo naudojami su CRT monitoriais.
Dažnas žino ekranų raiškas (800×600, 1024×768), dar gal kadrų dažnį (60, 70, 75 … 100Hz), tačiau žymiai mažiau žinomi kiti labai svarbūs parametrai- pixel clock ir eilučių dažnis.
Yra dar sinchronizacijos signalai, jų ilgis, dažnis, vieta ir poliariškumas taip pat standartizuoti.
Darant VGA signalą geriausiai skaičiuoti x ir y koordinates ne iki standartinio ekrano dydžio, bet iki viso signalo galo. T.y. VGA režime x reikia skaičiuoti ne iki 640 taškelio, bet iki 800. Tada labai lengva realizuoti teisingus sinchro signalus- po vaizdo palaukiam 16 pixelių (A), padarom sinchro signalą ir palaikom 96 pixelius (B), pašalinam sinchrosignalą ir dar 48 pixelius laukiam iki naujos eilutės pradžios (C). Panašiai ir su y koordinate.

Dabar biški VESA standartinių duomenų:

Mode Pixel clock, MHz VS, Hz HS, kHz Sinchro poliariškumas x y A B C D E F
VGA 60 25.17 60.04 31.46 – – 640 480 16 96 48 11 2 31
VGA 75 31.5 75 39.38 – – 640 480 16 96 48 11 2 32
VESA 1024×768 65 60 48.36 – – 1024 768 24 136 160 3 6 29
VESA 1280×1024 108 60 64 + + 1280 1024 48 112 248 1 3 38

Jei domina kitos rezoliucijos, va online skaičiuotuvas: http://www.tkk.fi/Misc/Electronics/faq/vga2rgb/calc.html

Šiaip dažniai gali vos vos skirtis- monitorius sugeba prisiderinti prie nedidelių nukrypimų, bet geriau daryti tiksliai. Darant schemutes su FPGA ir naudojant VGA režimą, galima pernelyg nepaisyti elementų vėlinimo, tačiau darant projektą skirta normaliam LCD monitoriui taimingas labai svarbu- 100MHz pixel clock tai jau ne juokas. Čia galioja ne tik vėlinimas išorinėje atmintyje, bet ir vėlinimas pačioje FPGA mikroschemoje.
Vienas iš geriausiu prietaisų pasitikrinti vėlinimus yra LCD monitorius dirbantis “native resolution”- 17″ monitorius tai “tikslus oscilografas” su 10ns “raiška”.

Pavyzdinis Verilog failas VESA 1027×768 vaizdelio generavimui (rodo kelius brūkšnelius):


// VESA 1027x768 @ 60Hz, Pixel clock=65MHz
module VGA(input clk,
output reg [3:0] out_R,
output reg [3:0] out_G,
output reg [3:0] out_B,
output VS,
output HS,
input reset
);

reg [15:0] x;
reg [15:0] y;

// SYNCS & VISIBILITY
assign HS=(x>1047) && (x<1183); //0..1023+24 ir 1023+24+136
assign VS=(y>770) && (y<776); //0..767+3 ir +6
assign visible_zone=(x<1024 && y<768);

//visible_zone;
always @(posedge clk)
begin
out_R < = (visible_zone && (x==0 || x==512 || x==1023)) ? 15: (visible_zone && (y==0 || y==767)) ? 15: 0; out_G <= (visible_zone && (x==0 || x==512 || x==1023)) ? 15: (visible_zone && y==384) ? 15: 0; out_B <= (visible_zone && (x==0 || x==512 || x==1023)) ? 15: 0; end // Skaiciuoklis. VESA 1024x768 (1024+24+136+160=1344, 768+3+6+29=806) always @(posedge clk) begin if (x<1344 && ~reset) x<=x+1; else begin x<=0; if (y<806 && ~reset) y<=y+1; else y<=0; end end endmodule

Tai du Quartus archyvai skirti DE1 plokštei, tačiau lengvai perdaromi bet kokiai kitai plokštei ar mikroschemai. Vienas variantas skirtas VESA 1024×768, o kitas variantas- VESA 1280×1024. Iš esmės, tai tas pats Verilog failas su papildoma PLL kuri generuoja reikiamą taktinį dažnį ir išėjimo jungtys. Atkreipkit dėmesį į tai, kad antrajam variante aš užmiršau invertuoti sinchro signalus, tačiau mano turimas priekabus LCD monitorius viską teisingai rodo.

7 replies on “VGA signalo generavimas”

  1. Hmmm, susimasciau dabar. O jei pas mane vien tik plika TFT matrica 800×600 rezoliucija. Po 6 RGB bitus. Tokiu atveju tasku vistiek daugiau yra? Keistai seip, paprastai uzdegt tai tu papildomu tasku neskaiciavau 🙂

  2. Taigi tu jungei matrica tiesiogiai, o čia rašau apie standartinius taimingus ir išorinius monitorius. Jungiant tiesiogai matricą, užtenka išlaikyti signalų seką ir minimalius taimingus.
    O dėl 3*6bitus tai nelabai ir supratau. Jei reikia daugiau spalvų- tai prašom, pasikeiti ir tiek. Paprasčiausiai DE1 plokštė turi primityvu video DACą su 4 bitais (viso 4096 spalvos).
    Čia jei apie “output reg [3:0] out_R,” kalbi.

  3. mano atveju turetu but output reg [5:0] out_R 🙂 Anyway, man Verilog tokia grazi ir tvarkinga kalba, kad visdar metausi tarp vhdl ir verilog 🙂

  4. Va, bandymas paleisti LCD native rezoliucijoje. 1280×1024, pixel clock ar tai 108 ar tai 106MHz…

    Source code kada nors paviešinsiu, jei kam bus įdomu.

Leave a Reply

Your email address will not be published. Required fields are marked *