galaxians
[fpga-games] / galaxian / src / mc_vga_if.v
1 //===============================================================================
2 // FPGA VGA INTERFACE FOR ALTERA CYCLONE & XILINX SPARTAN2E
3 //
4 // Version : 2.00
5 //
6 // Copyright(c) 2003 - 2004 Katsumi Degawa , All rights reserved
7 //
8 // based on a design by Tatsuyuki Satoh
9 //
10 // Important !
11 //
12 // This program is freeware for non-commercial use.
13 // An author does no guarantee about this program.
14 // You can use this under your own risk.
15 //
16 // 2004- 9-18 added SPARTAN2E DEVIDE . K.DEGAWA
17 //================================================================================
18 `include "src/mc_conf.v"
19
20 module mc_vga_if(
21
22 I_CLK_1,
23 I_CLK_2,
24 I_R,
25 I_G,
26 I_B,
27 I_H_SYNC,
28 I_V_SYNC,
29
30 O_R,
31 O_G,
32 O_B,
33 O_H_SYNCn,
34 O_V_SYNCn
35
36 );
37
38 // input signals
39 input I_CLK_1; // 6.144MHz input pixel clock
40 input I_CLK_2; // 12.288Mhz output pixel clock
41 input [2:0]I_R; // R in
42 input [2:0]I_G; // G in
43 input [1:0]I_B; // B in
44 input I_H_SYNC; // HSYNC input (16KHz)
45 input I_V_SYNC; // VSYNC input (60Hz)
46
47 // output signals
48 output [4:0]O_R; // R out
49 output [4:0]O_G; // G out
50 output [4:0]O_B; // B out
51 output O_H_SYNCn; // HSYNC output
52 output O_V_SYNCn; // VSYNC output
53
54 //---------------------------------------------------------------------------
55 // setup parameter
56 //---------------------------------------------------------------------------
57
58 parameter H_COUNT = 384; // number of pixels in H-SCAN
59 parameter HS_POS = 16; // HSYNC position
60 parameter HS_WIDTH = HS_POS+8; // HSYNC width / pixel
61 parameter VS_WIDTH = 8; // VSYNC width / HSYNC_OUT
62
63 //---------------------------------------------------------------------------
64 // input timming
65 //---------------------------------------------------------------------------
66 reg [8:0]Hpos_in; // input capture postion
67 reg L_Hsync_i;
68 wire HP_in = ~L_Hsync_i & I_H_SYNC;
69 always@(posedge I_CLK_1)
70 begin
71 Hpos_in <= HP_in ? 0: Hpos_in + 1;
72 L_Hsync_i <= I_H_SYNC;
73 end
74
75 //---------------------------------------------------------------------------
76 //output timming
77 //---------------------------------------------------------------------------
78 reg [8:0]Hpos_out;
79 reg L_Hsync_o;
80 wire HP_out = ~L_Hsync_o & I_H_SYNC;
81 wire HP_ret = HP_out | (Hpos_out == H_COUNT-1);
82
83 always@(posedge I_CLK_2)
84 begin
85 Hpos_out <= HP_ret ? 0:Hpos_out + 1;
86 L_Hsync_o <= I_H_SYNC;
87 end
88
89 reg O_Hsync;
90 always@(posedge I_CLK_2)
91 begin
92 case(Hpos_out)
93 HS_POS :O_Hsync <= 1'b1;
94 HS_WIDTH:O_Hsync <= 1'b0;
95 default :;
96 endcase
97 end
98
99 //---------------------------------------------------------------------------
100 // RGB capture(portA) & output(portB)
101 //---------------------------------------------------------------------------
102 wire [7:0]rgb_in = {I_R,I_G,I_B}; // RGB input
103 wire [7:0]rgb_out; // RGB output
104
105 `ifdef DEVICE_CYCLONE
106 alt_ram_512_8_d double_scan_ram(
107
108 .clock_a(I_CLK_1),
109 .address_a(Hpos_in),
110 .q_a(),
111 .data_a(rgb_in),
112 .wren_a(1'b1),
113 .enable_a(1'b1),
114 .aclr_a(1'b0),
115
116 .clock_b(I_CLK_2),
117 .address_b(Hpos_out),
118 .q_b(rgb_out),
119 .data_b(4'h0),
120 .wren_b(1'b0),
121 .enable_b(1'b1),
122 .aclr_b(1'b0)
123
124 );
125 `endif
126 `ifdef DEVICE_SPARTAN2E
127 RAMB4_S8_S8 double_scan_ram (
128
129 .CLKA(I_CLK_1),
130 .ADDRA(Hpos_in),
131 .DOA(),
132 .DIA(rgb_in),
133 .WEA(1'b1),
134 .ENA(1'b1),
135 .RSTA(1'b0),
136
137 .CLKB(I_CLK_2),
138 .ADDRB(Hpos_out),
139 .DOB(rgb_out),
140 .DIB(4'h0),
141 .WEB(1'b0),
142 .ENB(1'b1),
143 .RSTB(1'b0)
144
145 );
146 `endif
147 //---------------------------------------------------------------------------
148 // vsync remake
149 //
150 // 1 HSYNC_IN delay & HSYNC pulse width = 4xHSYNC(in)
151 //---------------------------------------------------------------------------
152
153 reg [2:0]vs_cnt;
154 reg O_Vsync;
155
156 always @(posedge O_Hsync)
157 begin
158 if(~I_V_SYNC)begin
159 vs_cnt <= VS_WIDTH-1;
160 end
161 else begin
162 if(vs_cnt==0) vs_cnt <= vs_cnt;
163 else vs_cnt <= vs_cnt-1;
164 end
165 end
166 always @(posedge O_Hsync)
167 begin
168 case(vs_cnt)
169 VS_WIDTH-2 :O_Vsync <= 1;
170 0 :O_Vsync <= 0;
171 endcase
172 end
173 //---------------------------------------------------------------------------
174 // output
175 //---------------------------------------------------------------------------
176
177 assign O_R = {2'b00,rgb_out[7:5]};
178 assign O_G = {2'b00,rgb_out[4:2]};
179 assign O_B = {3'b000,rgb_out[1:0]};
180
181 // converted H V SYNC
182 assign O_H_SYNCn = ~O_Hsync;
183 assign O_V_SYNCn = ~O_Vsync;
184
185 endmodule
186
187 `ifdef DEVICE_CYCLONE
188 module alt_ram_512_8_d (
189 data_a,
190 wren_a,
191 address_a,
192 data_b,
193 address_b,
194 wren_b,
195 clock_a,
196 enable_a,
197 clock_b,
198 enable_b,
199 aclr_a,
200 aclr_b,
201 q_a,
202 q_b);
203
204 input [7:0] data_a;
205 input wren_a;
206 input [8:0] address_a;
207 input [7:0] data_b;
208 input [8:0] address_b;
209 input wren_b;
210 input clock_a;
211 input enable_a;
212 input clock_b;
213 input enable_b;
214 input aclr_a;
215 input aclr_b;
216 output [7:0] q_a;
217 output [7:0] q_b;
218
219 wire [7:0] sub_wire0;
220 wire [7:0] sub_wire1;
221 wire [7:0] q_a = sub_wire0[7:0];
222 wire [7:0] q_b = sub_wire1[7:0];
223
224 altsyncram altsyncram_component (
225 .clocken0 (enable_a),
226 .clocken1 (enable_b),
227 .wren_a (wren_a),
228 .aclr0 (aclr_a),
229 .clock0 (clock_a),
230 .wren_b (wren_b),
231 .aclr1 (aclr_b),
232 .clock1 (clock_b),
233 .address_a (address_a),
234 .address_b (address_b),
235 .data_a (data_a),
236 .data_b (data_b),
237 .q_a (sub_wire0),
238 .q_b (sub_wire1));
239 defparam
240 altsyncram_component.operation_mode = "BIDIR_DUAL_PORT",
241 altsyncram_component.width_a = 8,
242 altsyncram_component.widthad_a = 9,
243 altsyncram_component.numwords_a = 512,
244 altsyncram_component.width_b = 8,
245 altsyncram_component.widthad_b = 9,
246 altsyncram_component.numwords_b = 512,
247 altsyncram_component.lpm_type = "altsyncram",
248 altsyncram_component.width_byteena_a = 1,
249 altsyncram_component.width_byteena_b = 1,
250 altsyncram_component.outdata_reg_a = "UNREGISTERED",
251 altsyncram_component.outdata_aclr_a = "NONE",
252 altsyncram_component.outdata_reg_b = "UNREGISTERED",
253 altsyncram_component.indata_aclr_a = "CLEAR0",
254 altsyncram_component.wrcontrol_aclr_a = "CLEAR0",
255 altsyncram_component.address_aclr_a = "CLEAR0",
256 altsyncram_component.indata_reg_b = "CLOCK1",
257 altsyncram_component.address_reg_b = "CLOCK1",
258 altsyncram_component.wrcontrol_wraddress_reg_b = "CLOCK1",
259 altsyncram_component.indata_aclr_b = "CLEAR1",
260 altsyncram_component.wrcontrol_aclr_b = "CLEAR1",
261 altsyncram_component.address_aclr_b = "CLEAR1",
262 altsyncram_component.outdata_aclr_b = "NONE",
263 altsyncram_component.ram_block_type = "M4K",
264 altsyncram_component.intended_device_family = "Stratix";
265
266
267 endmodule
268 `endif
Impressum, Datenschutz