cleanup clocks
[fpga-games] / galaxian / src / mc_video.v
1 //===============================================================================
2 // FPGA GALAXIAN VIDEO
3 //
4 // Version : 2.50
5 //
6 // Copyright(c) 2004 Katsumi Degawa , All rights reserved
7 //
8 // Important !
9 //
10 // This program is freeware for non-commercial use.
11 // An author does no guarantee about this program.
12 // You can use this under your own risk.
13 //
14 // 2004- 4-30 galaxian modify by K.DEGAWA
15 // 2004- 5- 6 first release.
16 // 2004- 8-23 Improvement with T80-IP.
17 // 2004- 9-22 The problem which missile didn't sometimes come out from was improved.
18 //================================================================================
19 //-----------------------------------------------------------------------------------------
20 // H_CNT[0],H_CNT[1],H_CNT[2],H_CNT[3],H_CNT[4],H_CNT[5],H_CNT[6],H_CNT[7],H_CNT[8],
21 // 1 H 2 H 4H 8H 16 H 32H 64 H 128 H 256 H
22 //-----------------------------------------------------------------------------------------
23 // V_CNT[0], V_CNT[1], V_CNT[2], V_CNT[3], V_CNT[4], V_CNT[5], V_CNT[6], V_CNT[7]
24 // 1 V 2 V 4 V 8 V 16 V 32 V 64 V 128 V
25 //-----------------------------------------------------------------------------------------
26
27 module mc_video(
28
29 I_CLK_18M,
30 I_CLK_12M,
31 I_CLK_6M,
32 I_H_CNT,
33 I_V_CNT,
34 I_H_FLIP,
35 I_V_FLIP,
36 I_V_BLn,
37 I_C_BLn,
38
39 I_A,
40 I_OBJ_SUB_A,
41 I_BD,
42 I_OBJ_RAM_RQn,
43 I_OBJ_RAM_RDn,
44 I_OBJ_RAM_WRn,
45 I_VID_RAM_RDn,
46 I_VID_RAM_WRn,
47
48 O_C_BLnX,
49 O_8HF,
50 O_256HnX,
51 O_1VF,
52 O_MISSILEn,
53 O_SHELLn,
54 O_BD,
55 O_VID,
56 O_COL
57
58 );
59
60 input I_CLK_18M;
61 input I_CLK_12M;
62 input I_CLK_6M;
63 input [8:0]I_H_CNT;
64 input [7:0]I_V_CNT;
65 input I_H_FLIP;
66 input I_V_FLIP;
67 input I_V_BLn;
68 input I_C_BLn;
69
70 input [9:0]I_A;
71 input [7:0]I_BD;
72 input [2:0]I_OBJ_SUB_A;
73 input I_OBJ_RAM_RQn;
74 input I_OBJ_RAM_RDn;
75 input I_OBJ_RAM_WRn;
76 input I_VID_RAM_RDn;
77 input I_VID_RAM_WRn;
78
79 output O_C_BLnX;
80 output O_8HF;
81 output O_256HnX;
82 output O_1VF;
83 output O_MISSILEn;
84 output O_SHELLn;
85
86 output [7:0]O_BD;
87 output [1:0]O_VID;
88 output [2:0]O_COL;
89
90 wire WB_LDn;
91 wire WB_CNTRLDn;
92 wire WB_CNTRCLRn;
93 wire WB_COLLn;
94 wire WB_VPLn;
95 wire WB_OBJDATALn;
96 wire WB_MLDn;
97 wire WB_SLDn;
98 wire W_3D;
99 reg W_LDn;
100 reg W_CNTRLDn;
101 reg W_CNTRCLRn;
102 reg W_COLLn;
103 reg W_VPLn;
104 reg W_OBJDATALn;
105 reg W_MLDn;
106 reg W_SLDn;
107
108 always@(negedge I_CLK_12M)
109 begin
110 W_LDn <= WB_LDn;
111 W_CNTRLDn <= WB_CNTRLDn;
112 W_CNTRCLRn <= WB_CNTRCLRn;
113 W_COLLn <= WB_COLLn;
114 W_VPLn <= WB_VPLn;
115 W_OBJDATALn <= WB_OBJDATALn;
116 W_MLDn <= WB_MLDn;
117 W_SLDn <= WB_SLDn;
118 end
119
120 mc_ld_pls LD_PLS(
121
122 .I_CLK_6M(I_CLK_6M),
123 .I_H_CNT(I_H_CNT),
124 .I_3D_DI(W_3D),
125
126 .O_LDn(WB_LDn),
127 .O_CNTRLDn(WB_CNTRLDn),
128 .O_CNTRCLRn(WB_CNTRCLRn),
129 .O_COLLn(WB_COLLn),
130 .O_VPLn(WB_VPLn),
131 .O_OBJDATALn(WB_OBJDATALn),
132 .O_MLDn(WB_MLDn),
133 .O_SLDn(WB_SLDn)
134
135 );
136
137 wire W_H_FLIP1 = ~I_H_CNT[8]&I_H_FLIP;
138
139 wire [7:3]W_HF_CNT = I_H_CNT[7:3]^{5{W_H_FLIP1}};
140 wire [7:0]W_VF_CNT = I_V_CNT[7:0]^{8{I_V_FLIP}};
141
142 assign O_8HF = W_HF_CNT[3];
143 assign O_1VF = W_VF_CNT[0];
144
145 reg [7:0]W_OBJ_D;
146 wire [3:0]W_6J_DA = {I_H_FLIP , W_HF_CNT[7],W_HF_CNT[3],I_H_CNT[2]};
147 wire [3:0]W_6J_DB = {W_OBJ_D[6],W_HF_CNT[3]&I_H_CNT[1], I_H_CNT[2],I_H_CNT[1]};
148 wire [3:0]W_6J_Q = I_H_CNT[8] ? W_6J_DB:W_6J_DA;
149
150 wire W_H_FLIP2 = W_6J_Q[3];
151 // Prats 4F,5F
152 wire [7:0]W_OBJ_RAM_AB = {1'b0,I_H_CNT[8],W_6J_Q[2],W_HF_CNT[6:4],W_6J_Q[1:0]};
153 wire [7:0]W_OBJ_RAM_A = I_OBJ_RAM_RQn ? W_OBJ_RAM_AB: I_A[7:0] ;
154
155 wire [7:0]W_OBJ_RAM_DOA,W_OBJ_RAM_DOB;
156
157 reg [7:0]W_H_POSI;
158 always@(posedge I_CLK_12M) W_H_POSI <= W_OBJ_RAM_DOB;
159
160 mc_obj_ram OBJ_RAM(
161
162 .I_CLKA(I_CLK_12M),
163 .I_ADDRA(I_A[7:0]),
164 .I_WEA(~I_OBJ_RAM_WRn),
165 .I_CEA(~I_OBJ_RAM_RQn),
166 .I_DA(I_BD),
167 .O_DA(W_OBJ_RAM_DOA),
168
169 .I_CLKB(I_CLK_12M),
170 .I_ADDRB(W_OBJ_RAM_AB),
171 .I_WEB(1'b0),
172 .I_CEB(1'b1),
173 .I_DB(8'h00),
174 .O_DB(W_OBJ_RAM_DOB)
175
176 );
177
178 wire [7:0]W_OBJ_RAM_D = I_OBJ_RAM_RDn ? 8'h00: W_OBJ_RAM_DOA;
179 // Prats 4L
180 always@(posedge W_OBJDATALn) W_OBJ_D <= W_H_POSI;
181 // Prats 4,5N
182
183 wire [8:0]W_45N_Q = W_VF_CNT[7:0] + W_H_POSI ;
184 assign W_3D = ~(&W_45N_Q[7:0]);
185
186 reg [7:0]W_2M_Q;
187 always@(posedge W_VPLn or negedge I_V_BLn)
188 begin
189 if(I_V_BLn==1'b0)
190 W_2M_Q <= 0;
191 else
192 W_2M_Q <= W_45N_Q[7:0];
193 end
194
195 wire W_2N = I_H_CNT[8]&W_OBJ_D[7];
196 wire [3:0]W_1M = W_2M_Q[3:0]^{W_2N,W_2N,W_2N,W_2N};
197
198 wire W_VID_RAM_CSn = I_VID_RAM_RDn & I_VID_RAM_WRn;
199
200 wire [7:0]W_VID_RAM_DI = I_VID_RAM_WRn ? 8'h00 : I_BD ;
201 wire [7:0]W_VID_RAM_DOA;
202
203 wire [11:0]W_VID_RAM_AA = {~(&W_2M_Q[7:4]),W_VID_RAM_CSn, 10'h00 /*I_A[9:0]*/};
204 wire [11:0]W_VID_RAM_AB = { 1'b0, 1'b0,W_2M_Q[7:4],W_1M[3],W_HF_CNT[7:3]};
205
206 wire [11:0]W_VID_RAM_A = I_C_BLn ? W_VID_RAM_AB:W_VID_RAM_AA;
207
208 wire [7:0]W_VID_RAM_D = I_VID_RAM_RDn ? 8'h00 :W_VID_RAM_DOA;
209
210 wire [7:0]W_VID_RAM_DOB;
211
212 mc_vid_ram VID_RAM(
213
214 .I_CLKA(I_CLK_12M),
215 .I_ADDRA(I_A[9:0]),
216 .I_DA(W_VID_RAM_DI),
217 .I_WEA(~I_VID_RAM_WRn),
218 .I_CEA(~W_VID_RAM_CSn),
219 .O_DA(W_VID_RAM_DOA),
220
221 .I_CLKB(I_CLK_12M),
222 .I_ADDRB(W_VID_RAM_A[9:0]),
223 .I_DB(8'h00),
224 .I_WEB(1'b0),
225 .I_CEB(1'b1),
226 .O_DB(W_VID_RAM_DOB)
227
228 );
229 //-- VIDEO DATA OUTPUT --------------
230 assign O_BD = W_OBJ_RAM_D | W_VID_RAM_D;
231
232 wire W_SRLD = ~(W_LDn | W_VID_RAM_A[11]);
233
234 wire [7:0]W_OBJ_ROM_AB = {W_OBJ_D[5:0],W_1M[3],W_OBJ_D[6]^I_H_CNT[3]};
235
236 wire [7:0]W_OBJ_ROM_A = I_H_CNT[8] ? W_OBJ_ROM_AB: W_VID_RAM_DOB;
237
238 wire [10:0]W_O_OBJ_ROM_A = {W_OBJ_ROM_A,W_1M[2:0]};
239
240 wire [7:0]W_1K_D;
241 wire [7:0]W_1H_D;
242
243 //1K VID-Rom
244 GALAXIAN_1K K_ROM(
245 .CLK(I_CLK_12M),
246 .ADDR(W_O_OBJ_ROM_A),
247 .DATA(W_1K_D),
248 .ENA(1'b1)
249 );
250
251 //1H VID-Rom
252 GALAXIAN_1H H_ROM(
253 .CLK(I_CLK_12M),
254 .ADDR(W_O_OBJ_ROM_A),
255 .DATA(W_1H_D),
256 .ENA(1'b1)
257 );
258
259
260 //---------------------------------------------------------------------------------
261 wire W_2L_Qa,W_2K_Qd;
262 wire W_2J_Qa,W_2H_Qd;
263 wire W_H_FLIP2X;
264
265 wire [3:0]W_3L_A = {W_2J_Qa,W_2L_Qa, 1'b1,W_SRLD};
266 wire [3:0]W_3L_B = {W_2H_Qd,W_2K_Qd,W_SRLD, 1'b1};
267 wire [3:0]W_3L_Y = W_H_FLIP2X ? W_3L_B: W_3L_A; // [3]=RAW1,[2]=RAW0
268
269 wire W_RAW0 = W_3L_Y[2];
270 wire W_RAW1 = W_3L_Y[3];
271
272 wire W_SRCLK = I_CLK_6M;
273 //------ PARTS 2KL ----------------------------------------------
274 wire [1:0]C_2KL = W_3L_Y[1:0];
275 wire [7:0]I_2KL = W_1K_D;
276 reg [7:0]reg_2KL;
277
278 assign W_2L_Qa = reg_2KL[7];
279 assign W_2K_Qd = reg_2KL[0];
280 always@(posedge W_SRCLK)
281 begin
282 case(C_2KL)
283 2'b00: reg_2KL <= reg_2KL;
284 2'b10: reg_2KL <= {reg_2KL[6:0],1'b0};
285 2'b01: reg_2KL <= {1'b0,reg_2KL[7:1]};
286 2'b11: reg_2KL <= I_2KL;
287 endcase
288 end
289 //------ PARTS 2HJ ----------------------------------------------
290 wire [1:0]C_2HJ = W_3L_Y[1:0];
291 wire [7:0]I_2HJ = W_1H_D;
292 reg [7:0]reg_2HJ;
293
294 assign W_2J_Qa = reg_2HJ[7];
295 assign W_2H_Qd = reg_2HJ[0];
296 always@(posedge W_SRCLK)
297 begin
298 case(C_2HJ)
299 2'b00: reg_2HJ <= reg_2HJ;
300 2'b10: reg_2HJ <= {reg_2HJ[6:0],1'b0};
301 2'b01: reg_2HJ <= {1'b0,reg_2HJ[7:1]};
302 2'b11: reg_2HJ <= I_2HJ;
303 endcase
304 end
305
306 //----- SHT2 -----------------------------------------------------
307 // Prats 6K
308 reg [2:0]W_6K_Q;
309 always@(posedge W_COLLn) W_6K_Q <= W_H_POSI[2:0];
310
311 // Prats 6P
312 reg [6:0]W_6P_Q;
313 always@(posedge I_CLK_6M)
314 begin
315 if(W_LDn==1'b0) W_6P_Q <= {W_H_FLIP2,W_H_FLIP1,I_C_BLn,~I_H_CNT[8],W_6K_Q[2:0]};
316 else W_6P_Q <= W_6P_Q;
317 end
318
319 assign W_H_FLIP2X = W_6P_Q[6];
320 wire W_H_FLIP1X = W_6P_Q[5];
321 wire W_C_BLnX = W_6P_Q[4];
322 wire W_256HnX = W_6P_Q[3];
323 wire [2:0]W_CD = W_6P_Q[2:0];
324
325 assign O_256HnX = W_256HnX;
326 assign O_C_BLnX = W_C_BLnX;
327
328 wire W_45T_CLR = W_CNTRCLRn | W_256HnX ;
329 reg [7:0]W_45T_Q;
330
331 always@(posedge I_CLK_6M)
332 begin
333 if(W_45T_CLR==1'b0)
334 W_45T_Q <= 0;
335 else if(W_CNTRLDn==1'b0)
336 W_45T_Q <= W_H_POSI;
337 else
338 W_45T_Q <= W_45T_Q + 1;
339 end
340
341 wire [7:0]W_LRAM_A = W_45T_Q^{8{W_H_FLIP1X}};
342
343 wire [4:0]W_LRAM_DI;
344 wire [4:0]W_LRAM_DO;
345
346 reg [1:0]W_RV;
347 reg [2:0]W_RC;
348
349 always@(negedge I_CLK_6M)
350 begin
351 W_RV <= W_LRAM_DO[1:0];
352 W_RC <= W_LRAM_DO[4:2];
353 end
354
355 wire W_LRAM_AND = ~(~((W_LRAM_A[4]|W_LRAM_A[5])|(W_LRAM_A[6]|W_LRAM_A[7]))|W_256HnX );
356 wire W_RAW_OR = W_RAW0 | W_RAW1 ;
357
358 wire [1:0]W_VID;
359 wire [2:0]W_COL;
360
361 assign W_VID[0] = ~(~(W_RAW0&W_RV[1])&W_RV[0]);
362 assign W_VID[1] = ~(~(W_RAW1&W_RV[0])&W_RV[1]);
363 assign W_COL[0] = ~(~(W_RAW_OR&W_CD[0]&W_RC[1]&W_RC[2])&W_RC[0]);
364 assign W_COL[1] = ~(~(W_RAW_OR&W_CD[1]&W_RC[2]&W_RC[0])&W_RC[1]);
365 assign W_COL[2] = ~(~(W_RAW_OR&W_CD[2]&W_RC[0]&W_RC[1])&W_RC[2]);
366
367 assign O_VID = W_VID;
368 assign O_COL = W_COL;
369
370 assign W_LRAM_DI[0] = W_LRAM_AND&W_VID[0];
371 assign W_LRAM_DI[1] = W_LRAM_AND&W_VID[1];
372 assign W_LRAM_DI[2] = W_LRAM_AND&W_COL[0];
373 assign W_LRAM_DI[3] = W_LRAM_AND&W_COL[1];
374 assign W_LRAM_DI[4] = W_LRAM_AND&W_COL[2];
375
376 mc_lram LRAM(
377
378 .I_CLK(I_CLK_18M),
379 .I_ADDR(W_LRAM_A),
380 .I_WE(I_CLK_6M),
381 .I_D(W_LRAM_DI),
382 .O_Dn(W_LRAM_DO)
383
384 );
385
386 mc_missile MISSILE(
387
388 .I_CLK_18M(I_CLK_18M),
389 .I_CLK_6M(I_CLK_6M),
390 .I_C_BLn_X(W_C_BLnX),
391 .I_MLDn(W_MLDn),
392 .I_SLDn(W_SLDn),
393 .I_HPOS(W_H_POSI),
394
395 .O_MISSILEn(O_MISSILEn),
396 .O_SHELLn(O_SHELLn)
397
398 );
399
400 endmodule
401
402
Impressum, Datenschutz