/* VGA Demo 800x600 at 72Hz http://www-mtl.mit.edu/Courses/6.111/labkit/vga.shtml 800x600, 72Hz 50.000 800 56 120 64 600 37 6 23 Pixel Clock (MHz): 50.000 Horizontal (in Pixels) Active Video: 800 (16us) Front Porch: 56 (1.12us) Sync Pulse: 120 (2.4us) Back Porch: 64 (1.28us) Total pixel clock ticks: 1040 (20.8us) Vertical (in Lines, so x20.8us) Active Video: 600 (12480us) Front Porch: 37 (769.6us) Sync Pulse: 6 (124.8us) Back Porch: 23 (478.4us) Total pixel clock ticks: 666 (13.32us) Total pixel clock ticks: 692,640 50,000,000 / 692,640 = 72.187572188 = 72Hz 1 pixel clock = 1/50Mhz = 20ns = 0.02us */
module vga_demo ( CLOCK_50, RESET, VGA_RED, VGA_GREEN, VGA_BLUE, VGA_HS, VGA_VS ); input CLOCK_50; input RESET; output VGA_RED; output VGA_GREEN; output VGA_BLUE; output VGA_HS; output VGA_VS;
/* Internal registers for horizontal signal timing */ reg [10:0] hor_reg; // to count 1040 different values up to 1039 reg hor_sync; wire hor_max = (hor_reg == 1039); // to tell when a line is full
/* Internal registers for vertical signal timing */ reg [9:0] ver_reg; // to count 666 different values up to 665 reg ver_sync; reg red, green, blue; wire ver_max = (ver_reg == 665); // to tell when a line is full
// Code
/* Running through line */ always @ (posedge CLOCK_50 or posedge RESET) begin
if (RESET) begin hor_reg <= 0; ver_reg <= 0; end else if (hor_max) begin hor_reg <= 0;
/* Running through frame */ if (ver_max) ver_reg <= 0; else ver_reg <= ver_reg + 1;
end else hor_reg <= hor_reg + 1;
end always @ (posedge CLOCK_50 or posedge RESET) begin if (RESET) begin hor_sync <= 0; ver_sync <= 0; end else begin
/* Generating the horizontal sync signal */ if (hor_reg == 856) // video (800) + front porch (56) hor_sync <= 1; // turn on horizontal sync pulse else if (hor_reg == 976) // video (800) + front porch (56) + Sync Pulse (120) hor_sync <= 0; // turn off horizontal sync pulse
/* Generating the vertical sync signal */ if (ver_reg == 637) // LINES: video (600) + front porch (37) ver_sync <= 1; // turn on vertical sync pulse else if (ver_reg == 643) // LINES: video (600) + front porch (37) + Sync Pulse (6) ver_sync <= 0; // turn off vertical sync pulse
// Draw a single square. if (hor_reg >= 100 && hor_reg <= 200 && ver_reg >= 100 && ver_reg <= 200) begin red <= 1; green <= 0; blue <= 0; end else begin red <= 1; green <= 1; blue <= 1; end end end
// Send the sync signals to the output, inverted as the sync pulse is low. // Maybe wrong as this doc says pulse id positive http://tinyvga.com/vga-timing/800x600@72Hz assign VGA_HS = ~hor_sync; assign VGA_VS = ~ver_sync; // Send a pattern of colours (based on the registry bits) but do not output anything during the synchronization periods //assign VGA_RED = (!hor_reg[0] && !ver_reg[0] && ver_reg < 600 && hor_reg < 800); //assign VGA_GREEN = (!hor_reg[1] && !ver_reg[1] && ver_reg < 600 && hor_reg < 800); //assign VGA_BLUE = (!hor_reg[2] && !ver_reg[2] && ver_reg < 600 && hor_reg < 800); assign VGA_RED = red && ver_reg < 600 && hor_reg < 800; assign VGA_GREEN = green && ver_reg < 600 && hor_reg < 800; assign VGA_BLUE = blue && ver_reg < 600 && hor_reg < 800; // http://gerfficient.com/2013/02/11/fpga-to-vga-using-de0-nano/ endmodule |