/* minivga1.v: by karttu, 24. 4. 2005. Impelent a minimal VGA-controller for Spartan-3 FPGA Starter Board. Richard Herveille's module vga_tgen.v has been used as a model for this module. Also his vga_vtim.v (renamed here vgatimer.v) is employed almost verbatim here. For the original sources of those two modules, see: http://www.opencores.org/projects.cgi/web/vga_lcd/overview */ //synopsys translate_off `include "timescale.v" //synopsys translate_on module minivga1(CLK,RST,VGA_R,VGA_G,VGA_B,VGA_HSYNC,VGA_VSYNC); input CLK; input RST; output VGA_R; output VGA_G; output VGA_B; output VGA_HSYNC; // horizontal sync pulse output VGA_VSYNC; // vertical sync pulse // horizontal timing parameters parameter V_THSYNC = 96-1; // horizontal sync pulse width (in pixels) parameter V_THGDEL = 48-1; // horizontal gate delay (in pixels) parameter V_THGATE = 640-1; // hor. gate (number of visible pixels per line) parameter V_THLEN = 800-1; // hor. length (tot. number of pixels per line) // vertical timing parameters parameter V_TVSYNC = 2-1; // vertical sync pulse width (in lines) parameter V_TVGDEL = 29-1; // vertical gate delay (in lines) parameter V_TVGATE = 480-1; // vertical gate (# of visible lines per frame) parameter V_TVLEN = 521-1; // vertical length (number of lines per frame) reg [ 7:0] Thsync = V_THSYNC; reg [ 7:0] Thgdel = V_THGDEL; reg [15:0] Thgate = V_THGATE; reg [15:0] Thlen = V_THLEN; reg [ 7:0] Tvsync = V_TVSYNC; reg [ 7:0] Tvgdel = V_TVGDEL; reg [15:0] Tvgate = V_TVGATE; reg [15:0] Tvlen = V_TVLEN; reg pix_clk = 0; reg [9:0] vga_x = 0; // Allow range 0-1023. (in practice 0-639) reg [9:0] vga_y = 0; // Allow range 0-1023. (in practice 0-479) wire [9:0] vga_x_next = vga_x + 1; wire [9:0] vga_y_next = vga_y + 1; wire eof; wire Hgate, Vgate; wire Hdone; // These three functions generate a nice 20x15 quilt test pattern. // The top-left corner should be white (111) function foo_R; input [9:0] x; input [9:0] y; begin foo_R = ~x[5]; end endfunction function foo_G; input [9:0] x; input [9:0] y; begin foo_G = ~y[5]; end endfunction function foo_B; input [9:0] x; input [9:0] y; begin foo_B = (x[6] == y[6]); end endfunction assign VGA_R = foo_R(vga_x,vga_y); assign VGA_G = foo_G(vga_x,vga_y); assign VGA_B = foo_B(vga_x,vga_y); // hookup horizontal timing generator vgatimer hor_gen( .clk(CLK), .ena(pix_clk), .rst(RST), .Tsync(Thsync), .Tgdel(Thgdel), .Tgate(Thgate), .Tlen(Thlen), .Sync(VGA_HSYNC), .Gate(Hgate), .Done(Hdone) ); // hookup vertical timing generator wire vclk_ena = Hdone & pix_clk; vgatimer ver_gen( .clk(CLK), .ena(vclk_ena), .rst(RST), .Tsync(Tvsync), .Tgdel(Tvgdel), .Tgate(Tvgate), .Tlen(Tvlen), .Sync(VGA_VSYNC), .Gate(Vgate), .Done(eof) ); always @(posedge CLK) begin pix_clk = ~pix_clk; // Toggle the pixel clock. if(pix_clk) begin if(VGA_HSYNC) vga_x <= 0; if(Hgate) vga_x <= vga_x_next; if(VGA_VSYNC) vga_y <= 0; if(Hdone & Vgate) vga_y <= vga_y_next; end end endmodule