コントロールパネル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

戻る