SNES(スーパーファミコン)用のパッド IFの RTLコードです。
FPGAにでも使ってください。
PDSで
先週のファミコンパッド記事は珍しくアクセスがあったので(ほんのちょっとですが)
今週はスーファミ編です。
pin配置はこちらを参考に
■SFC Development Wiki Controller : Controller Ports
SNES(スーパーファミコン)のパッドは、ファミコン同様電源GND+3本しか使ってません
なので、先週のファミコン用の回路を恐竜進化させるだけでOKでした。
Pin# pad FPGA
1 +5V <- +3.3V
2 clock <- SCK_o
3 Latch <- XLATCH_o
4 Data1 -> DAT_i
5 Data2 ->N.C.
6 IOBIt -> N.C.
7 GND <- 0V
丸い方が7pinとしています。
とりあえす REQ_i はHに釣ってください。
C_F_CKにはclock/CK_EE_iの周波数を設定してください。
1Mbpsに合わせます。
PADのICは前記は3.0から8.0Vで動きますが、
中期以降はミツミのV520Bというカスタム品に変わってて、電源保証囲が変わりませんが
とりあえず3.3Vでは動いてる様です。
ソースは以下。
// SNES_PAD_IF.v
// SNES_PAD_IF()
// @manga_koji
//
//K5OuK7 :start SNES_PAD_IF base on NES_PAD_IF
//K59sK1 :ok maye...
//K51xxx :1st
`default_nettype none
module SNES_PAD_IF
#(
parameter C_F_CK = 135_000_000
)(
input tri1 CK_i
, input tri1 XARST_i
, input tri1 CK_EE_i
, input tri0 REQ_i //at level H
, input tri1 DAT_i
, output wire XLATCH_o
, output wire SCK_o
, output wire B_o //H:push
, output wire Y_o
, output wire SELECT_o
, output wire START_o
, output wire UP_o
, output wire DOWN_o
, output wire LEFT_o
, output wire RIGHT_o
, output wire A_o
, output wire X_o
, output wire L_o
, output wire R_o
) ;
// log2() for calc bit width from data N
// constant function on Verilog 2001
function integer log2 ;
input integer value ;
begin value = value - 1 ;
for(log2=0 ; value>0 ; log2=log2+1)
value = value>>1 ;
end endfunction
localparam C_F_PDIV_CK = 500_000 ;
// mastar prescaler
localparam C_PDIV_N = C_F_CK / C_F_PDIV_CK ;
integer PCTRs ;
wire PCTR_cy = &( PCTRs | (~(C_PDIV_N-1))) ;
reg[11:0] REGs ;
reg[4:0] PC ;
reg XLATCH ;
reg SCK ;
always@(posedge CK_i or negedge XARST_i)
if(~XARST_i)
begin PCTRs <= (C_PDIV_N-1) ;
XLATCH <= 1'b1 ;
SCK <= 1'b0 ;
REGs <= ~0 ;
PC<=0;
end else if(CK_EE_i)
begin
PCTRs <= (PCTR_cy)? (C_PDIV_N-1) : (PCTRs + 1) ;
if(PCTR_cy)
begin
PC <= PC + 1 ;
case( PC )
0:
begin //Idle
if( ~ REQ_i )
begin SCK <= 1'b0 ;
XLATCH <= 1'b1 ;
PC<=PC ; //PAUSE
end else
begin SCK <= 1'b0 ;
XLATCH <= 1'b0 ;
PCTRs <= 0 ;
PC <= 8 ;
end
end
8,10,12,14,16,18,20,22,24,26,28,30 :
begin SCK <= 1'b0 ;
REGs[
{ ~PC[4] ^ PC[3]
, ~PC[3]
, PC[2:1]
}
] <= ~ DAT_i ;
PCTRs <= 0 ;
end
9,11,13,15,17,19,21,23,25,27,29:
begin SCK <= 1'b1 ;
PCTRs <= 0 ;
end
31: begin XLATCH <= 1'b1 ;
PCTRs <= 0 ;
PC <= 0 ;
end
default :
begin XLATCH <= 1'b1 ;
SCK <= 1'b0 ;
PC<=0;
end
endcase
end
end
assign SCK_o = SCK ;
assign XLATCH_o = XLATCH ;
assign {
R_o
, L_o
, X_o
, A_o
, RIGHT_o
, LEFT_o
, DOWN_o
, UP_o
, START_o
, SELECT_o
, Y_o
, B_o
} = REGs
;
endmodule
//SNES_PAD_IF()
enjoy! make ;-)