From 7df69092665a756c2d3a38f97e3e0c75bd5ab21f Mon Sep 17 00:00:00 2001 From: Maximilian Rehkopf Date: Mon, 9 Jul 2012 02:12:59 +0200 Subject: [PATCH] FPGA: rework shared memory access FSM --- verilog/sd2snes/main.v | 240 ++++++++++++++------------ verilog/sd2snes_cx4/cx4.v | 1 + verilog/sd2snes_cx4/main.v | 338 ++++++++++++++++++++----------------- verilog/sd2sneslite/main.v | 30 ++-- 4 files changed, 325 insertions(+), 284 deletions(-) diff --git a/verilog/sd2snes/main.v b/verilog/sd2snes/main.v index cb2a4b7..feed825 100644 --- a/verilog/sd2snes/main.v +++ b/verilog/sd2snes/main.v @@ -472,16 +472,20 @@ parameter ST_MCU_WR_WAIT = 18'b000100000000000000; parameter ST_MCU_WR_WAIT2 = 18'b001000000000000000; parameter ST_MCU_WR_END = 18'b010000000000000000; -parameter ROM_RD_WAIT = 4'h4; +parameter ROM_RD_WAIT = 4'h0; parameter ROM_RD_WAIT_MCU = 4'h6; +parameter ROM_WR_WAIT = 4'h4; parameter ROM_WR_WAIT1 = 4'h2; -parameter ROM_WR_WAIT2 = 4'h3; -parameter ROM_WR_WAIT_MCU = 4'h6; +parameter ROM_WR_WAIT2 = 4'h1; +parameter ROM_WR_WAIT_MCU = 4'h5; + +parameter SNES_DEAD_TIMEOUT = 17'd88000; // 1ms reg [17:0] STATE; initial STATE = ST_IDLE; reg [7:0] SNES_DINr; +reg [7:0] SNES_DOUTr; reg [7:0] ROM_DOUTr; assign DSPX_SNES_DATA_IN = SNES_DATA; @@ -508,7 +512,7 @@ assign SNES_DATA = (snescmd_rd_enable & ~SNES_PARD) ? snescmd_regs[SNES_ADDR[3:0 :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; + :SNES_DOUTr /*(ROM_ADDR0 ? ROM_DATA[7:0] : ROM_DATA[15:8])*/) : 8'bZ; reg [3:0] ST_MEM_DELAYr; reg MCU_RD_PENDr; @@ -520,25 +524,35 @@ always @(posedge CLK2) begin else if(STATE & (ST_SNES_RD_END | ST_SNES_WR_END)) NEED_SNES_ADDRr <= 1'b0; end -wire ASSERT_SNES_ADDR = SNES_CPU_CLK & NEED_SNES_ADDRr; - -assign ROM_ADDR = (SD_DMA_TO_ROM) ? MCU_ADDR[23:1] : (ASSERT_SNES_ADDR) ? MAPPED_SNES_ADDR[23:1] : ROM_ADDRr[23:1]; -assign ROM_ADDR0 = (SD_DMA_TO_ROM) ? 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; +reg ROM_SAr; +initial ROM_SAr = 1'b1; +//wire ROM_SA = SNES_FAKE_CLK | ((STATE == ST_IDLE) ^ (~RQ_MCU_RDYr & SNES_cycle_end)); +wire ROM_SA = ROM_SAr; + +assign ROM_ADDR = (SD_DMA_TO_ROM) ? MCU_ADDR[23:1] : (ROM_SA) ? MAPPED_SNES_ADDR[23:1] : ROM_ADDRr[23:1]; +assign ROM_ADDR0 = (SD_DMA_TO_ROM) ? MCU_ADDR[0] : (ROM_SA) ? MAPPED_SNES_ADDR[0] : ROM_ADDRr[0]; + +reg ROM_WEr; +initial ROM_WEr = 1'b1; +reg ROM_DOUT_ENr; +initial ROM_DOUT_ENr = 1'b0; + +reg[17:0] SNES_DEAD_CNTr; +initial SNES_DEAD_CNTr = 0; + always @(posedge CLK2) begin if(MCU_RRQ) begin MCU_RD_PENDr <= 1'b1; RQ_MCU_RDYr <= 1'b0; + ROM_ADDRr <= MCU_ADDR; end else if(MCU_WRQ) begin MCU_WR_PENDr <= 1'b1; RQ_MCU_RDYr <= 1'b0; + ROM_ADDRr <= MCU_ADDR; end else if(STATE & (ST_MCU_RD_END | ST_MCU_WR_END)) begin MCU_RD_PENDr <= 1'b0; MCU_WR_PENDr <= 1'b0; @@ -546,115 +560,119 @@ always @(posedge CLK2) begin end end +always @(posedge CLK2) begin + if(~SNES_CPU_CLK) SNES_DEAD_CNTr <= SNES_DEAD_CNTr + 1; + else SNES_DEAD_CNTr <= 17'h0; +end + +always @(posedge CLK2) begin + if(SNES_DEAD_CNTr > SNES_DEAD_TIMEOUT) SNES_DEADr <= 1'b1; + else if(SNES_CPU_CLK) SNES_DEADr <= 1'b0; +end + reg snes_wr_cycle; always @(posedge CLK2) begin - if(SNES_cycle_start & ~SNES_WR_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; + if(SNES_DEADr & SNES_CPU_CLK) STATE <= ST_IDLE; // interrupt+restart an ongoing MCU access when the SNES comes alive + else + case(STATE) + ST_IDLE: begin + ROM_SAr <= 1'b1; + ROM_DOUT_ENr <= 1'b0; + if(SNES_cycle_start & ~SNES_WRITE) begin + STATE <= ST_SNES_WR_ADDR; + if(IS_SAVERAM | IS_WRITABLE | IS_FLASHWR) begin + ROM_WEr <= 1'b0; + ROM_DOUT_ENr <= 1'b1; + end + end else if(SNES_cycle_start) begin +// STATE <= ST_SNES_RD_ADDR; + STATE <= ST_SNES_RD_END; + SNES_DOUTr <= (ROM_ADDR0 ? ROM_DATA[7:0] : ROM_DATA[15:8]); + end else if(SNES_DEADr & MCU_RD_PENDr) begin + STATE <= ST_MCU_RD_ADDR; + end else if(SNES_DEADr & MCU_WR_PENDr) begin + STATE <= ST_MCU_WR_ADDR; 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; + end + ST_SNES_RD_ADDR: begin + ST_MEM_DELAYr <= ROM_RD_WAIT; + STATE <= ST_SNES_RD_WAIT; + end + ST_SNES_RD_WAIT: begin + ST_MEM_DELAYr <= ST_MEM_DELAYr - 1; +// if(ST_MEM_DELAYr == 0) begin +// end +// else STATE <= ST_SNES_RD_WAIT; + end + + ST_SNES_WR_ADDR: begin + ST_MEM_DELAYr <= ROM_WR_WAIT1; + STATE <= ST_SNES_WR_WAIT1; + end + ST_SNES_WR_WAIT1: begin + ST_MEM_DELAYr <= ST_MEM_DELAYr - 1; + if(ST_MEM_DELAYr == 0) begin ST_MEM_DELAYr <= ROM_WR_WAIT2; - STATE <= ST_SNES_WR_WAIT2; + STATE <= ST_SNES_WR_WAIT2; + ROM_DOUTr <= SNES_DATA; 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; + else STATE <= ST_SNES_WR_WAIT1; + end + ST_SNES_WR_WAIT2: begin + ST_MEM_DELAYr <= ST_MEM_DELAYr - 1; + if(ST_MEM_DELAYr == 0) begin + STATE <= ST_SNES_WR_END; 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; + else STATE <= ST_SNES_WR_WAIT2; + end + ST_SNES_RD_END, ST_SNES_WR_END: begin + ROM_DOUT_ENr <= 1'b0; + if(MCU_RD_PENDr) begin + STATE <= ST_MCU_RD_ADDR; + end else if(MCU_WR_PENDr) begin + STATE <= ST_MCU_WR_ADDR; + end else STATE <= ST_IDLE; + end + ST_MCU_RD_ADDR: begin + ROM_SAr <= 1'b0; + ST_MEM_DELAYr <= ROM_RD_WAIT_MCU; + STATE <= ST_MCU_RD_WAIT; + end + ST_MCU_RD_WAIT: begin + ST_MEM_DELAYr <= ST_MEM_DELAYr - 1; + if(ST_MEM_DELAYr == 0) begin + STATE <= ST_MCU_RD_END; 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; + else STATE <= ST_MCU_RD_WAIT; + end + ST_MCU_RD_END: begin + MCU_DINr <= ROM_ADDRr[0] ? ROM_DATA[7:0] : ROM_DATA[15:8]; + STATE <= ST_IDLE; + end + + ST_MCU_WR_ADDR: begin + ROM_DOUTr <= MCU_DOUT; + ROM_SAr <= 1'b0; + ST_MEM_DELAYr <= ROM_WR_WAIT_MCU; + STATE <= ST_MCU_WR_WAIT; + ROM_DOUT_ENr <= 1'b1; + ROM_WEr <= 1'b0; + end + ST_MCU_WR_WAIT: begin + ST_MEM_DELAYr <= ST_MEM_DELAYr - 1; + if(ST_MEM_DELAYr == 0) begin + ROM_WEr <= 1'b1; + STATE <= ST_MCU_WR_END; 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 + else STATE <= ST_MCU_WR_WAIT; + end + ST_MCU_WR_END: begin + ROM_DOUT_ENr <= 1'b0; + STATE <= ST_IDLE; + end + endcase end always @(posedge SYSCLK2) begin diff --git a/verilog/sd2snes_cx4/cx4.v b/verilog/sd2snes_cx4/cx4.v index 5a546b0..a7197e1 100644 --- a/verilog/sd2snes_cx4/cx4.v +++ b/verilog/sd2snes_cx4/cx4.v @@ -334,6 +334,7 @@ always @(posedge CLK) begin CACHE_ST <= ST_CACHE_START; cache_pgmpage <= cx4_mmio_pgmpage; cache_cachepage <= cx4_mmio_cachepage; + cx4_busy[BUSY_CACHE] <= 1'b1; end else if(cpu_cache_en & (~cachevalid[~cpu_page] | |(cachetag[~cpu_page] ^ cpu_p))) begin diff --git a/verilog/sd2snes_cx4/main.v b/verilog/sd2snes_cx4/main.v index d6b8de8..b82fb00 100644 --- a/verilog/sd2snes_cx4/main.v +++ b/verilog/sd2snes_cx4/main.v @@ -87,6 +87,9 @@ always @(posedge CLK2) begin end wire [23:0] SNES_ADDR = SNES_ADDR_r[2] & SNES_ADDR_r[1]; +wire [7:0] CX4_SNES_DATA_IN; +wire [7:0] CX4_SNES_DATA_OUT; + wire [7:0] spi_cmd_data; wire [7:0] spi_param_data; wire [7:0] spi_input_data; @@ -114,9 +117,6 @@ wire [7:0] MSU_SNES_DATA_OUT; wire [5:0] msu_status_reset_bits; wire [5:0] msu_status_set_bits; -wire [7:0] CX4_SNES_DATA_IN; -wire [7:0] CX4_SNES_DATA_OUT; - wire [23:0] MAPPED_SNES_ADDR; wire ROM_ADDR0; @@ -369,25 +369,28 @@ parameter ST_MCU_WR_WAIT2 = 21'b000001000000000000000; parameter ST_MCU_WR_END = 21'b000010000000000000000; parameter ST_CX4_RD_ADDR = 21'b000100000000000000000; parameter ST_CX4_RD_WAIT = 21'b001000000000000000000; -parameter ST_CX4_RD_WAIT2 = 21'b010000000000000000000; -parameter ST_CX4_RD_END = 21'b100000000000000000000; +parameter ST_CX4_RD_END = 21'b010000000000000000000; -parameter ROM_RD_WAIT = 4'h4; +parameter ROM_RD_WAIT = 4'h0; parameter ROM_RD_WAIT_MCU = 4'h6; +parameter ROM_WR_WAIT = 4'h4; parameter ROM_WR_WAIT1 = 4'h2; -parameter ROM_WR_WAIT2 = 4'h3; -parameter ROM_WR_WAIT_MCU = 4'h6; +parameter ROM_WR_WAIT2 = 4'h1; +parameter ROM_WR_WAIT_MCU = 4'h5; parameter ROM_RD_WAIT_CX4 = 4'h6; +parameter SNES_DEAD_TIMEOUT = 17'd88000; // 1ms + reg [20:0] STATE; initial STATE = ST_IDLE; +reg [7:0] SNES_DINr; +reg [7:0] SNES_DOUTr; +reg [7:0] ROM_DOUTr; + assign MSU_SNES_DATA_IN = SNES_DATA; assign CX4_SNES_DATA_IN = SNES_DATA; -reg [7:0] SNES_DINr; -reg [7:0] ROM_DOUTr; - reg [7:0] r213fr; reg r213f_forceread; reg [2:0] r213f_delay; @@ -419,25 +422,61 @@ always @(posedge CLK2) begin end wire IS_CART = IS_ROM | IS_SAVERAM | IS_WRITABLE; -wire ASSERT_SNES_ADDR = SNES_CPU_CLK & NEED_SNES_ADDRr & IS_CART & ~cx4_active; - -assign ROM_ADDR = (SD_DMA_TO_ROM) ? MCU_ADDR[23:1] : (ASSERT_SNES_ADDR) ? MAPPED_SNES_ADDR[23:1] : ROM_ADDRr[23:1]; -assign ROM_ADDR0 = (SD_DMA_TO_ROM) ? 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; +reg RQ_CX4_RDYr; +initial RQ_CX4_RDYr = 1'b1; +assign CX4_RDY = RQ_CX4_RDYr; + +reg ROM_SAr; +initial ROM_SAr = 1'b1; +wire ROM_SA = ROM_SAr; + +reg ROM_CAr; +initial ROM_CAr = 1'b0; +wire ROM_CA = ROM_CAr; + +reg [23:0] CX4_ADDRr; + +assign ROM_ADDR = (SD_DMA_TO_ROM) ? MCU_ADDR[23:1] : ROM_CA ? CX4_ADDRr[23:1] : ROM_SA ? MAPPED_SNES_ADDR[23:1] : ROM_ADDRr[23:1]; +assign ROM_ADDR0 = (SD_DMA_TO_ROM) ? MCU_ADDR[0] : ROM_CA ? CX4_ADDRr[0] : ROM_SA ? MAPPED_SNES_ADDR[0] : ROM_ADDRr[0]; + +reg ROM_WEr; +initial ROM_WEr = 1'b1; +reg ROM_DOUT_ENr; +initial ROM_DOUT_ENr = 1'b0; + +reg[17:0] SNES_DEAD_CNTr; +initial SNES_DEAD_CNTr = 0; + +always @(posedge CLK2) begin + if(cx4_active) begin + if(CX4_RRQ) begin + CX4_RD_PENDr <= 1'b1; + RQ_CX4_RDYr <= 1'b0; + CX4_ADDRr <= CX4_ADDR; + end else if(STATE == ST_CX4_RD_END) begin + CX4_RD_PENDr <= 1'b0; + RQ_CX4_RDYr <= 1'b1; + end + end else begin + CX4_RD_PENDr <= 1'b0; + RQ_CX4_RDYr <= 1'b1; + end +end + always @(posedge CLK2) begin if(MCU_RRQ) begin MCU_RD_PENDr <= 1'b1; RQ_MCU_RDYr <= 1'b0; + ROM_ADDRr <= MCU_ADDR; end else if(MCU_WRQ) begin MCU_WR_PENDr <= 1'b1; RQ_MCU_RDYr <= 1'b0; + ROM_ADDRr <= MCU_ADDR; end else if(STATE & (ST_MCU_RD_END | ST_MCU_WR_END)) begin MCU_RD_PENDr <= 1'b0; MCU_WR_PENDr <= 1'b0; @@ -445,151 +484,138 @@ always @(posedge CLK2) begin end end -reg RQ_CX4_RDYr; -initial RQ_CX4_RDYr = 1'b1; -assign CX4_RDY = RQ_CX4_RDYr; - always @(posedge CLK2) begin - if(CX4_RRQ) begin - CX4_RD_PENDr <= 1'b1; - RQ_CX4_RDYr <= 1'b0; - end else if(STATE == ST_CX4_RD_WAIT && ST_MEM_DELAYr == 4'h0) begin - CX4_RD_PENDr <= 1'b0; - RQ_CX4_RDYr <= 1'b1; - end + if(~SNES_CPU_CLK) SNES_DEAD_CNTr <= SNES_DEAD_CNTr + 1; + else SNES_DEAD_CNTr <= 17'h0; end -reg snes_wr_cycle; +always @(posedge CLK2) begin + if(SNES_DEAD_CNTr > SNES_DEAD_TIMEOUT) SNES_DEADr <= 1'b1; + else if(SNES_CPU_CLK) SNES_DEADr <= 1'b0; +end always @(posedge CLK2) begin - if(SNES_cycle_start & IS_CART & ~cx4_active) begin - STATE <= ST_SNES_RD_ADDR; - end else if(SNES_WR_start & IS_CART & ~cx4_active) begin - STATE <= ST_SNES_WR_ADDR; - end else begin - case(STATE) - ST_IDLE: begin - ROM_ADDRr <= MAPPED_SNES_ADDR; - if(CX4_RD_PENDr) begin - STATE <= ST_CX4_RD_WAIT; - ROM_ADDRr <= CX4_ADDR; - ST_MEM_DELAYr <= ROM_RD_WAIT_CX4; - end else if(~cx4_active && ~ASSERT_SNES_ADDR) begin - if(MCU_RD_PENDr) STATE <= ST_MCU_RD_ADDR; - else if(MCU_WR_PENDr) STATE <= ST_MCU_WR_ADDR; - else STATE <= ST_IDLE; + if(SNES_DEADr & SNES_CPU_CLK) STATE <= ST_IDLE; // interrupt+restart an ongoing MCU access when the SNES comes alive + else + case(STATE) + ST_IDLE: begin + ROM_SAr <= 1'b1; + ROM_CAr <= 1'b0; + ROM_DOUT_ENr <= 1'b0; + if(cx4_active) begin + if(CX4_RD_PENDr) STATE <= ST_CX4_RD_ADDR; + end else if(SNES_cycle_start & ~SNES_WRITE) begin + STATE <= ST_SNES_WR_ADDR; + if(IS_SAVERAM | IS_WRITABLE) begin + ROM_WEr <= 1'b0; + ROM_DOUT_ENr <= 1'b1; end - 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_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; + end else if(SNES_cycle_start) begin +// STATE <= ST_SNES_RD_ADDR; + STATE <= ST_SNES_RD_END; + SNES_DOUTr <= (ROM_ADDR0 ? ROM_DATA[7:0] : ROM_DATA[15:8]); + end else if(SNES_DEADr & MCU_RD_PENDr) begin + STATE <= ST_MCU_RD_ADDR; + end else if(SNES_DEADr & MCU_WR_PENDr) begin + STATE <= ST_MCU_WR_ADDR; + end + end + ST_SNES_RD_ADDR: begin + ST_MEM_DELAYr <= ROM_RD_WAIT; + STATE <= ST_SNES_RD_WAIT; + end + ST_SNES_RD_WAIT: begin + ST_MEM_DELAYr <= ST_MEM_DELAYr - 1; +// if(ST_MEM_DELAYr == 0) begin +// end +// else STATE <= ST_SNES_RD_WAIT; + end + + ST_SNES_WR_ADDR: begin + ST_MEM_DELAYr <= ROM_WR_WAIT1; + STATE <= ST_SNES_WR_WAIT1; + end + ST_SNES_WR_WAIT1: begin + ST_MEM_DELAYr <= ST_MEM_DELAYr - 1; + if(ST_MEM_DELAYr == 0) begin + 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; - if(ROM_ADDR0) MCU_DINr <= ROM_DATA[7:0]; - else MCU_DINr <= ROM_DATA[15:8]; - end - else STATE <= ST_MCU_RD_WAIT; - 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 - - ST_CX4_RD_ADDR: begin - ROM_ADDRr <= CX4_ADDR; - STATE <= ST_CX4_RD_WAIT; - ST_MEM_DELAYr <= ROM_RD_WAIT_CX4; - end - ST_CX4_RD_WAIT: begin - ST_MEM_DELAYr <= ST_MEM_DELAYr - 4'h1; - if(ST_MEM_DELAYr == 4'h0) STATE <= ST_IDLE; - else STATE <= ST_CX4_RD_WAIT; - if(ROM_ADDR0) CX4_DINr <= ROM_DATA[7:0]; - else CX4_DINr <= ROM_DATA[15:8]; - end - ST_CX4_RD_END: begin - STATE <= ST_IDLE; - end - endcase - end + ROM_DOUTr <= SNES_DATA; + end + else STATE <= ST_SNES_WR_WAIT1; + end + ST_SNES_WR_WAIT2: begin + ST_MEM_DELAYr <= ST_MEM_DELAYr - 1; + if(ST_MEM_DELAYr == 0) begin + STATE <= ST_SNES_WR_END; + ROM_WEr <= 1'b1; + end + else STATE <= ST_SNES_WR_WAIT2; + end + ST_SNES_RD_END, ST_SNES_WR_END: begin + ROM_DOUT_ENr <= 1'b0; + if(MCU_RD_PENDr) begin + STATE <= ST_MCU_RD_ADDR; + end else if(MCU_WR_PENDr) begin + STATE <= ST_MCU_WR_ADDR; + end else STATE <= ST_IDLE; + end + ST_MCU_RD_ADDR: begin + ROM_SAr <= 1'b0; + ST_MEM_DELAYr <= ROM_RD_WAIT_MCU; + STATE <= ST_MCU_RD_WAIT; + end + ST_MCU_RD_WAIT: begin + ST_MEM_DELAYr <= ST_MEM_DELAYr - 1; + if(ST_MEM_DELAYr == 0) begin + STATE <= ST_MCU_RD_END; + end + else STATE <= ST_MCU_RD_WAIT; + end + ST_MCU_RD_END: begin + MCU_DINr <= ROM_ADDRr[0] ? ROM_DATA[7:0] : ROM_DATA[15:8]; + STATE <= ST_IDLE; + end + + ST_MCU_WR_ADDR: begin + ROM_DOUTr <= MCU_DOUT; + ROM_SAr <= 1'b0; + ST_MEM_DELAYr <= ROM_WR_WAIT_MCU; + STATE <= ST_MCU_WR_WAIT; + ROM_DOUT_ENr <= 1'b1; + ROM_WEr <= 1'b0; + end + ST_MCU_WR_WAIT: begin + ST_MEM_DELAYr <= ST_MEM_DELAYr - 1; + if(ST_MEM_DELAYr == 0) begin + ROM_WEr <= 1'b1; + STATE <= ST_MCU_WR_END; + end + else STATE <= ST_MCU_WR_WAIT; + end + ST_MCU_WR_END: begin + ROM_DOUT_ENr <= 1'b0; + STATE <= ST_IDLE; + end + ST_CX4_RD_ADDR: begin + ROM_CAr <= 1'b1; + ST_MEM_DELAYr <= ROM_RD_WAIT_CX4; + STATE <= ST_CX4_RD_WAIT; + end + ST_CX4_RD_WAIT: begin + ST_MEM_DELAYr <= ST_MEM_DELAYr - 1; + if(ST_MEM_DELAYr == 0) begin + STATE <= ST_CX4_RD_END; + end + else STATE <= ST_CX4_RD_WAIT; + end + ST_CX4_RD_END: begin + ROM_CAr <= 1'b0; + CX4_DINr <= CX4_ADDRr[0] ? ROM_DATA[7:0] : ROM_DATA[15:8]; + STATE <= ST_IDLE; + end + + endcase end always @(posedge SYSCLK2) begin diff --git a/verilog/sd2sneslite/main.v b/verilog/sd2sneslite/main.v index 9b76cda..5b49976 100644 --- a/verilog/sd2sneslite/main.v +++ b/verilog/sd2sneslite/main.v @@ -35,6 +35,10 @@ module main( output SNES_DATABUS_DIR, input SNES_SYSCLK, + input [7:0] SNES_PA, + input SNES_PARD, + input SNES_PAWR, + /* SRAM signals */ /* Bus 1: PSRAM, 128Mbit, 16bit, 70ns */ inout [15:0] ROM_DATA, @@ -93,8 +97,6 @@ wire [7:0] spi_input_data; wire [31:0] spi_byte_cnt; wire [2:0] spi_bit_cnt; wire [23:0] MCU_ADDR; -wire [7:0] mcu_data_in; -wire [7:0] mcu_data_out; wire [23:0] SAVERAM_MASK; wire [23:0] ROM_MASK; @@ -125,7 +127,6 @@ mcu_cmd snes_mcu_cmd( .param_ready(spi_param_ready), .cmd_data(spi_cmd_data), .param_data(spi_param_data), - .mcu_write(MCU_WRITE), .mcu_data_in(MCU_DINr), .mcu_data_out(MCU_DOUT), .spi_byte_cnt(spi_byte_cnt), @@ -140,7 +141,6 @@ mcu_cmd snes_mcu_cmd( ); wire [7:0] DCM_STATUS; - // dcm1: dfs 4x my_dcm snes_dcm( .CLKIN(CLKIN), @@ -194,11 +194,6 @@ address snes_addr( .ROM_MASK(ROM_MASK) ); -wire SNES_READ_CYCLEw; -wire SNES_WRITE_CYCLEw; -wire MCU_READ_CYCLEw; -wire MCU_WRITE_CYCLEw; - parameter MODE_SNES = 1'b0; parameter MODE_MCU = 1'b1; @@ -220,23 +215,24 @@ parameter ST_MCU_WR_WAIT = 18'b000100000000000000; parameter ST_MCU_WR_WAIT2 = 18'b001000000000000000; parameter ST_MCU_WR_END = 18'b010000000000000000; -parameter ROM_RD_WAIT = 4'h4; +parameter ROM_RD_WAIT = 4'h0; parameter ROM_RD_WAIT_MCU = 4'h6; +parameter ROM_WR_WAIT = 4'h4; parameter ROM_WR_WAIT1 = 4'h2; -parameter ROM_WR_WAIT2 = 4'h3; -parameter ROM_WR_WAIT_MCU = 4'h6; +parameter ROM_WR_WAIT2 = 4'h1; +parameter ROM_WR_WAIT_MCU = 4'h5; + +parameter SNES_DEAD_TIMEOUT = 17'd88000; // 1ms reg [17:0] STATE; initial STATE = ST_IDLE; -reg [1:0] CYCLE_RESET; -reg ROM_WE_MASK; -reg ROM_OE_MASK; - reg [7:0] SNES_DINr; +reg [7:0] SNES_DOUTr; reg [7:0] ROM_DOUTr; -assign SNES_DATA = (!SNES_READ) ? SNES_DINr : 8'bZ; +assign SNES_DATA = ~SNES_READ ? SNES_DOUTr + : 8'bZ; reg [3:0] ST_MEM_DELAYr; reg MCU_RD_PENDr;