====== Видеоадаптер VGA для проекта БК-FPGA ====== Экран БК-0010 имеет разрешение 512x256 точек. Для отображения на стандартном мониторе возьмем за основу временную диаграмму [[http://www.epanorama.net/documents/pc/vga_timing.html | режима 640x480]] и немного изменим ее. Увеличим разрешение по вертикали до 512 и будем отображать каждую строку дважды. Для облегчения расчетов существует удобный [[http://www.tkk.fi/Misc/Electronics/faq/vga2rgb/calc.html | калькулятор видеорежимов]]. Есть полезная статья [[http://www.xess.com/appnotes/an-101204-vgagen.html | VGA Generator for the XSA Boards]] с примером [[http://www.xess.com/projects/an-101204-vgagen.zip | кода на VHDL]]. ===== Горизонтальная развертка ===== ^ VGA 640x480 ^ БК 512x512 ^ Параметр ^ | 25.175 | 25.00 | Pixel clock frequency, MHz | | NEG | NEG | Horizontal Sync Polarity | | 31.46 kHz | 36.23 kHz | Horizontal Frequency | | 800 / 31.78 | 690 | A (pixels/us) -- Scanline | | 96 / 3.81 | 50 / 2.00 | B (pixels/us) -- Sync pulse length | | 48 / 1.91 | 92 | C (pixels/us) -- Back porch | | 640 / 25.42 | 512 | D (pixels/us) -- Active video | | 16 / 0.64 | 36 | E (pixels/us) -- Front porch |
         ______________________          ________
________|        VIDEO         |________| VIDEO (next line)
    |-C-|----------D-----------|-E-|
__   ______________________________   ___________
  |_|                              |_|
  |B|
  |---------------A----------------|
===== Вертикальная развертка ===== ^ VGA 640x480 ^ БК 512x512 ^ Параметр ^ | 25.175 MHz | 25.00 MHz | Pixel clock frequency | | NEG | NEG | Vertical Sync Polarity | | 59.94 Hz | 59.59 Hz | Vertical Frequency | | 525 / 16.68 | 614 | O (pixels/ms) -- Total frame | | 2 / 0.064 | 4 / 0.11 | P (pixels/ms) -- Sync length | | 31 / 0.99 | 61 | Q (pixels/ms) -- Back porch | | 480 / 15.25 | 512 | R (pixels/ms) -- Active video | | 11 / 0.35 | 31 | S (pixels/ms) -- Front porch |
         ______________________          ________
________|        VIDEO         |________|  VIDEO (next frame)
    |-Q-|----------R-----------|-S-|
__   ______________________________   ___________
  |_|                              |_|
  |P|
  |---------------O----------------|
===== Как это выглядит ===== В качестве тестового изображения выбрана такая картинка: {{512x256.png}} Вот как это выглядит на экране: {{vga-photo.jpg}} ===== Исходные тексты ===== Исходные тексты теста можно скачать здесь: {{vga512x256.zip}}. Всего 176 строчек на Верилоге. // // Videoadapter 512x256 one bit per pixel. // Clock 25 MHz. // Uses 16 kbytes of video memory: 8192 words of 16 bit each // module vga512x256 ( input wire clk, input wire rst, output wire [12:0] maddr, // address to video memory input wire [15:0] mdata, // data from video memory output wire red, output wire green, output wire blue, output wire hsync, output wire vsync); // // Horizontal timing // parameter B = 50; // Sync pulse length parameter C = 92; // Back porch parameter D = 512; // Active video parameter E = 36; // Front porch // // Vertical timing // parameter P = 4; // Sync length parameter Q = 61; // Back porch parameter R = 512; // Active video parameter S = 31; // Front porch // Current pixel's X-Y position. reg [9:0] cnt_x; reg [9:0] cnt_y; // Video data shift register. reg [15:0] word; // Video output bits. assign red = word[0]; assign green = word[0]; assign blue = word[0]; // Address of video memory. assign maddr = { cnt_y[8:1], cnt_x[8:4] }; // Delay hsync by 1 clock. assign hsync = ~(cnt_x > (D + E) && cnt_x <= (D + E + B)); assign vsync = ~(cnt_y >= (R + S) && cnt_y < (R + S + P)); always @(posedge clk) begin // Horizontal dot counter. if (rst || cnt_x == (B + C + D + E - 1)) cnt_x <= 0; else cnt_x <= cnt_x + 1; // Vertical line counter. if (rst) cnt_y <= 0; else if (cnt_x == (B + C + D + E - 1)) begin if (cnt_y == (P + Q + R + S - 1)) cnt_y <= 0; else cnt_y <= cnt_y + 1; end // Video data shift register. // Reading from memory must be delayed by 1 clock. if (cnt_x[3:0] == 1) begin if (cnt_x <= D && cnt_y < R) word <= mdata; else word <= 0; end else word <= { 1'b0, word[15:1] }; end endmodule