コントロールパネルHDLソース (Ver1.01 @ 2003.11.16 シンクロ連射機能を追加)
こんなプログラムに著作権を主張する気はありませんが、何かに流用するなら連絡をください。バージョンアップしたときに連絡するかもしれません。暇ができたら解説します。
機能
展望と課題
ss2pcb.v
// SEGA Suturn PAD -> PCB Control // Create by Mitsuhiro Fujita // Ver1.00 2003.11.06 // Ver1.01 2003.11.16 Rapid Fire mode added. // // SS connector // __________________________ // / \ // |_--_--_--_--_--_--_--_--_--_| // VDD D0 S0 D3 GND // D1 S1 VDD D2 module SS2PCB (CLK, VCLK, RESETZ, P1D0, P1D1, P1D2, P1D3, P2D0, P2D1, P2D2, P2D3, S0, S1, MODE0, MODE1, MODE2, CLKOUT1, CLKOUT2, LEDOUT, P1_UP, P1_DOWN, P1_LEFT, P1_RIGHT, P1_A, P1_B, P1_C, P1_X, P1_Y, P1_Z, P1_L, P1_R, P1_S, P2_UP, P2_DOWN, P2_LEFT, P2_RIGHT, P2_A, P2_B, P2_C, P2_X, P2_Y, P2_Z, P2_L, P2_R, P2_S); input CLK; // CLK input (port 87) input VCLK; input RESETZ; // ~RESET signal // {s0, s1} 00 01 10 11 input P1D0; // player 1 data 0 (Z, B, Up, 0) input P1D1; // player 1 data 1 (Y, C, Down, 0) input P1D2; // player 1 data 2 (X, A, Left, 1) input P1D3; // player 1 data 3 (R, S, Right, L) input P2D0; // player 2 data 0 (Z, B, Up, 0) input P2D1; // player 2 data 1 (Y, C, Down, 0) input P2D2; // player 2 data 2 (X, A, Left, 1) input P2D3; // player 2 data 3 (R, S, Right, L) output S0; // page addr 0 output S1; // page addr 1 output LEDOUT; // POWER LED output P1_UP; // player 1 up key output P1_DOWN; // player 1 down key output P1_LEFT; // player 1 left key output P1_RIGHT; // player 1 right key output P1_A; // player 1 A button output P1_B; // player 1 B button output P1_C; // player 1 C button output P1_X; // player 1 X button output P1_Y; // player 1 Y botton output P1_Z; // player 1 Z botton output P1_L; // player 1 L botton output P1_R; // player 1 R botton output P1_S; // player 1 Start botton output P2_UP; // player 2 Up key output P2_DOWN; // player 2 Down key output P2_LEFT; // player 2 Left key output P2_RIGHT; // player 2 Right key output P2_A; // player 2 A button output P2_B; // player 2 B button output P2_C; // player 2 C button output P2_X; // player 2 X button output P2_Y; // player 2 Y botton output P2_Z; // player 2 Z botton output P2_L; // player 2 L botton output P2_R; // player 2 R botton output P2_S; // player 2 Start botton output MODE0; // MODE LED out 0 output MODE1; // MODE LED out 1 output MODE2; // MODE LED out 2 output CLKOUT1; // SCLK OUT output CLKOUT2; // RCLK OUT // Pad signal wire p_P1_up, p_P1_down, p_P1_left, p_P1_right; wire p_P1_A, p_P1_B, p_P1_C; wire p_P1_X, p_P1_Y, p_P1_Z; wire p_P1_L, p_P1_R, p_P1_S; wire p_P2_up, p_P2_down, p_P2_left, p_P2_right; wire p_P2_A, p_P2_B, p_P2_C; wire p_P2_X, p_P2_Y, p_P2_Z; wire p_P2_L, p_P2_R, p_P2_S; wire p_S0, p_S1; wire p_MODE0, p_MODE1, p_MODE2; wire SLRCLK; assign LEDOUT = RESETZ ? 1'b0 : 1'bz; CLKDIV clkdiv (CLK, VCLK, SCLK, RCLK, RCLK2, RESETZ); MAKEADR makeadr (SCLK, p_S0, p_S1, RESETZ); MODE mode (p_P1_L, p_P2_L, RCLK, RCLK2, SLRCLK, p_MODE0, p_MODE1, p_MODE2, RESETZ); SIGDEC sigdec1 ( .s0(p_S0), .s1(p_S1), .d0(P1D0), .d1(P1D1), .d2(P1D2), .d3(P1D3), .mode0(p_MODE0), .mode1(p_MODE1), .mode2(p_MODE2), .SCLK(SCLK), .RCLK(SLRCLK), .o000(p_P1_Z), .o001(p_P1_Y), .o002(p_P1_X), .o003(p_P1_R), .o010(p_P1_B), .o011(p_P1_C), .o012(p_P1_A), .o013(p_P1_S), .o100(p_P1_up), .o101(p_P1_down), .o102(p_P1_left), .o103(p_P1_right), .o110(), .o111(), .o112(), .o113(p_P1_L)); SIGDEC sigdec2 ( .s0(p_S0), .s1(p_S1), .d0(P2D0), .d1(P2D1), .d2(P2D2), .d3(P2D3), .mode0(p_MODE0), .mode1(p_MODE1), .mode2(p_MODE2), .SCLK(SCLK), .RCLK(SLRCLK), .o000(p_P2_Z), .o001(p_P2_Y), .o002(p_P2_X), .o003(p_P2_R), .o010(p_P2_B), .o011(p_P2_C), .o012(p_P2_A), .o013(p_P2_S), .o100(p_P2_up), .o101(p_P2_down), .o102(p_P2_left), .o103(p_P2_right), .o110(), .o111(), .o112(), .o113(p_P2_L)); // output signal make assign S0 = p_S0; assign S1 = p_S1; assign P1_UP = p_P1_up ? 1'b0 : 1'bz; assign P1_DOWN = p_P1_down ? 1'b0 : 1'bz; assign P1_LEFT = p_P1_left ? 1'b0 : 1'bz; assign P1_RIGHT = p_P1_right ? 1'b0 : 1'bz; assign P2_UP = p_P2_up ? 1'b0 : 1'bz; assign P2_DOWN = p_P2_down ? 1'b0 : 1'bz; assign P2_LEFT = p_P2_left ? 1'b0 : 1'bz; assign P2_RIGHT = p_P2_right ? 1'b0 : 1'bz; assign P1_A = p_P1_A ? 1'b0 : 1'bz; assign P1_B = p_P1_B ? 1'b0 : 1'bz; assign P1_C = p_P1_C ? 1'b0 : 1'bz; assign P1_X = p_P1_X ? 1'b0 : 1'bz; assign P1_Y = p_P1_Y ? 1'b0 : 1'bz; assign P1_Z = p_P1_Z ? 1'b0 : 1'bz; assign P1_L = p_P1_L ? 1'b0 : 1'bz; assign P1_R = p_P1_R ? 1'b0 : 1'bz; assign P1_S = p_P1_S ? 1'b0 : 1'bz; assign P2_A = p_P2_A ? 1'b0 : 1'bz; assign P2_B = p_P2_B ? 1'b0 : 1'bz; assign P2_C = p_P2_C ? 1'b0 : 1'bz; assign P2_X = p_P2_X ? 1'b0 : 1'bz; assign P2_Y = p_P2_Y ? 1'b0 : 1'bz; assign P2_Z = p_P2_Z ? 1'b0 : 1'bz; assign P2_L = p_P2_L ? 1'b0 : 1'bz; assign P2_R = p_P2_R ? 1'b0 : 1'bz; assign P2_S = p_P2_S ? 1'b0 : 1'bz; assign CLKOUT1 = SCLK; assign CLKOUT2 = RCLK; assign MODE0 = p_MODE0 ? 1'b0 : 1'bz; assign MODE1 = (p_MODE1 & SLRCLK) ? 1'b0 : 1'bz; assign MODE2 = (p_MODE2 & SLRCLK) ? 1'b0 : 1'bz; endmodule module CLKDIV (CLK, VCLK, SCLK, RCLK, RCLK2, RESETZ); // clock divider // __ __ __ __ __ __ // _| |_| |_| |_| |_| |_| |_ source clk (1kHz) // // ____ ____ ____ // _| |____| |____| |____ addr clk (250Hz) Fxx/2 // // ____ _____ _____ ____ _ // |_| |_| |_| |_| Virtical Sync Clock (60Hz) // _______ ______ // ____| |_______| |___ Rapid Fire clock (30Hz VCLK/2) // _______________ // ____| |__________ Rapid Fire clock 2 (15Hz VCLK/4) input CLK; // Base clock input VCLK; output SCLK; // addr clock output RCLK; // rapid fire clock output RCLK2; input RESETZ; // RESET SIGNAL reg [15:0] div1; // addr clk making // reg [5:0] div2; // Rapid clk making reg [5:0] div3; // Rapid clk making reg SCLK; // addr clock reg reg RCLK; // rapid clock reg reg RCLK2; // rapid clock reg always @(posedge CLK or negedge RESETZ) if (~RESETZ) begin div1 <= 16'h0000; SCLK <= 1'b0; end else if (div1==16'h0001) begin div1 <= 16'h0000; SCLK <= ~SCLK; end else begin div1 <= div1 + 16'h0001; end always @(posedge VCLK or negedge RESETZ) if (~RESETZ) RCLK <= 1'b0; else RCLK <= ~RCLK; always @(posedge VCLK or negedge RESETZ) if (~RESETZ) begin div3 <= 6'b000000; RCLK2 <= 1'b0; end else if (div3==6'b000001) begin div3 <= 6'b000000; RCLK2 <= ~RCLK2; end else begin div3 <= div3 + 6'b000001; end endmodule module MAKEADR ( SCLK, p_S0, p_S1, RESETZ ); // page address maker // _ _ _ _ _ // SCLK _| |______| |______| |______| |______| |_ // _________________ // S0 ___________| |____________ // _________________ // S1 ____________________| |___ // <--00--> <--10--> <--11--> <--01--> input SCLK; // Clock output p_S0; // page addr 0 output p_S1; // page addr 1 input RESETZ; // RESET SIGNAL reg p_S0; // register for S0 reg p_S1; // register for S1 always @(posedge SCLK or negedge RESETZ) if (~RESETZ) {p_S0, p_S1} <= 2'b00; else {p_S0, p_S1} <= {p_S0, p_S1} + 2'b1; endmodule module SIGDEC ( s0, s1, d0, d1, d2, d3, mode0, mode1, mode2, SCLK, RCLK, o000, o001, o002, o003, o010, o011, o012, o013, o100, o101, o102, o103, o110, o111, o112, o113); // create PAD signal input s0; // page addr 0 input s1; // page addr 1 input d0; // data input 0 input d1; // data input 0 input d2; // data input 0 input d3; // data input 0 input mode0; // mode 0 input mode1; // mode 1 input mode2; // mode 2 input SCLK; // addr clock input RCLK; // Rapid fire clock output o000; // Z out output o001; // Y out output o002; // X out output o003; // R out output o010; // B out output o011; // C out output o012; // A out output o013; // S out output o100; // up out output o101; // down out output o102; // left out output o103; // right out output o110; // nc output o111; // nc output o112; // nc output o113; // L out reg [3:0] keybuf00; // key buffer 0 reg [3:0] keybuf01; // key buffer 1 reg [3:0] keybuf11; // key buffer 2 reg [3:0] keybuf10; // key buffer 3 wire [3:0] din = {d3, d2, d1 ,d0}; always @(posedge SCLK) case ({s0, s1}) 2'b11: keybuf00 <= din; 2'b10: keybuf01 <= din; 2'b01: keybuf10 <= din; 2'b00: keybuf11 <= din; endcase wire rZ = keybuf00[0] | RCLK; // rapid Z wire rY = keybuf00[1] | RCLK; // rapid Y wire rX = keybuf00[2] | RCLK; // rapid X wire p_rB = keybuf01[0] | RCLK; // rapid B wire p_rC = keybuf01[1] | RCLK; // rapid C wire p_rA = keybuf01[2] | RCLK; // rapid A wire rB = p_rB & (mode1 ? keybuf00[1] : 1'b1); wire rC = p_rC & (mode1 ? keybuf00[0] : 1'b1); wire rA = p_rA & (mode1 ? keybuf00[2] : 1'b1); assign o000 = mode0 ? keybuf00[0] : rZ; // Z out assign o001 = mode0 ? keybuf00[1] : rY; // Y out assign o002 = mode0 ? keybuf00[2] : rX; // X out assign o003 = keybuf00[3]; // R out assign o010 = mode0 ? keybuf01[0] : rB; // B out assign o011 = mode0 ? keybuf01[1] : rC; // C out assign o012 = mode0 ? keybuf01[2] : rA; // A out assign o013 = keybuf01[3]; // S out assign o100 = keybuf10[0]; // up out assign o101 = keybuf10[1]; // down out assign o102 = keybuf10[2]; // left out assign o103 = keybuf10[3]; // right out assign o110 = keybuf11[0]; // nc assign o111 = keybuf11[1]; // nc assign o112 = keybuf11[2]; // nc assign o113 = keybuf11[3]; // L out endmodule module MODE (p_P1_L, p_P2_L, RCLK, RCLK2, SLRCLK, p_MODE0, p_MODE1, p_MODE2, RESETZ); input p_P1_L; // player 1 L input p_P2_L; // player 2 L input RCLK; // Rapid fire clock (25Hz) input RCLK2; // Rapid fire clock (25Hz) output SLRCLK; output p_MODE0; // mode 0 output output p_MODE1; // mode 1 output output p_MODE2; // mode 2 output input RESETZ; // reset reg [7:0] nfilter; // noise filter reg p_MODE0; // mode 0 reg reg MODE1; // mode 1 reg reg MODE2; // mode 2 reg reg MODE1B; reg MODE2B; wire P12_L = p_P1_L & p_P2_L; // player 1 & 2 L always @(posedge RCLK or negedge RESETZ) if (~RESETZ) nfilter <= 8'hff; else nfilter <= {nfilter[6:0], P12_L}; wire msel = nfilter[6] | nfilter[5] |nfilter[4] |nfilter[3] |nfilter[2] | nfilter[1] |nfilter[0]; always @(posedge P12_L or negedge RESETZ) if (~RESETZ) {p_MODE0, MODE1, MODE1B, MODE2, MODE2B} <= 5'b10000; else {p_MODE0, MODE1, MODE1B, MODE2, MODE2B} <= {MODE2B, p_MODE0, MODE1, MODE1B, MODE2}; assign SLRCLK = (MODE1B | MODE2B) ? RCLK2 : RCLK; assign p_MODE1 = MODE1 | MODE1B; assign p_MODE2 = MODE2 | MODE2B; endmodule |