NES(ファミコン)用のパッド IFの RTLコードです。
FPGAにでも使ってください。
PDSで
pin配置はこちらを参考に
■NES DEV controller port pin out
NES、ファミコン本体パッド P1、ファミコン本体外付けPADはpin配置が異なるだけで
同じ回路がつ変えます。
pad FPGA
GND <- 0V
- 5V <- +3.3V
CLK <- SCK_o
OUT <- XLATCH_o
D0 -> DAT_i
D4 ->N.C.
D3 -> N.C.
とりあえす REQ_i はHに釣ってください。
C_F_CKにはclock/CK_EE_iの周波数を設定してください。
1Mbpsに合わせます。
PADのICは3.0から8.0Vで動くので、FPGAのポート耐圧に合わせてください。
// NES_PAD_IF.v // NES_PAD_IF() // @manga_koji //2020-05-13we //K59sK1 :ok maybe... //K51xxx :1st `default_nettype none `include "../MISC/define.vh" module NES_PAD_IF #( `p C_DBG_ACC = 0 , `p C_F_CK = 135_000_000 )( `in `tri1 CK_i , `in `tri1 XARST_i , `in `tri1 CK_EE_i , `in `tri0 REQ_i //at level H , `in `tri1 DAT_i , `out `w XLATCH_o , `out `w SCK_o , `out `w A_o //H:push , `out `w B_o //H:push , `out `w SELECT_o //H:push , `out `w START_o //H:push , `out `w UP_o //H:push , `out `w DOWN_o //H:push , `out `w LEFT_o //H:push , `out `w RIGHT_o //H:push ) ; // log2() for calc bit width from data N // $clog2() is same constant function on Verilog 2001 `func `int log2 ; `in `int value ; `b value = value - 1 ; for(log2=0 ; value>0 ; log2=log2+1) value = value>>1 ; `e `efunc `lp C_F_PDIV_CK = (C_DBG_ACC)? C_F_CK/4 : 500_000 ; // mastar prescaler `lp C_PDIV_N = C_F_CK / C_F_PDIV_CK ; `int PCTRs ; `w PCTR_cy = &( PCTRs | (~(C_PDIV_N-1))) ; `r[7:0] REGs ; `r[4:0] PC ; `r XLATCH ; `r SCK ; `ack `xar `b PCTRs <= (C_PDIV_N-1) ; XLATCH <= 1'b1 ; SCK <= 1'b0 ; REGs <= ~0 ; PC<=0; `e else `cke `b PCTRs <= (PCTR_cy)? (C_PDIV_N-1) : (PCTRs + 1) ; if(PCTR_cy) `b PC <= PC + 1 ; case( PC ) 0: `b //Idle if( ~ REQ_i ) `b SCK <= 1'b0 ; XLATCH <= 1'b1 ; PC<=PC ; //PAUSE `e else `b SCK <= 1'b0 ; XLATCH <= 1'b0 ; PCTRs <= 0 ; PC <= 8 ; `e `e 8,10,12,14,16,18,20,22 : `b SCK <= 1'b0 ; REGs[{PC[3],~PC[2:1]}] <= ~ DAT_i ; PCTRs <= 0 ; `e 9,11,13,15,17,19,21: `b SCK <= 1'b1 ; PCTRs <= 0 ; `e 23: `b XLATCH <= 1'b1 ; PCTRs <= 0 ; PC <= 0 ; `e default : `b XLATCH <= 1'b1 ; SCK <= 1'b0 ; PC<=0; `e `ecase `e `e `a SCK_o = SCK ; `a XLATCH_o = XLATCH ; `a { A_o , B_o , SELECT_o , START_o , UP_o , DOWN_o , LEFT_o , RIGHT_o } = REGs ; endmodule
こちらはコマンド短縮用のマクロ。パスの通る場所においてください。
// ../MISC/define.vh //@manga_koji //2020-05-13we `define ack always@(posedge CK_i or negedge XARST_i) `define sck always@(posedge CK_i) `define xar if(~XARST_i) `define xsr if(~XSRST_i) `define cke if(CK_EE_i) `define b begin `define C begin `define e end `define J end `define D end `define a assign `define func function `define efunc endfunction `define s signed `define Ds $signed `define in input `define out output `define io inout `define w wire `define r reg `define int integer `define gen generate `define egen endgenerate `define gv genvar `define p parameter `define param parameter `define lp localparam `define pe posedge `define ne negedge `define rep repeat `define init initial `define al always `define elif else if `define ecase endcase `define emodule endmodule `ifdef TANG_FPGA `define tri0 wire `define tri1 wire `else `define tri0 tri0 `define tri1 tri1 `endif
enjoy! make ;-)