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