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 ;-)