diff --git a/verilog/sd2snes/address.v b/verilog/sd2snes/address.v index 8433089..b53624d 100644 --- a/verilog/sd2snes/address.v +++ b/verilog/sd2snes/address.v @@ -23,16 +23,14 @@ module address( input [2:0] MAPPER, // MCU detected mapper input [23:0] SNES_ADDR, // requested address from SNES input SNES_CS, // "CART" pin from SNES (active low) - output [22:0] ROM_ADDR, // Address to request from SRAM0 + output [23:0] ROM_ADDR, // Address to request from SRAM0 output ROM_SEL, // enable SRAM0 (active low) input MCU_OVR, // enable MCU master mode (active low) - input MODE, // MCU(1) or SNES(0) ("bus phase") output IS_SAVERAM, // address/CS mapped as SRAM? output IS_ROM, // address mapped as ROM? output IS_WRITABLE, // address somehow mapped as writable area? input [23:0] MCU_ADDR, // allow address to be set externally input ADDR_WRITE, - output ROM_ADDR0, input [23:0] SAVERAM_MASK, input [23:0] ROM_MASK, input use_msu, @@ -54,7 +52,7 @@ parameter [2:0] wire [1:0] SRAM_BANK; -wire [23:0] SRAM_ADDR_FULL; +wire [23:0] SRAM_SNES_ADDR; /* currently supported mappers: Index Mapper @@ -101,6 +99,7 @@ assign IS_SAVERAM = SAVERAM_MASK[0] : 1'b0)); +/* BS-X has 4 MBits of extra RAM that can be mapped to various places */ assign IS_WRITABLE = IS_SAVERAM |((MAPPER == 3'b011) ?((bsx_regs[3] && SNES_ADDR[23:20]==4'b0110) @@ -123,8 +122,7 @@ assign IS_WRITABLE = IS_SAVERAM 8 1=map BSX cartridge ROM @80-9f:8000-ffff */ -assign SRAM_ADDR_FULL = (MODE) ? MCU_ADDR - :((MAPPER == 3'b000) +assign SRAM_SNES_ADDR = ((MAPPER == 3'b000) ?(IS_SAVERAM ? 24'hE00000 + ((SNES_ADDR[14:0] - 15'h6000) & SAVERAM_MASK) @@ -188,12 +186,10 @@ assign SRAM_ADDR_FULL = (MODE) ? MCU_ADDR ) : 24'b0); -assign ROM_ADDR = SRAM_ADDR_FULL[23:1]; +assign ROM_ADDR = SRAM_SNES_ADDR; assign ROM_SEL = 1'b0; // (MODE) ? CS_ARRAY[SRAM_BANK] : IS_SAVERAM ? 4'b1000 : CS_ARRAY[SRAM_BANK]; -assign ROM_ADDR0 = SRAM_ADDR_FULL[0]; - assign msu_enable_w = featurebits[FEAT_MSU1] & (!SNES_ADDR[22] && ((SNES_ADDR[15:0] & 16'hfff8) == 16'h2000)); reg [7:0] msu_enable_r; initial msu_enable_r = 8'b00000000; diff --git a/verilog/sd2snes/data.v b/verilog/sd2snes/data.v index a1c72c0..2c10fda 100644 --- a/verilog/sd2snes/data.v +++ b/verilog/sd2snes/data.v @@ -22,6 +22,7 @@ module data( input CLK, input SNES_READ, input SNES_WRITE, + input ROM_WE, input MCU_READ, input MCU_WRITE, inout [7:0] SNES_DATA, @@ -80,7 +81,7 @@ assign MCU_OUT_DATA = !MCU_OVR ? (FROM_ROM_BYTE) assign ROM_DATA[7:0] = ROM_ADDR0 ?(!MCU_OVR ? (!MCU_WRITE ? MCU_IN_DATA : 8'bZ) : (MODE ? (!MCU_WRITE ? MCU_IN_MEM : 8'bZ) - : (!SNES_WRITE ? SNES_IN_MEM : 8'bZ) + : (!ROM_WE ? SNES_IN_MEM : 8'bZ) ) ) :8'bZ; @@ -88,7 +89,7 @@ assign ROM_DATA[7:0] = ROM_ADDR0 assign ROM_DATA[15:8] = ROM_ADDR0 ? 8'bZ :(!MCU_OVR ? (!MCU_WRITE ? MCU_IN_DATA : 8'bZ) : (MODE ? (!MCU_WRITE ? MCU_IN_MEM : 8'bZ) - : (!SNES_WRITE ? SNES_IN_MEM : 8'bZ) + : (!ROM_WE ? SNES_IN_MEM : 8'bZ) ) ); diff --git a/verilog/sd2snes/dcm.v b/verilog/sd2snes/dcm.v index 36a2409..90b516e 100644 --- a/verilog/sd2snes/dcm.v +++ b/verilog/sd2snes/dcm.v @@ -37,7 +37,7 @@ module my_dcm ( .CLKFX_DIVIDE(1), // Can be any integer from 1 to 32 .CLKFX_MULTIPLY(4), // Can be any integer from 2 to 32 .CLKIN_DIVIDE_BY_2("FALSE"), // TRUE/FALSE to enable CLKIN divide by two feature - .CLKIN_PERIOD(43.478), // Specify period of input clock + .CLKIN_PERIOD(41.667), // Specify period of input clock .CLKOUT_PHASE_SHIFT("NONE"), // Specify phase shift of NONE, FIXED or VARIABLE .CLK_FEEDBACK("NONE"), // Specify clock feedback of NONE, 1X or 2X .DESKEW_ADJUST("SYSTEM_SYNCHRONOUS"), // SOURCE_SYNCHRONOUS, SYSTEM_SYNCHRONOUS or diff --git a/verilog/sd2snes/main.ucf b/verilog/sd2snes/main.ucf index 02fa246..8ec5c4d 100644 --- a/verilog/sd2snes/main.ucf +++ b/verilog/sd2snes/main.ucf @@ -76,6 +76,10 @@ NET "MCU_OVR" LOC = P92; NET "MCU_OVR" IOSTANDARD = LVCMOS33; NET "MCU_OVR" DRIVE = 8; +NET "MCU_RDY" LOC = P83; +NET "MCU_RDY" IOSTANDARD = LVCMOS33; +NET "MCU_RDY" DRIVE = 8; + NET "ROM_ADDR[0]" LOC = P166; @@ -517,4 +521,4 @@ NET "SD_DAT[2]" IOSTANDARD = LVCMOS33; NET "SD_DAT[3]" IOSTANDARD = LVCMOS33; NET "SNES_SYSCLK" LOC = P180; -NET "SNES_SYSCLK" IOSTANDARD = LVCMOS33; \ No newline at end of file +NET "SNES_SYSCLK" IOSTANDARD = LVCMOS33; diff --git a/verilog/sd2snes/main.v b/verilog/sd2snes/main.v index 045e87e..66bdb41 100644 --- a/verilog/sd2snes/main.v +++ b/verilog/sd2snes/main.v @@ -59,7 +59,8 @@ module main( input SPI_SS, inout SPI_SCK, input MCU_OVR, - + output MCU_RDY, + output DAC_MCLK, output DAC_LRCK, output DAC_SDOUT, @@ -67,14 +68,12 @@ module main( /* SD signals */ input [3:0] SD_DAT, inout SD_CMD, - inout SD_CLK + inout SD_CLK, /* debug */ - , output p113_out ); wire dspx_dp_enable; -assign p113_out = dspx_dp_enable; wire [7:0] spi_cmd_data; wire [7:0] spi_param_data; @@ -84,8 +83,6 @@ wire [2:0] spi_bit_cnt; wire [23:0] MCU_ADDR; wire [7:0] mcu_data_in; wire [7:0] mcu_data_out; -wire [7:0] MCU_IN_DATA; -wire [7:0] MCU_OUT_DATA; wire [3:0] MAPPER; wire [23:0] SAVERAM_MASK; wire [23:0] ROM_MASK; @@ -132,6 +129,11 @@ wire [10:0] dspx_dat_addr; wire dspx_dat_we; wire [7:0] featurebits; + +wire [23:0] MAPPED_SNES_ADDR; +wire ROM_ADDR0; +wire [22:0] MAPPED_SNES_ADDR2 = MAPPED_SNES_ADDR[23:1]; + //wire SD_DMA_EN; //SPI_DMA_CTRL; sd_dma snes_sd_dma( @@ -265,6 +267,9 @@ upd77c25 snes_dspx ( .DP_ADDR(SNES_ADDR[10:0]) ); +reg [7:0] MCU_DINr; +wire [7:0] MCU_DOUT; + mcu_cmd snes_mcu_cmd( .clk(CLK2), .snes_sysclk(SNES_SYSCLK), @@ -274,10 +279,10 @@ mcu_cmd snes_mcu_cmd( .param_data(spi_param_data), .mcu_mapper(MAPPER), .mcu_sram_size(SRAM_SIZE), - .mcu_read(MCU_READ), +// .mcu_read(MCU_READ), .mcu_write(MCU_WRITE), - .mcu_data_in(MCU_OUT_DATA), - .mcu_data_out(MCU_IN_DATA), + .mcu_data_in(MCU_DINr), + .mcu_data_out(MCU_DOUT), .spi_byte_cnt(spi_byte_cnt), .spi_bit_cnt(spi_bit_cnt), .spi_data_out(spi_input_data), @@ -324,7 +329,10 @@ mcu_cmd snes_mcu_cmd( .dspx_dat_addr_out(dspx_dat_addr), .dspx_dat_we_out(dspx_dat_we), .dspx_reset_out(dspx_reset), - .featurebits_out(featurebits) + .featurebits_out(featurebits), + .mcu_rrq(MCU_RRQ), + .mcu_wrq(MCU_WRQ), + .mcu_rq_rdy(MCU_RDY) ); // dcm1: dfs 4x @@ -338,37 +346,27 @@ my_dcm snes_dcm( assign DCM_RST=0; -wire SNES_RW; -reg [1:0] SNES_READr; -reg [1:0] SNES_WRITEr; -reg [1:0] SNES_CSr; -reg [5:0] SNES_CPU_CLKr; +reg [5:0] SNES_READr; +reg [5:0] SNES_WRITEr; +reg [12:0] SNES_CPU_CLKr; reg [5:0] SNES_RWr; reg [23:0] SNES_ADDRr; -reg [23:0] SNES_ADDR_PREVr; -reg [3:0] SNES_ADDRCHGr; -wire SNES_READs = (SNES_READr == 2'b11); -wire SNES_WRITEs = (SNES_WRITEr == 2'b11); -wire SNES_CSs = (SNES_CSr == 2'b11); -wire SNES_CPU_CLKs = SNES_CPU_CLK; // (SNES_CPU_CLKr == 2'b11); +wire SNES_RW = (SNES_READ & SNES_WRITE); + wire SNES_RW_start = (SNES_RWr == 6'b111110); // falling edge marks beginning of cycle -wire SNES_cycle_start = (SNES_CPU_CLKr == 6'b000011); -wire SNES_ADDRCHG = (SNES_ADDRr != SNES_ADDR_PREVr); -wire SNES_addr_start = (SNES_ADDRCHGr[0] == 1'b1); - -assign SNES_RW = (SNES_READ & SNES_WRITE); +wire SNES_RD_start = (SNES_READr == 6'b111110); +wire SNES_WR_start = (SNES_WRITEr == 6'b111110); +wire SNES_cycle_start = (SNES_CPU_CLKr[5:0] == 6'b000001); +wire SNES_cycle_end = (SNES_CPU_CLKr[5:0] == 6'b111110); always @(posedge CLK2) begin - SNES_READr <= {SNES_READr[0], SNES_READ}; - SNES_WRITEr <= {SNES_WRITEr[0], SNES_WRITE}; - SNES_CSr <= {SNES_CSr[0], SNES_CS}; - SNES_CPU_CLKr <= {SNES_CPU_CLKr[4:0], SNES_CPU_CLK}; + SNES_READr <= {SNES_READr[4:0], SNES_READ}; + SNES_WRITEr <= {SNES_WRITEr[4:0], SNES_WRITE}; + SNES_CPU_CLKr <= {SNES_CPU_CLKr[11:0], SNES_CPU_CLK}; SNES_RWr <= {SNES_RWr[4:0], SNES_RW}; end -reg ADDR_WRITE; - wire ROM_SEL; address snes_addr( @@ -377,15 +375,13 @@ address snes_addr( .featurebits(featurebits), .SNES_ADDR(SNES_ADDR), // requested address from SNES .SNES_CS(SNES_CS), // "CART" pin from SNES (active low) - .ROM_ADDR(ROM_ADDR), // Address to request from SRAM (active low) + .ROM_ADDR(MAPPED_SNES_ADDR), // Address to request from SRAM (active low) .ROM_SEL(ROM_SEL), // which SRAM unit to access .MCU_OVR(MCU_OVR), // enable MCU mode (active low) - .MODE(MODE), // MCU(1) or SNES(0) ("bus phase") .IS_SAVERAM(IS_SAVERAM), .IS_ROM(IS_ROM), .IS_WRITABLE(IS_WRITABLE), .MCU_ADDR(MCU_ADDR), - .ROM_ADDR0(ROM_ADDR0), .SAVERAM_MASK(SAVERAM_MASK), .ROM_MASK(ROM_MASK), //MSU-1 @@ -407,73 +403,40 @@ wire SNES_WRITE_CYCLEw; wire MCU_READ_CYCLEw; wire MCU_WRITE_CYCLEw; -data snes_data( - .CLK(CLK2), - .SNES_READ(SNES_READ), - .SNES_WRITE(SNES_WRITE), - .MCU_READ(MCU_READ), - .MCU_WRITE(MCU_WRITE), - .SNES_DATA(SNES_DATA), - .ROM_DATA(ROM_DATA), - .MODE(MODE), - .SNES_DATA_TO_MEM(SNES_DATA_TO_MEM), - .MCU_DATA_TO_MEM(MCU_DATA_TO_MEM), - .ROM_DATA_TO_SNES_MEM(ROM_DATA_TO_SNES_MEM), - .ROM_DATA_TO_MCU_MEM(ROM_DATA_TO_MCU_MEM), - .MCU_OVR(MCU_OVR), - .MCU_IN_DATA(MCU_IN_DATA), - .MCU_OUT_DATA(MCU_OUT_DATA), - .ROM_ADDR0(ROM_ADDR0), - .MSU_DATA_IN(MSU_SNES_DATA_IN), - .MSU_DATA_OUT(MSU_SNES_DATA_OUT), - .BSX_DATA_IN(BSX_SNES_DATA_IN), - .BSX_DATA_OUT(BSX_SNES_DATA_OUT), - .SRTC_DATA_IN(SRTC_SNES_DATA_IN), - .SRTC_DATA_OUT(SRTC_SNES_DATA_OUT), - .DSPX_DATA_IN(DSPX_SNES_DATA_IN), - .DSPX_DATA_OUT(DSPX_SNES_DATA_OUT), - .msu_enable(msu_enable), - .bsx_data_ovr(bsx_data_ovr), - .srtc_enable(srtc_enable), - .dspx_enable(dspx_enable), - .dspx_dp_enable(dspx_dp_enable) -); - parameter MODE_SNES = 1'b0; parameter MODE_MCU = 1'b1; -parameter STATE_0 = 14'b00000000000001; -parameter STATE_1 = 14'b00000000000010; -parameter STATE_2 = 14'b00000000000100; -parameter STATE_3 = 14'b00000000001000; -parameter STATE_4 = 14'b00000000010000; -parameter STATE_5 = 14'b00000000100000; -parameter STATE_6 = 14'b00000001000000; -parameter STATE_7 = 14'b00000010000000; -parameter STATE_8 = 14'b00000100000000; -parameter STATE_9 = 14'b00001000000000; -parameter STATE_10 = 14'b00010000000000; -parameter STATE_11 = 14'b00100000000000; -parameter STATE_12 = 14'b01000000000000; -parameter STATE_IDLE = 14'b10000000000000; +parameter ST_IDLE = 18'b000000000000000001; +parameter ST_SNES_RD_ADDR = 18'b000000000000000010; +parameter ST_SNES_RD_WAIT = 18'b000000000000000100; +parameter ST_SNES_RD_END = 18'b000000000000001000; +parameter ST_SNES_WR_ADDR = 18'b000000000000010000; +parameter ST_SNES_WR_WAIT1= 18'b000000000000100000; +parameter ST_SNES_WR_DATA = 18'b000000000001000000; +parameter ST_SNES_WR_WAIT2= 18'b000000000010000000; +parameter ST_SNES_WR_END = 18'b000000000100000000; +parameter ST_MCU_RD_ADDR = 18'b000000001000000000; +parameter ST_MCU_RD_WAIT = 18'b000000010000000000; +parameter ST_MCU_RD_WAIT2 = 18'b000000100000000000; +parameter ST_MCU_RD_END = 18'b000001000000000000; +parameter ST_MCU_WR_ADDR = 18'b000010000000000000; +parameter ST_MCU_WR_WAIT = 18'b000100000000000000; +parameter ST_MCU_WR_WAIT2 = 18'b001000000000000000; +parameter ST_MCU_WR_END = 18'b010000000000000000; -reg [13:0] STATE; +parameter ROM_RD_WAIT = 4'h4; +parameter ROM_RD_WAIT_MCU = 4'h5; +parameter ROM_WR_WAIT1 = 4'h2; +parameter ROM_WR_WAIT2 = 4'h3; +parameter ROM_WR_WAIT_MCU = 4'h6; + +reg [17:0] STATE; reg [3:0] STATEIDX; reg [1:0] CYCLE_RESET; reg ROM_WE_MASK; reg ROM_OE_MASK; -reg [13:0] ROM_WE_ARRAY [3:0]; -reg [13:0] ROM_OE_ARRAY [3:0]; - -reg [13:0] SNES_DATA_TO_MEM_ARRAY[1:0]; -reg [13:0] MCU_DATA_TO_MEM_ARRAY[1:0]; -reg [13:0] ROM_DATA_TO_SNES_MEM_ARRAY[1:0]; -reg [13:0] ROM_DATA_TO_MCU_MEM_ARRAY[1:0]; - -reg [13:0] MODE_ARRAY; - reg SNES_READ_CYCLE; reg SNES_WRITE_CYCLE; reg MCU_READ_CYCLE; @@ -489,11 +452,9 @@ reg [3:0] MAPPER_BUF; reg SNES_DATABUS_OE_BUF; reg SNES_DATABUS_DIR_BUF; -assign MODE = !MCU_OVR ? MODE_MCU : MODE_ARRAY[STATEIDX]; - initial begin CYCLE_RESET = 2'b0; - STATE = STATE_IDLE; + STATE = ST_IDLE; STATEIDX = 13; ROM_WE_MASK = 1'b1; ROM_OE_MASK = 1'b1; @@ -501,30 +462,6 @@ initial begin SNES_WRITE_CYCLE = 1'b1; MCU_READ_CYCLE = 1'b1; MCU_WRITE_CYCLE = 1'b1; - MODE_ARRAY = 14'b0_000000_1111111; - - ROM_WE_ARRAY[2'b00] = 14'b1_000000_0000000; - ROM_WE_ARRAY[2'b01] = 14'b1_000000_1111111; - ROM_WE_ARRAY[2'b10] = 14'b1_111111_0000000; - ROM_WE_ARRAY[2'b11] = 14'b1_111111_1111111; - - ROM_OE_ARRAY[2'b00] = 14'b1_111111_1111111; - ROM_OE_ARRAY[2'b01] = 14'b1_111111_0000000; - ROM_OE_ARRAY[2'b10] = 14'b0_000000_1111111; - ROM_OE_ARRAY[2'b11] = 14'b0_000000_0000000; - - SNES_DATA_TO_MEM_ARRAY[1'b0] = 14'b0_000100_0000000; // SNES write - SNES_DATA_TO_MEM_ARRAY[1'b1] = 14'b0_000000_0000000; // SNES read - - MCU_DATA_TO_MEM_ARRAY[1'b0] = 14'b1_111111_1111111; // MCU write - MCU_DATA_TO_MEM_ARRAY[1'b1] = 14'b0_000000_0000000; // MCU read - - ROM_DATA_TO_SNES_MEM_ARRAY[1'b0] = 14'b0_000000_0000000; // SNES write - ROM_DATA_TO_SNES_MEM_ARRAY[1'b1] = 14'b0_000010_0000000; // SNES read - - ROM_DATA_TO_MCU_MEM_ARRAY[1'b0] = 14'b0_000000_0000000; // MCU write - ROM_DATA_TO_MCU_MEM_ARRAY[1'b1] = 14'b0_000000_0000001; // MCU read - end // falling edge of SNES /RD or /WR marks the beginning of a new cycle @@ -533,100 +470,207 @@ end // the minimum of 6 SNES cycles to get everything done. // we have 24 internal cycles to work with. (CLKIN * 4) +assign DSPX_SNES_DATA_IN = SNES_DATA; +assign SRTC_SNES_DATA_IN = SNES_DATA; +assign MSU_SNES_DATA_IN = SNES_DATA; +assign BSX_SNES_DATA_IN = SNES_DATA; + +reg [7:0] SNES_DINr; +reg [7:0] ROM_DOUTr; + +assign SNES_DATA = (!SNES_READ) ? (srtc_enable ? SRTC_SNES_DATA_OUT + :dspx_enable ? DSPX_SNES_DATA_OUT + :dspx_dp_enable ? DSPX_SNES_DATA_OUT + :msu_enable ? MSU_SNES_DATA_OUT + :bsx_data_ovr ? BSX_SNES_DATA_OUT + :SNES_DINr /*(ROM_ADDR0 ? ROM_DATA[7:0] : ROM_DATA[15:8])*/) : 8'bZ; + +reg [3:0] ST_MEM_DELAYr; +reg MCU_RD_PENDr; +reg MCU_WR_PENDr; +reg [23:0] ROM_ADDRr; +reg NEED_SNES_ADDRr; always @(posedge CLK2) begin - CYCLE_RESET <= {CYCLE_RESET[0], SNES_cycle_start}; + if(SNES_cycle_end) NEED_SNES_ADDRr <= 1'b1; + else if(STATE & (ST_SNES_RD_END | ST_SNES_WR_END)) NEED_SNES_ADDRr <= 1'b0; end -reg[7:0] STATECNT; -initial STATECNT = 0; +wire ASSERT_SNES_ADDR = SNES_CPU_CLK & NEED_SNES_ADDRr; + +assign ROM_ADDR = (!MCU_OVR) ? MCU_ADDR[23:1] : (ASSERT_SNES_ADDR) ? MAPPED_SNES_ADDR[23:1] : ROM_ADDRr[23:1]; +assign ROM_ADDR0 = (!MCU_OVR) ? MCU_ADDR[0] : (ASSERT_SNES_ADDR) ? MAPPED_SNES_ADDR[0] : ROM_ADDRr[0]; + +reg ROM_WEr; +initial ROM_WEr = 1'b1; + +reg RQ_MCU_RDYr; +initial RQ_MCU_RDYr = 1'b1; +assign MCU_RDY = RQ_MCU_RDYr; always @(posedge CLK2) begin - MCU_READ_CYCLE <= MCU_READ; - MCU_WRITE_CYCLE <= MCU_WRITE; - if (SNES_cycle_start) begin - SNES_READ_CYCLE <= SNES_READ; - SNES_WRITE_CYCLE <= SNES_WRITE; - STATE <= STATE_0; - STATEIDX <= 12; - STATECNT <= 0; - end else begin - STATECNT <= STATECNT + 1; - case (STATE) - STATE_0: begin - SNES_WRITE_CYCLE <= SNES_WRITE; - STATE <= STATE_1; STATEIDX <= 11; - end - STATE_1: begin - STATE <= STATE_2; STATEIDX <= 10; - end - STATE_2: begin - STATE <= STATE_3; STATEIDX <= 9; - end - STATE_3: begin - STATE <= STATE_4; STATEIDX <= 8; - end - STATE_4: begin - STATE <= STATE_5; STATEIDX <= 7; - end - STATE_5: begin - STATE <= STATE_6; STATEIDX <= 6; - end - STATE_6: begin - STATE <= STATE_7; STATEIDX <= 5; - end - STATE_7: begin - STATE <= STATE_8; STATEIDX <= 4; - end - STATE_8: begin - STATE <= STATE_9; STATEIDX <= 3; - end - STATE_9: begin - STATE <= STATE_10; STATEIDX <= 2; - end - STATE_10: begin - STATE <= STATE_11; STATEIDX <= 1; - end - STATE_11: begin - STATE <= STATE_12; STATEIDX <= 0; - end - STATE_12: begin - STATE <= STATE_IDLE; STATEIDX <= 13; - end - STATE_IDLE: begin - STATE <= STATE_IDLE; STATEIDX <= 13; - end - default: begin - STATE <= STATE_IDLE; STATEIDX <= 13; - end - endcase + if(MCU_RRQ) begin + MCU_RD_PENDr <= 1'b1; + RQ_MCU_RDYr <= 1'b0; + end else if(MCU_WRQ) begin + MCU_WR_PENDr <= 1'b1; + RQ_MCU_RDYr <= 1'b0; + end else if(STATE & (ST_MCU_RD_END | ST_MCU_WR_END)) begin + MCU_RD_PENDr <= 1'b0; + MCU_WR_PENDr <= 1'b0; + RQ_MCU_RDYr <= 1'b1; end end +reg [23:0] SNES_ADDRsr[1:0]; +always @(posedge CLK2) begin + SNES_ADDRsr[0] <= SNES_ADDR; + SNES_ADDRsr[1] <= SNES_ADDRsr[0]; +end +wire SNES_ADDRchg = (SNES_ADDRsr[0] != SNES_ADDRsr[1]); + +reg snes_wr_cycle; + +always @(posedge CLK2) begin + if(SNES_cycle_start) begin + STATE <= ST_SNES_RD_ADDR; + end else if(SNES_WR_start) begin + STATE <= ST_SNES_WR_ADDR; + end else begin + case(STATE) + ST_IDLE: begin + ROM_ADDRr <= MAPPED_SNES_ADDR; + if(MCU_RD_PENDr) STATE <= ST_MCU_RD_ADDR; + else if(MCU_WR_PENDr) STATE <= ST_MCU_WR_ADDR; + else STATE <= ST_IDLE; + end + ST_SNES_RD_ADDR: begin + STATE <= ST_SNES_RD_WAIT; + ST_MEM_DELAYr <= ROM_RD_WAIT; + end + ST_SNES_RD_WAIT: begin + ST_MEM_DELAYr <= ST_MEM_DELAYr - 4'h1; + if(ST_MEM_DELAYr == 4'h0) STATE <= ST_SNES_RD_END; + else STATE <= ST_SNES_RD_WAIT; + if(ROM_ADDR0) SNES_DINr <= ROM_DATA[7:0]; + else SNES_DINr <= ROM_DATA[15:8]; + end + ST_SNES_RD_END: begin + STATE <= ST_IDLE; + if(ROM_ADDR0) SNES_DINr <= ROM_DATA[7:0]; + else SNES_DINr <= ROM_DATA[15:8]; + end + ST_SNES_WR_ADDR: begin + ROM_WEr <= (!IS_FLASHWR & !IS_WRITABLE); + snes_wr_cycle <= 1'b1; + STATE <= ST_SNES_WR_WAIT1; + ST_MEM_DELAYr <= ROM_WR_WAIT1; + end + ST_SNES_WR_WAIT1: begin + ST_MEM_DELAYr <= ST_MEM_DELAYr - 4'h1; + if(ST_MEM_DELAYr == 4'h0) STATE <= ST_SNES_WR_DATA; + else STATE <= ST_SNES_WR_WAIT1; + end + ST_SNES_WR_DATA: begin + ROM_DOUTr <= SNES_DATA; + ST_MEM_DELAYr <= ROM_WR_WAIT2; + STATE <= ST_SNES_WR_WAIT2; + end + ST_SNES_WR_WAIT2: begin + ST_MEM_DELAYr <= ST_MEM_DELAYr - 4'h1; + if(ST_MEM_DELAYr == 4'h0) STATE <= ST_SNES_WR_END; + else STATE <= ST_SNES_WR_WAIT2; + end + ST_SNES_WR_END: begin + STATE <= ST_IDLE; + ROM_WEr <= 1'b1; + snes_wr_cycle <= 1'b0; + end + ST_MCU_RD_ADDR: begin + ROM_ADDRr <= MCU_ADDR; + STATE <= ST_MCU_RD_WAIT; + ST_MEM_DELAYr <= ROM_RD_WAIT_MCU; + end + ST_MCU_RD_WAIT: begin + ST_MEM_DELAYr <= ST_MEM_DELAYr - 4'h1; + if(ST_MEM_DELAYr == 4'h0) begin + STATE <= ST_MCU_RD_WAIT2; + ST_MEM_DELAYr <= 4'h2; + end + else STATE <= ST_MCU_RD_WAIT; + if(ROM_ADDR0) MCU_DINr <= ROM_DATA[7:0]; + else MCU_DINr <= ROM_DATA[15:8]; + end + ST_MCU_RD_WAIT2: begin + ST_MEM_DELAYr <= ST_MEM_DELAYr - 4'h1; + if(ST_MEM_DELAYr == 4'h0) begin + STATE <= ST_MCU_RD_END; + end else STATE <= ST_MCU_RD_WAIT2; + end + ST_MCU_RD_END: begin + STATE <= ST_IDLE; + end + ST_MCU_WR_ADDR: begin + ROM_ADDRr <= MCU_ADDR; + STATE <= ST_MCU_WR_WAIT; + ST_MEM_DELAYr <= ROM_WR_WAIT_MCU; + ROM_DOUTr <= MCU_DOUT; + ROM_WEr <= 1'b0; + end + ST_MCU_WR_WAIT: begin + ST_MEM_DELAYr <= ST_MEM_DELAYr - 4'h1; + if(ST_MEM_DELAYr == 4'h0) begin + ROM_WEr <= 1'b1; + STATE <= ST_MCU_WR_WAIT2; + ST_MEM_DELAYr <= 4'h2; + end + else STATE <= ST_MCU_WR_WAIT; + end + ST_MCU_WR_WAIT2: begin + ST_MEM_DELAYr <= ST_MEM_DELAYr - 4'h1; + if(ST_MEM_DELAYr == 4'h0) begin + STATE <= ST_MCU_WR_END; + end else STATE <= ST_MCU_WR_WAIT2; + end + ST_MCU_WR_END: begin + STATE <= ST_IDLE; + end + + endcase + end +end + +// wire MCU_RRQ; +// wire MCU_WRQ; +// reg ROM_OEr; +assign ROM_DATA[7:0] = ROM_ADDR0 + ?(!MCU_OVR ? (!MCU_WRITE ? MCU_DOUT : 8'bZ) + : (!ROM_WE ? ROM_DOUTr : 8'bZ) + ) + :8'bZ; + +assign ROM_DATA[15:8] = ROM_ADDR0 ? 8'bZ + :(!MCU_OVR ? (!MCU_WRITE ? MCU_DOUT : 8'bZ) + : (!ROM_WE ? ROM_DOUTr : 8'bZ) + ); + // When in MCU mode, enable SRAM_WE according to MCU programming // else enable SRAM_WE according to state&cycle assign ROM_WE = !MCU_OVR ?MCU_WRITE - :((!IS_FLASHWR & !IS_WRITABLE & !MODE) - | ROM_WE_ARRAY[{SNES_WRITE_CYCLE, MCU_WRITE_CYCLE}][STATEIDX]); + :ROM_WEr | (ASSERT_SNES_ADDR & ~snes_wr_cycle); /* & !MODE) + | ROM_WE_ARRAY[{SNES_WRITE_CYCLE, MCU_WRITE_CYCLE}][STATEIDX])*/ // When in MCU mode, enable SRAM_OE whenever not writing // else enable SRAM_OE according to state&cycle -assign ROM_OE = !MCU_OVR - ?MCU_READ - :ROM_OE_ARRAY[{SNES_WRITE_CYCLE, MCU_WRITE_CYCLE}][STATEIDX]; +assign ROM_OE = 1'b0; //!MCU_OVR + //?MCU_READ + //:ROM_OE_ARRAY[{SNES_WRITE_CYCLE, MCU_WRITE_CYCLE}][STATEIDX]; assign ROM_CE = 1'b0; // !MCU_OVR ? (MCU_READ & MCU_WRITE) : ROM_SEL; assign ROM_BHE = !ROM_WE ? ROM_ADDR0 : 1'b0; assign ROM_BLE = !ROM_WE ? !ROM_ADDR0 : 1'b0; -//assign SRAM_BHE = SRAM_ADDR0; -//assign SRAM_BLE = ~SRAM_ADDR0; - -// dumb version -//assign SRAM_OE = !MCU_ENA ? MCU_READ : SNES_READs; -//assign SRAM_WE = !MCU_ENA ? MCU_WRITE : 1'b1; - //assign SNES_DATABUS_OE = (!IS_SAVERAM & SNES_CS) | (SNES_READ & SNES_WRITE); assign SNES_DATABUS_OE = (dspx_enable | dspx_dp_enable) ? 1'b0 : msu_enable ? 1'b0 : @@ -639,15 +683,9 @@ assign SNES_DATABUS_OE = (dspx_enable | dspx_dp_enable) ? 1'b0 : assign SNES_DATABUS_DIR = !SNES_READ ? 1'b1 : 1'b0; -assign SNES_DATA_TO_MEM = SNES_DATA_TO_MEM_ARRAY[SNES_WRITE_CYCLE][STATEIDX]; -assign MCU_DATA_TO_MEM = MCU_DATA_TO_MEM_ARRAY[MCU_WRITE_CYCLE][STATEIDX]; - -assign ROM_DATA_TO_SNES_MEM = ROM_DATA_TO_SNES_MEM_ARRAY[SNES_WRITE_CYCLE][STATEIDX]; -assign ROM_DATA_TO_MCU_MEM = ROM_DATA_TO_MCU_MEM_ARRAY[MCU_WRITE_CYCLE][STATEIDX]; - -assign SNES_READ_CYCLEw = SNES_READ_CYCLE; -assign SNES_WRITE_CYCLEw = SNES_WRITE_CYCLE; assign IRQ_DIR = 1'b0; assign SNES_IRQ = 1'bZ; +assign p113_out = ROM_WE; + endmodule diff --git a/verilog/sd2snes/mcu_cmd.v b/verilog/sd2snes/mcu_cmd.v index fd1a003..192bb84 100644 --- a/verilog/sd2snes/mcu_cmd.v +++ b/verilog/sd2snes/mcu_cmd.v @@ -26,8 +26,10 @@ module mcu_cmd( input [7:0] param_data, output [3:0] mcu_mapper, output [3:0] mcu_sram_size, - output mcu_read, + output mcu_rrq, output mcu_write, + output mcu_wrq, + input mcu_rq_rdy, output [7:0] mcu_data_out, input [7:0] mcu_data_in, output [7:0] spi_data_out, @@ -147,6 +149,7 @@ reg [31:0] SNES_SYSCLK_FREQ_BUF; reg [7:0] MCU_DATA_OUT_BUF; reg [7:0] MCU_DATA_IN_BUF; reg [1:0] mcu_nextaddr_buf; +reg mcu_nextaddr_r; reg SD_DMA_NEXTADDRr; always @(posedge clk) SD_DMA_NEXTADDRr <= SD_DMA_NEXTADDR; @@ -206,46 +209,12 @@ always @(posedge clk) begin SD_DMA_PARTIALr <= cmd_data[2]; end 4'h8: SD_DMA_TGTr <= 2'b00; - 4'h9: SD_DMA_TGTr <= cmd_data[1:0]; + 4'h9: SD_DMA_TGTr <= cmd_data[1:0]; // not implemented // 4'hE: // select memory unit endcase end else if (param_ready) begin casex (cmd_data[7:0]) - 8'h0x: - case (cmd_data[1:0]) - 2'b01: begin - case (spi_byte_cnt) - 32'h2: begin - DAC_ADDR_OUT_BUF[10:8] <= param_data[2:0]; - DAC_ADDR_OUT_BUF[7:0] <= 8'b0; - end - 32'h3: - DAC_ADDR_OUT_BUF[7:0] <= param_data; - endcase - end - 2'b10: begin - case (spi_byte_cnt) - 32'h2: begin - MSU_ADDR_OUT_BUF[13:8] <= param_data[5:0]; - MSU_ADDR_OUT_BUF[7:0] <= 8'b0; - end - 32'h3: - MSU_ADDR_OUT_BUF[7:0] <= param_data; - endcase - end - default: - case (spi_byte_cnt) - 32'h2: begin - ADDR_OUT_BUF[23:16] <= param_data; - ADDR_OUT_BUF[15:0] <= 16'b0; - end - 32'h3: - ADDR_OUT_BUF[15:8] <= param_data; - 32'h4: - ADDR_OUT_BUF[7:0] <= param_data; - endcase - endcase 8'h1x: case (spi_byte_cnt) 32'h2: @@ -403,10 +372,46 @@ always @(posedge clk) begin featurebits_out <= param_data[7:0]; endcase end +end - if (SD_DMA_NEXTADDR | (mcu_nextaddr & (cmd_data[7:5] == 3'h4) +always @(posedge clk) begin + if(param_ready && cmd_data[7:4] == 4'h0) begin + case (cmd_data[1:0]) + 2'b01: begin + case (spi_byte_cnt) + 32'h2: begin + DAC_ADDR_OUT_BUF[10:8] <= param_data[2:0]; + DAC_ADDR_OUT_BUF[7:0] <= 8'b0; + end + 32'h3: + DAC_ADDR_OUT_BUF[7:0] <= param_data; + endcase + end + 2'b10: begin + case (spi_byte_cnt) + 32'h2: begin + MSU_ADDR_OUT_BUF[13:8] <= param_data[5:0]; + MSU_ADDR_OUT_BUF[7:0] <= 8'b0; + end + 32'h3: + MSU_ADDR_OUT_BUF[7:0] <= param_data; + endcase + end + default: + case (spi_byte_cnt) + 32'h2: begin + ADDR_OUT_BUF[23:16] <= param_data; + ADDR_OUT_BUF[15:0] <= 16'b0; + end + 32'h3: + ADDR_OUT_BUF[15:8] <= param_data; + 32'h4: + ADDR_OUT_BUF[7:0] <= param_data; + endcase + endcase + end else if (SD_DMA_NEXTADDR | (mcu_nextaddr & (cmd_data[7:5] == 3'h4) && (cmd_data[3]) - && (spi_byte_cnt > (32'h1+cmd_data[4]))) + && (spi_byte_cnt >= (32'h1+cmd_data[4]))) ) begin case (SD_DMA_TGTr) @@ -419,7 +424,9 @@ end // value fetch during last SPI bit always @(posedge clk) begin - if (spi_bit_cnt == 3'h7) begin + if (cmd_data[7:4] == 4'h8 && mcu_nextaddr_buf == 2'b01) + MCU_DATA_IN_BUF <= mcu_data_in; + else if (spi_bit_cnt == 3'h7) begin if (cmd_data[7:0] == 8'hF0) MCU_DATA_IN_BUF <= 8'hA5; else if (cmd_data[7:0] == 8'hF1) @@ -464,60 +471,74 @@ always @(posedge clk) begin endcase else if (cmd_data[7:0] == 8'hFF) MCU_DATA_IN_BUF <= param_data; - else if (cmd_data[7:4] == 4'h8) - MCU_DATA_IN_BUF <= mcu_data_in; - else - MCU_DATA_IN_BUF <= cmd_data; end end // nextaddr pulse generation always @(posedge clk) begin - if (spi_bit_cnt == 3'h0) - mcu_nextaddr_buf <= {mcu_nextaddr_buf[0], 1'b1}; - else - mcu_nextaddr_buf <= {mcu_nextaddr_buf[0], 1'b0}; + mcu_nextaddr_buf <= {mcu_nextaddr_buf[0], mcu_rq_rdy}; end +parameter ST_RRQ = 4'b0001; +parameter ST_WAIT = 4'b0010; +parameter ST_NEXT = 4'b0100; +parameter ST_IDLE = 4'b1000; + +reg [3:0] rrq_state; +initial rrq_state = ST_IDLE; +reg [2:0] rrq_wait; +reg mcu_rrq_r; + +reg [3:0] wrq_state; +initial wrq_state = ST_IDLE; +reg [2:0] wrq_wait; +reg mcu_wrq_r; -// r/w pulse always @(posedge clk) begin - if ((spi_bit_cnt == 3'h1 - || spi_bit_cnt == 3'h2 - || spi_bit_cnt == 3'h3 - ) - & (cmd_data[7:4] == 4'h9) - & (spi_byte_cnt > 32'h1) - ) - MCU_WRITE_BUF <= 1'b0; - else - MCU_WRITE_BUF <= 1'b1; + case(rrq_state) + ST_IDLE: begin + mcu_nextaddr_r <= 1'b0; + if((param_ready | cmd_ready) && cmd_data[7:4] == 4'h8) begin + mcu_rrq_r <= 1'b1; + rrq_state <= ST_RRQ; + end else + rrq_state <= ST_IDLE; + end + ST_RRQ: begin + mcu_rrq_r <= 1'b0; + rrq_state <= ST_IDLE; + end + endcase +end -// Read pulse is 3 spi cycles to ensure that the value -// is ready in the 2nd cycle in MCU master mode - if ((spi_bit_cnt == 3'h5 - || spi_bit_cnt == 3'h6 - || spi_bit_cnt == 3'h7 - ) - & (cmd_data[7:4] == 4'h8) - & (spi_byte_cnt > 32'h0) - ) - MCU_READ_BUF <= 1'b0; - else - MCU_READ_BUF <= 1'b1; +always @(posedge clk) begin + case(wrq_state) + ST_IDLE: begin + mcu_nextaddr_r <= 1'b0; + if(param_ready && cmd_data[7:4] == 4'h9) begin + mcu_wrq_r <= 1'b1; + wrq_state <= ST_RRQ; + end else + wrq_state <= ST_IDLE; + end + ST_RRQ: begin + mcu_wrq_r <= 1'b0; + wrq_state <= ST_IDLE; + end + endcase end // trigger for nextaddr assign mcu_nextaddr = mcu_nextaddr_buf == 2'b01; -assign mcu_read = MCU_READ_BUF; - +assign mcu_rrq = mcu_rrq_r; +assign mcu_wrq = mcu_wrq_r; assign mcu_write = SD_DMA_STATUS ?(SD_DMA_TGTr == 2'b00 ?SD_DMA_SRAM_WE :1'b1 ) - : MCU_WRITE_BUF; + : 1'b1; assign addr_out = ADDR_OUT_BUF; assign dac_addr_out = DAC_ADDR_OUT_BUF;