//=============================================================================== // FPGA VGA INTERFACE FOR ALTERA CYCLONE & XILINX SPARTAN2E // // Version : 2.00 // // Copyright(c) 2003 - 2004 Katsumi Degawa , All rights reserved // // based on a design by Tatsuyuki Satoh // // Important ! // // This program is freeware for non-commercial use. // An author does no guarantee about this program. // You can use this under your own risk. // // 2004- 9-18 added SPARTAN2E DEVIDE . K.DEGAWA //================================================================================ `include "src/mc_conf.v" module mc_vga_if( I_CLK_1, I_CLK_2, I_R, I_G, I_B, I_H_SYNC, I_V_SYNC, O_R, O_G, O_B, O_H_SYNCn, O_V_SYNCn ); // input signals input I_CLK_1; // 6.144MHz input pixel clock input I_CLK_2; // 12.288Mhz output pixel clock input [2:0]I_R; // R in input [2:0]I_G; // G in input [1:0]I_B; // B in input I_H_SYNC; // HSYNC input (16KHz) input I_V_SYNC; // VSYNC input (60Hz) // output signals output [2:0]O_R; // R out output [2:0]O_G; // G out output [1:0]O_B; // B out output O_H_SYNCn; // HSYNC output output O_V_SYNCn; // VSYNC output //--------------------------------------------------------------------------- // setup parameter //--------------------------------------------------------------------------- parameter H_COUNT = 384; // number of pixels in H-SCAN parameter HS_POS = 16; // HSYNC position parameter HS_WIDTH = HS_POS+8; // HSYNC width / pixel parameter VS_WIDTH = 8; // VSYNC width / HSYNC_OUT //--------------------------------------------------------------------------- // input timming //--------------------------------------------------------------------------- reg [8:0]Hpos_in; // input capture postion reg L_Hsync_i; wire HP_in = ~L_Hsync_i & I_H_SYNC; always@(posedge I_CLK_1) begin Hpos_in <= HP_in ? 0: Hpos_in + 1; L_Hsync_i <= I_H_SYNC; end //--------------------------------------------------------------------------- //output timming //--------------------------------------------------------------------------- reg [8:0]Hpos_out; reg L_Hsync_o; wire HP_out = ~L_Hsync_o & I_H_SYNC; wire HP_ret = HP_out | (Hpos_out == H_COUNT-1); always@(posedge I_CLK_2) begin Hpos_out <= HP_ret ? 0:Hpos_out + 1; L_Hsync_o <= I_H_SYNC; end reg O_Hsync; always@(posedge I_CLK_2) begin case(Hpos_out) HS_POS :O_Hsync <= 1'b1; HS_WIDTH:O_Hsync <= 1'b0; default :; endcase end //--------------------------------------------------------------------------- // RGB capture(portA) & output(portB) //--------------------------------------------------------------------------- wire [7:0]rgb_in = {I_R,I_G,I_B}; // RGB input wire [7:0]rgb_out; // RGB output `ifdef DEVICE_CYCLONE alt_ram_512_8_d double_scan_ram( .clock_a(I_CLK_1), .address_a(Hpos_in), .q_a(), .data_a(rgb_in), .wren_a(1'b1), .enable_a(1'b1), .aclr_a(1'b0), .clock_b(I_CLK_2), .address_b(Hpos_out), .q_b(rgb_out), .data_b(4'h0), .wren_b(1'b0), .enable_b(1'b1), .aclr_b(1'b0) ); `endif `ifdef DEVICE_SPARTAN2E RAMB4_S8_S8 double_scan_ram ( .CLKA(I_CLK_1), .ADDRA(Hpos_in), .DOA(), .DIA(rgb_in), .WEA(1'b1), .ENA(1'b1), .RSTA(1'b0), .CLKB(I_CLK_2), .ADDRB(Hpos_out), .DOB(rgb_out), .DIB(4'h0), .WEB(1'b0), .ENB(1'b1), .RSTB(1'b0) ); `endif //--------------------------------------------------------------------------- // vsync remake // // 1 HSYNC_IN delay & HSYNC pulse width = 4xHSYNC(in) //--------------------------------------------------------------------------- reg [2:0]vs_cnt; reg O_Vsync; always @(posedge O_Hsync) begin if(~I_V_SYNC)begin vs_cnt <= VS_WIDTH-1; end else begin if(vs_cnt==0) vs_cnt <= vs_cnt; else vs_cnt <= vs_cnt-1; end end always @(posedge O_Hsync) begin case(vs_cnt) VS_WIDTH-2 :O_Vsync <= 1; 0 :O_Vsync <= 0; endcase end //--------------------------------------------------------------------------- // output //--------------------------------------------------------------------------- assign O_R = rgb_out[7:5]; assign O_G = rgb_out[4:2]; assign O_B = rgb_out[1:0]; // converted H V SYNC assign O_H_SYNCn = ~O_Hsync; assign O_V_SYNCn = ~O_Vsync; endmodule `ifdef DEVICE_CYCLONE module alt_ram_512_8_d ( data_a, wren_a, address_a, data_b, address_b, wren_b, clock_a, enable_a, clock_b, enable_b, aclr_a, aclr_b, q_a, q_b); input [7:0] data_a; input wren_a; input [8:0] address_a; input [7:0] data_b; input [8:0] address_b; input wren_b; input clock_a; input enable_a; input clock_b; input enable_b; input aclr_a; input aclr_b; output [7:0] q_a; output [7:0] q_b; wire [7:0] sub_wire0; wire [7:0] sub_wire1; wire [7:0] q_a = sub_wire0[7:0]; wire [7:0] q_b = sub_wire1[7:0]; altsyncram altsyncram_component ( .clocken0 (enable_a), .clocken1 (enable_b), .wren_a (wren_a), .aclr0 (aclr_a), .clock0 (clock_a), .wren_b (wren_b), .aclr1 (aclr_b), .clock1 (clock_b), .address_a (address_a), .address_b (address_b), .data_a (data_a), .data_b (data_b), .q_a (sub_wire0), .q_b (sub_wire1)); defparam altsyncram_component.operation_mode = "BIDIR_DUAL_PORT", altsyncram_component.width_a = 8, altsyncram_component.widthad_a = 9, altsyncram_component.numwords_a = 512, altsyncram_component.width_b = 8, altsyncram_component.widthad_b = 9, altsyncram_component.numwords_b = 512, altsyncram_component.lpm_type = "altsyncram", altsyncram_component.width_byteena_a = 1, altsyncram_component.width_byteena_b = 1, altsyncram_component.outdata_reg_a = "UNREGISTERED", altsyncram_component.outdata_aclr_a = "NONE", altsyncram_component.outdata_reg_b = "UNREGISTERED", altsyncram_component.indata_aclr_a = "CLEAR0", altsyncram_component.wrcontrol_aclr_a = "CLEAR0", altsyncram_component.address_aclr_a = "CLEAR0", altsyncram_component.indata_reg_b = "CLOCK1", altsyncram_component.address_reg_b = "CLOCK1", altsyncram_component.wrcontrol_wraddress_reg_b = "CLOCK1", altsyncram_component.indata_aclr_b = "CLEAR1", altsyncram_component.wrcontrol_aclr_b = "CLEAR1", altsyncram_component.address_aclr_b = "CLEAR1", altsyncram_component.outdata_aclr_b = "NONE", altsyncram_component.ram_block_type = "M4K", altsyncram_component.intended_device_family = "Stratix"; endmodule `endif