`timescale 1ns / 1ps //============================================================ // Tony Hyun Kim // XVGA (1024x768@60Hz) driver, works with a 65MHz `clk' // Design is taken from 6.111 VGA circuit //------------------------------------------------------------ // Example usage: /* wire pclk, pclk_unbuf; DCM pixel_clock_dcm (.CLKIN(CLK1), // 25MHz .CLKFX(pclk_unbuf)); // synthesis attribute CLKFX_MULTIPLY of pixel_clock_dcm is 13 // synthesis attribute CLKFX_DIVIDE of pixel_clock_dcm is 5 // synthesis attribute CLK_FEEDBACK of pixel_clock_dcm is NONE BUFG pixel_clock_buf (.I(pclk_unbuf), .O(pclk)); wire [10:0] pixel_count; wire [9:0] line_count; wire blank; wire hs, vs; xvga xvga_driver(pclk, btn[3], pixel_count, line_count, hs, vs, blank); always @ (posedge pclk) begin vgaRed <= blank ? (line_count[9:7] ^ pixel_count[9:7]) : 3'b0; vgaGreen <= blank ? (line_count[6:4] ^ pixel_count[6:4]) : 3'b0; vgaBlue <= blank ? (line_count[3:2] ^ pixel_count[3:2]) : 2'b0; HSYNC <= hs; VSYNC <= vs; end */ //------------------------------------------------------------ // NOTES: // 1) Need to generate a 65MHz clock (1024x768@60 video) from // 25MHz. Recall that: // CLKFX_MULTIPLY is between 2 and 32 (inclusive) // CLKFX_DIVIDE is between 1 and 32 // 2) Recall that the VGA color signals MUST be set to black // during a blanking period. //============================================================ module xvga( input clk, input reset, output reg [10:0] pixel_count, output reg [9:0] line_count, output reg hsync, // hsync, vsync, blank are active low output reg vsync, output reg blank ); parameter H_ACTIVE = 11'd1024; parameter H_FP = 11'd24; // front porch parameter H_SP = 11'd136; // sync pulse parameter H_BP = 11'd160; // back porch parameter H_TOTAL = 11'd1344; // ACTIVE + FP + SP + BP parameter V_ACTIVE = 10'd768; parameter V_FP = 10'd3; parameter V_SP = 10'd6; parameter V_BP = 10'd29; parameter V_TOTAL = 10'd806; // next state is computed with combinational logic wire [10:0] next_pixel_count; wire [9:0] next_line_count; assign next_pixel_count = (pixel_count == H_TOTAL - 11'd1) ? 11'b0 : pixel_count + 11'd1; assign next_line_count = (pixel_count == H_TOTAL - 11'd1) ? (line_count == V_TOTAL - 10'd1) ? 10'b0 : line_count + 10'd1 : line_count; always @ (posedge clk) if (reset) begin pixel_count <= 11'b0; line_count <= 10'b0; hsync <= 1'b1; vsync <= 1'b1; blank <= 1'b1; end else begin pixel_count <= next_pixel_count; line_count <= next_line_count; hsync <= (next_pixel_count < H_ACTIVE + H_FP) | (next_pixel_count >= H_ACTIVE + H_FP + H_SP); vsync <= (next_line_count < V_ACTIVE + V_FP) | (next_line_count >= V_ACTIVE + V_FP + V_SP); blank <= (next_pixel_count < H_ACTIVE) & (next_line_count < V_ACTIVE); end endmodule