]> git.zerfleddert.de Git - fpga-games/blob - galaxian/src/psPAD_top.v
galaxians
[fpga-games] / galaxian / src / psPAD_top.v
1 //-------------------------------------------------------------------
2 //
3 // PLAYSTATION CONTROLLER(DUALSHOCK TYPE) INTERFACE TOP
4 //
5 // Version : 2.00
6 //
7 // Copyright(c) 2003 - 2004 Katsumi Degawa , All rights reserved
8 //
9 // Important !
10 //
11 // This program is freeware for non-commercial use.
12 // An author does no guarantee about this program.
13 // You can use this under your own risk.
14 //
15 // 2003.10.30 It is optimized for the FPGA game.
16 // It was made an analog mode fixation.(Dualshock)
17 // by K Degawa
18 //
19 //-------------------------------------------------------------------
20 //--------- SIMULATION ----------------------------------------------
21 //`define SIMULATION_1
22
23 `ifdef SIMULATION_1
24 `define Timer_siz 18
25 `else
26 `define Timer_siz 12
27 `endif
28 //-------------------------------------------------------------------
29
30 `timescale 100ps/10ps
31 `include "src/mc_conf.v"
32
33 module psPAD_top(
34
35 I_CLK250K, // MAIN CLK 250KHz
36 I_RSTn, // MAIN RESET
37 O_psCLK, // psCLK CLK OUT
38 O_psSEL, // psSEL OUT
39 O_psTXD, // psTXD OUT
40 I_psRXD, // psRXD IN
41 O_RXD_1, // RX DATA 1 (8bit)
42 O_RXD_2, // RX DATA 2 (8bit)
43 O_RXD_3, // RX DATA 3 (8bit)
44 O_RXD_4, // RX DATA 4 (8bit)
45 O_RXD_5, // RX DATA 5 (8bit)
46 O_RXD_6, // RX DATA 6 (8bit)
47 I_CONF_SW, //
48 I_MODE_SW, //
49 I_MODE_EN, //
50 I_VIB_SW, // Vibration SW VIB_SW[0] Small Moter OFF 0:ON 1:
51 // VIB_SW[1] Bic Moter OFF 0:ON 1(Dualshook Only)
52 I_VIB_DAT // Vibration(Bic Moter)Data 8'H00-8'HFF (Dualshook Only)
53
54 );
55
56 input I_CLK250K,I_RSTn;
57 input I_CONF_SW;
58 input I_MODE_SW,I_MODE_EN;
59 input [1:0]I_VIB_SW;
60 input [7:0]I_VIB_DAT;
61 input I_psRXD;
62 output O_psCLK;
63 output O_psSEL;
64 output O_psTXD;
65 output [7:0]O_RXD_1;
66 output [7:0]O_RXD_2;
67 output [7:0]O_RXD_3;
68 output [7:0]O_RXD_4;
69 output [7:0]O_RXD_5;
70 output [7:0]O_RXD_6;
71
72 wire W_scan_seq_pls;
73 wire W_type;
74 wire [3:0]W_byte_cnt;
75 wire W_RXWT;
76 wire W_TXWT;
77 wire W_TXSET;
78 wire W_TXEN;
79 wire [7:0]W_TXD_DAT;
80 wire [7:0]W_RXD_DAT;
81 wire W_conf_ent;
82
83 ps_pls_gan pls(
84
85 .I_CLK(I_CLK250K),
86 .I_RSTn(I_RSTn),
87 .I_TYPE(W_type), // DEGITAL PAD 0: ANALOG PAD 1:
88
89 .O_SCAN_SEQ_PLS(W_scan_seq_pls),
90 .O_RXWT(W_RXWT),
91 .O_TXWT(W_TXWT),
92 .O_TXSET(W_TXSET),
93 .O_TXEN(W_TXEN),
94 .O_psCLK(O_psCLK),
95 .O_psSEL(O_psSEL),
96 .O_byte_cnt(W_byte_cnt),
97
98 //.Timer(O_Timer)
99 .Timer()
100
101 );
102
103 `ifdef Dualshock
104 txd_commnd cmd(
105
106 .I_CLK(W_TXSET),
107 .I_RSTn(I_RSTn),
108 .I_BYTE_CNT(W_byte_cnt),
109 .I_MODE({I_CONF_SW,~I_MODE_EN,I_MODE_SW}),
110 .I_VIB_SW(I_VIB_SW),
111 .I_VIB_DAT(I_VIB_DAT),
112 .I_RXD_DAT(W_RXD_DAT),
113 .O_TXD_DAT(W_TXD_DAT),
114 .O_TYPE(W_type),
115 .O_CONF_ENT(W_conf_ent)
116
117 );
118
119 `else
120 txd_commnd_EZ cmd(
121
122 .I_CLK(W_TXSET),
123 .I_RSTn(I_RSTn),
124 .I_BYTE_CNT(W_byte_cnt),
125 .I_MODE(),
126 .I_VIB_SW(I_VIB_SW),
127 .I_VIB_DAT(),
128 .I_RXD_DAT(),
129 .O_TXD_DAT(W_TXD_DAT),
130 .O_TYPE(W_type),
131 .O_CONF_ENT(W_conf_ent)
132
133 );
134
135 `endif
136
137 ps_txd txd(
138
139 .I_CLK(I_CLK250K),
140 .I_RSTn(I_RSTn),
141 .I_WT(W_TXWT),
142 .I_EN(W_TXEN),
143 .I_TXD_DAT(W_TXD_DAT),
144 .O_psTXD(O_psTXD)
145
146 );
147
148 ps_rxd rxd(
149
150 .I_CLK(O_psCLK),
151 .I_RSTn(I_RSTn),
152 .I_WT(W_RXWT),
153 .I_psRXD(I_psRXD),
154 .O_RXD_DAT(W_RXD_DAT)
155
156 );
157
158 //---------- RXD DATA DEC ----------------------------------------
159 reg [7:0]O_RXD_1;
160 reg [7:0]O_RXD_2;
161 reg [7:0]O_RXD_3;
162 reg [7:0]O_RXD_4;
163 reg [7:0]O_RXD_5;
164 reg [7:0]O_RXD_6;
165
166 reg W_rxd_mask;
167 always@(posedge W_scan_seq_pls)
168 W_rxd_mask <= ~W_conf_ent;
169
170 always@(negedge W_RXWT)
171 begin
172 if(W_rxd_mask)begin
173 case(W_byte_cnt)
174 3: O_RXD_1 <= W_RXD_DAT;
175 4: O_RXD_2 <= W_RXD_DAT;
176 5: O_RXD_3 <= W_RXD_DAT;
177 6: O_RXD_4 <= W_RXD_DAT;
178 7: O_RXD_5 <= W_RXD_DAT;
179 8: O_RXD_6 <= W_RXD_DAT;
180 default:;
181 endcase
182 end
183 end
184
185 endmodule
186
187 module txd_commnd_EZ(
188
189 I_CLK,
190 I_RSTn,
191 I_BYTE_CNT,
192 I_MODE,
193 I_VIB_SW,
194 I_VIB_DAT,
195 I_RXD_DAT,
196 O_TXD_DAT,
197 O_TYPE,
198 O_CONF_ENT
199
200 );
201
202 input I_CLK,I_RSTn;
203 input [3:0]I_BYTE_CNT;
204 input [2:0]I_MODE;
205 input [1:0]I_VIB_SW;
206 input [7:0]I_VIB_DAT;
207 input [7:0]I_RXD_DAT;
208 output [7:0]O_TXD_DAT;
209 output O_TYPE;
210 output O_CONF_ENT;
211
212 reg [7:0]O_TXD_DAT;
213
214 assign O_TYPE = 1'b1;
215 assign O_CONF_ENT = 1'b0;
216 always@(posedge I_CLK or negedge I_RSTn)
217 begin
218 if(! I_RSTn)begin
219 O_TXD_DAT <= 8'h00;
220 end
221 else begin
222 case(I_BYTE_CNT)
223 0:O_TXD_DAT <= 8'h01;
224 1:O_TXD_DAT <= 8'h42;
225 3:begin
226 if(I_VIB_SW) O_TXD_DAT <= 8'h40;
227 else O_TXD_DAT <= 8'h00;
228 end
229 4:begin
230 if(I_VIB_SW) O_TXD_DAT <= 8'h01;
231 else O_TXD_DAT <= 8'h00;
232 end
233 default: O_TXD_DAT <= 8'h00;
234 endcase
235 end
236 end
237
238 endmodule
239
240 module txd_commnd(
241
242
243 I_CLK,
244 I_RSTn,
245 I_BYTE_CNT,
246 I_MODE,
247 I_VIB_SW,
248 I_VIB_DAT,
249 I_RXD_DAT,
250 O_TXD_DAT,
251 O_TYPE,
252 O_CONF_ENT
253
254 );
255
256 input I_CLK,I_RSTn;
257 input [3:0]I_BYTE_CNT;
258 input [2:0]I_MODE;
259 input [1:0]I_VIB_SW;
260 input [7:0]I_VIB_DAT;
261 input [7:0]I_RXD_DAT;
262 output [7:0]O_TXD_DAT;
263 output O_TYPE;
264 output O_CONF_ENT;
265
266 reg [7:0]O_TXD_DAT;
267 reg [2:0]conf_state;
268 reg conf_entry;
269 reg conf_done;
270 reg pad_status;
271 reg pad_id;
272
273 assign O_TYPE = pad_id;
274 assign O_CONF_ENT = conf_entry;
275
276 always@(posedge I_CLK or negedge I_RSTn)
277 begin
278 if(! I_RSTn) pad_id <= 1'b0;
279 else begin
280 if(I_BYTE_CNT==2)begin
281 case(I_RXD_DAT) //------ GET TYPE(Byte_SEQ)
282 8'h23: pad_id <= 1'b1;
283 8'h41: pad_id <= 1'b0;
284 8'h53: pad_id <= 1'b1;
285 8'h73: pad_id <= 1'b1;
286 8'hE3: pad_id <= 1'b1;
287 8'hF3: pad_id <= 1'b1;
288 default: pad_id <= 1'b0;
289 endcase
290 end
291 end
292 end
293
294 always@(posedge I_CLK or negedge I_RSTn)
295 begin
296 if(! I_RSTn)begin
297 O_TXD_DAT <= 8'h00;
298 conf_entry <= 1'b0;
299 conf_done <= 1'b1;
300 conf_state <= 0;
301 pad_status <= 0;
302 end
303 else begin
304 //---------- nomal mode --------------------------------------------------------
305 //----------------- read_data_and_vibrate_ex 01,42,00,WW,PP(,00,00,00,00)
306 // --,ID,SS,XX,XX(,XX,XX,XX,XX)
307 if(~conf_entry)begin
308 case(I_BYTE_CNT)
309 0:O_TXD_DAT <= 8'h01;
310 1:O_TXD_DAT <= 8'h42;
311 3:begin
312 if(pad_status)begin
313 if(I_VIB_SW[0]) O_TXD_DAT <= 8'h01;
314 else O_TXD_DAT <= 8'h00;
315 end
316 else begin
317 if(I_VIB_SW[0]|I_VIB_SW[1]) O_TXD_DAT <= 8'h40;
318 else O_TXD_DAT <= 8'h00;
319 end
320 end
321 4:begin
322 if(pad_status)begin
323 if(I_VIB_SW[1]) O_TXD_DAT <= I_VIB_DAT;
324 else O_TXD_DAT <= 8'h00;
325 end
326 else begin
327 if(I_VIB_SW[0]|I_VIB_SW[1]) O_TXD_DAT <= 8'h01;
328 else O_TXD_DAT <= 8'h00;
329 end
330 if(pad_id==0)begin
331 if(conf_state == 0)
332 conf_entry <= 1'b1;
333 end
334 end
335 8:begin
336 O_TXD_DAT <= 8'h00;
337 if(pad_id==1)begin
338 if(conf_state == 0)
339 conf_entry <= 1'b1;
340 end
341 end
342 default: O_TXD_DAT <= 8'h00;
343 endcase
344 end
345 //---------- confg mode --------------------------------------------------------
346 else begin
347 case(conf_state)
348 //-------- config_mode_enter (43): 01,43,00,01,00(,00 x 4 or XX x 16)
349 // --,ID,SS,XX,XX(,XX x 4 or XX x 16)
350 0:begin
351 case(I_BYTE_CNT)
352 0:begin
353 O_TXD_DAT <= 8'h01;
354 conf_done <= 1'b0;
355 end
356 1:O_TXD_DAT <= 8'h43;
357 3:O_TXD_DAT <= 8'h01;
358 4:begin
359 O_TXD_DAT <= 8'h00;
360 if(pad_id==0)begin
361 conf_state <= 1;
362 end
363 end
364 8:begin
365 O_TXD_DAT <= 8'h00;
366 if(pad_id==1)begin
367 conf_state <= 1;
368 end
369 end
370 default:O_TXD_DAT <= 8'h00;
371 endcase
372 end
373 //-------- set_mode_and_lock (44): 01,44,00,XX,YY,00,00,00,00
374 //
375 1:begin
376 case(I_BYTE_CNT)
377 0:O_TXD_DAT <= 8'h01;
378 1:O_TXD_DAT <= 8'h44;
379 2:begin
380 O_TXD_DAT <= 8'h00;
381 if(I_RXD_DAT == 8'hF3)begin
382 conf_done <= 1'b0;
383 pad_status <= 1'b1;
384 end
385 else begin
386 conf_done <= 1'b1;
387 pad_status <= 1'b0;
388 end
389 end
390 3:O_TXD_DAT <= 8'h01;
391 4:begin
392 O_TXD_DAT <= 8'h03;
393 if(pad_id==0 && conf_done==1'b1)begin
394 conf_state <= 7;
395 conf_entry <= 1'b0;
396 end
397 end
398 8:begin
399 O_TXD_DAT <= 8'h00;
400 conf_state <= 3;
401 if(pad_id==1 && conf_done==1'b1)begin
402 conf_state <= 7;
403 conf_entry <= 1'b0;
404 end
405 end
406 default:O_TXD_DAT <= 8'h00;
407 endcase
408 end
409 //-------- query_model_and_mode (45): 01,45,00,5A,5A,5A,5A,5A,5A
410 // FF,F3,5A,TT,02,MM,VV,01,00
411 /*
412 1:begin
413 case(I_BYTE_CNT)
414 0:O_TXD_DAT <= 8'h01;
415 1:O_TXD_DAT <= 8'h45;
416 2:begin
417 O_TXD_DAT <= 8'h00;
418 conf_done <= (I_RXD_DAT == 8'hF3)? 1'b0:1'b1;
419 end
420 4:begin
421 O_TXD_DAT <= 8'h00;
422 if(I_RXD_DAT==8'h01 || I_RXD_DAT==8'h03) pad_status <= 1;
423 if(pad_id==0 && conf_done==1'b1)begin
424 conf_state <= 7;
425 conf_entry <= 1'b0;
426 end
427 end
428 8:begin
429 O_TXD_DAT <= 8'h00;
430 conf_state <= 2;
431 if(pad_id==1 && conf_done==1'b1)begin
432 conf_state <= 7;
433 conf_entry <= 1'b0;
434 end
435 end
436 default:O_TXD_DAT <= 8'h00;
437 endcase
438 end
439 //-------- set_mode_and_lock (44): 01,44,00,XX,YY,00,00,00,00
440 // --,F3,5A,00,00,00,00,00,00
441 2:begin
442 case(I_BYTE_CNT)
443 0:O_TXD_DAT <= 8'h01;
444 1:O_TXD_DAT <= 8'h44;
445 3:O_TXD_DAT <= 8'h01;
446 4:O_TXD_DAT <= 8'h03;
447 8:begin
448 O_TXD_DAT <= 8'h00;
449 conf_state<= 3;
450 end
451 default:O_TXD_DAT <= 8'h00;
452 endcase
453 end
454 */
455 //-------- vibration_enable (4D): 01,4D,00,00,01,FF,FF,FF,FF
456 // --,F3,5A,XX,YY,FF,FF,FF,FF
457 3:begin
458 case(I_BYTE_CNT)
459 0:O_TXD_DAT <= 8'h01;
460 1:O_TXD_DAT <= 8'h4D;
461 2,3:O_TXD_DAT <= 8'h00;
462 4:O_TXD_DAT <= 8'h01;
463 8:begin
464 O_TXD_DAT <= 8'hFF;
465 conf_state<= 6;
466 end
467 default:O_TXD_DAT <= 8'hFF;
468 endcase
469 end
470 //-------- config_mode_exit (43): 01,43,00,00,00,00,00,00,00
471 // --,F3,5A,00,00,00,00,00,00
472 6:begin
473 case(I_BYTE_CNT)
474 0:O_TXD_DAT <= 8'h01;
475 1:O_TXD_DAT <= 8'h43;
476 2,3:O_TXD_DAT <= 8'h00;
477 8:begin
478 O_TXD_DAT <= 8'h00;
479 conf_state<= 7;
480 conf_entry<= 1'b0;
481 conf_done <= 1'b1;
482 end
483 default:O_TXD_DAT <= 8'h00;
484 endcase
485 end
486 default:;
487 endcase
488 end
489 end
490 end
491
492 endmodule
493
494 module ps_pls_gan(
495
496 I_CLK,
497 I_RSTn,
498 I_TYPE,
499
500 O_SCAN_SEQ_PLS,
501 O_RXWT,
502 O_TXWT,
503 O_TXSET,
504 O_TXEN,
505 O_psCLK,
506 O_psSEL,
507 O_byte_cnt,
508
509 Timer
510
511 );
512
513 parameter Timer_size = `Timer_siz;
514
515 input I_CLK,I_RSTn;
516 input I_TYPE;
517 output O_SCAN_SEQ_PLS;
518 output O_RXWT;
519 output O_TXWT;
520 output O_TXSET;
521 output O_TXEN;
522 output O_psCLK;
523 output O_psSEL;
524 output [3:0]O_byte_cnt;
525
526 output [Timer_size-1:0]Timer;
527 reg [Timer_size-1:0]Timer;
528
529 reg O_SCAN_SEQ_PLS;
530 reg RXWT;
531 reg TXWT;
532 reg TXSET;
533 reg psCLK_gate;
534 reg psSEL;
535 reg [3:0]O_byte_cnt;
536
537 always@(posedge I_CLK or negedge I_RSTn)
538 begin
539 if(! I_RSTn) Timer <= 0;
540 else Timer <= Timer+1;
541 end
542
543 always@(posedge I_CLK or negedge I_RSTn)
544 begin
545 if(! I_RSTn)
546 O_SCAN_SEQ_PLS <= 0;
547 else begin
548 if(Timer == 0) O_SCAN_SEQ_PLS <= 1;
549 else O_SCAN_SEQ_PLS <= 0;
550 end
551 end
552
553 always@(posedge I_CLK or negedge I_RSTn)
554 begin
555 if(! I_RSTn)
556 begin
557 psCLK_gate <= 1;
558 RXWT <= 0;
559 TXWT <= 0;
560 TXSET <= 0;
561 end
562 else begin
563 case(Timer[4:0])
564 6: TXSET <= 1;
565 8: TXSET <= 0;
566 9: TXWT <= 1;
567 11: TXWT <= 0;
568 12: psCLK_gate <= 0;
569 20: psCLK_gate <= 1;
570 21: RXWT <= 1;
571 23: RXWT <= 0;
572 default:;
573 endcase
574 end
575 end
576
577 always@(posedge I_CLK or negedge I_RSTn)
578 begin
579 if(! I_RSTn)
580 psSEL <= 1;
581 else begin
582 if(O_SCAN_SEQ_PLS == 1)
583 psSEL <= 0;
584 else if((I_TYPE == 0)&&(Timer == 158))
585 psSEL <= 1;
586 else if((I_TYPE == 1)&&(Timer == 286))
587 psSEL <= 1;
588 end
589 end
590
591 always@(posedge I_CLK or negedge I_RSTn)
592 begin
593 if(! I_RSTn)
594 O_byte_cnt <= 0;
595 else begin
596 if( O_SCAN_SEQ_PLS == 1)
597 O_byte_cnt <= 0;
598 else begin
599 if( Timer[4:0] == 5'b11111)begin
600 if(I_TYPE == 0 && O_byte_cnt == 5)
601 O_byte_cnt <= O_byte_cnt;
602 else if(I_TYPE == 1 && O_byte_cnt == 9)
603 O_byte_cnt <= O_byte_cnt;
604 else
605 O_byte_cnt <= O_byte_cnt+1;
606 end
607 end
608 end
609 end
610
611 assign O_psCLK = psCLK_gate | I_CLK | psSEL;
612 assign O_psSEL = psSEL;
613 assign O_RXWT = ~psSEL&RXWT;
614 assign O_TXSET = ~psSEL&TXSET;
615 assign O_TXWT = ~psSEL&TXWT;
616 assign O_TXEN = ~psSEL&(~psCLK_gate);
617
618 endmodule
619
620 module ps_rxd(
621
622 I_CLK,
623 I_RSTn,
624 I_WT,
625 I_psRXD,
626 O_RXD_DAT
627
628 );
629
630 input I_CLK,I_RSTn,I_WT;
631 input I_psRXD;
632 output [7:0]O_RXD_DAT;
633 reg [7:0]O_RXD_DAT;
634 reg [7:0]sp;
635
636 always@(posedge I_CLK or negedge I_RSTn)
637 if(! I_RSTn) sp <= 1;
638 else sp <= { I_psRXD, sp[7:1]};
639 always@(posedge I_WT or negedge I_RSTn)
640 if(! I_RSTn) O_RXD_DAT <= 1;
641 else O_RXD_DAT <= sp;
642
643 endmodule
644
645 module ps_txd(
646
647 I_CLK,
648 I_RSTn,
649 I_WT,
650 I_EN,
651 I_TXD_DAT,
652 O_psTXD
653
654 );
655
656 input I_CLK,I_RSTn;
657 input I_WT,I_EN;
658 input [7:0]I_TXD_DAT;
659 output O_psTXD;
660 reg O_psTXD;
661 reg [7:0]ps;
662
663 always@(negedge I_CLK or negedge I_RSTn)
664 begin
665 if(! I_RSTn)begin
666 O_psTXD <= 1;
667 ps <= 0;
668 end
669 else begin
670 if(I_WT)
671 ps <= I_TXD_DAT;
672 else begin
673 if(I_EN)begin
674 O_psTXD <= ps[0];
675 ps <= {1'b1, ps[7:1]};
676 end
677 else begin
678 O_psTXD <= 1'd1;
679 ps <= ps;
680 end
681 end
682 end
683 end
684
685 endmodule
Impressum, Datenschutz