From a50522b4e90b5c008ac5ce0f8c88f5aea5a3c71f Mon Sep 17 00:00:00 2001 From: ikari Date: Sat, 14 Jan 2012 01:22:38 +0100 Subject: [PATCH] FPGA: optimize non-sector-aligned SD DMA reads --- verilog/sd2snes/main.v | 6 +++++- verilog/sd2snes/mcu_cmd.v | 15 ++++++++++++--- verilog/sd2snes/sd_dma.v | 14 ++++++++++---- 3 files changed, 27 insertions(+), 8 deletions(-) diff --git a/verilog/sd2snes/main.v b/verilog/sd2snes/main.v index e63a5db..027c7df 100644 --- a/verilog/sd2snes/main.v +++ b/verilog/sd2snes/main.v @@ -144,7 +144,9 @@ sd_dma snes_sd_dma( .SD_DMA_NEXTADDR(SD_DMA_NEXTADDR), .SD_DMA_PARTIAL(SD_DMA_PARTIAL), .SD_DMA_PARTIAL_START(SD_DMA_PARTIAL_START), - .SD_DMA_PARTIAL_END(SD_DMA_PARTIAL_END) + .SD_DMA_PARTIAL_END(SD_DMA_PARTIAL_END), + .SD_DMA_START_MID_BLOCK(SD_DMA_START_MID_BLOCK), + .SD_DMA_END_MID_BLOCK(SD_DMA_END_MID_BLOCK) ); wire SD_DMA_TO_ROM = (SD_DMA_STATUS && (SD_DMA_TGT == 2'b00)); @@ -293,6 +295,8 @@ mcu_cmd snes_mcu_cmd( .SD_DMA_PARTIAL(SD_DMA_PARTIAL), .SD_DMA_PARTIAL_START(SD_DMA_PARTIAL_START), .SD_DMA_PARTIAL_END(SD_DMA_PARTIAL_END), + .SD_DMA_START_MID_BLOCK(SD_DMA_START_MID_BLOCK), + .SD_DMA_END_MID_BLOCK(SD_DMA_END_MID_BLOCK), .dac_addr_out(dac_addr), .DAC_STATUS(DAC_STATUS), // .dac_volume_out(dac_volume), diff --git a/verilog/sd2snes/mcu_cmd.v b/verilog/sd2snes/mcu_cmd.v index 4ccd9e8..6706087 100644 --- a/verilog/sd2snes/mcu_cmd.v +++ b/verilog/sd2snes/mcu_cmd.v @@ -48,7 +48,9 @@ module mcu_cmd( output SD_DMA_PARTIAL, output [10:0] SD_DMA_PARTIAL_START, output [10:0] SD_DMA_PARTIAL_END, - + output reg SD_DMA_START_MID_BLOCK, + output reg SD_DMA_END_MID_BLOCK, + // DAC output [10:0] dac_addr_out, input DAC_STATUS, @@ -103,6 +105,8 @@ initial begin dspx_dat_addr_out = 10'b0000000000; dspx_reset_out = 1'b1; region_out = 0; + SD_DMA_START_MID_BLOCK = 0; + SD_DMA_END_MID_BLOCK = 0; end wire [31:0] snes_sysclk_freq; @@ -179,6 +183,7 @@ initial begin MSU_ADDR_OUT_BUF = 0; SD_DMA_ENr = 0; MAPPER_BUF = 1; + SD_DMA_PARTIALr = 0; end // command interpretation @@ -221,12 +226,16 @@ always @(posedge clk) begin SD_DMA_ENr <= 1'b0; 8'h6x: case (spi_byte_cnt) - 32'h2: + 32'h2: begin + SD_DMA_START_MID_BLOCK <= param_data[7]; SD_DMA_PARTIAL_STARTr[10:9] <= param_data[1:0]; + end 32'h3: SD_DMA_PARTIAL_STARTr[8:0] <= {param_data, 1'b0}; - 32'h4: + 32'h4: begin + SD_DMA_END_MID_BLOCK <= param_data[7]; SD_DMA_PARTIAL_ENDr[10:9] <= param_data[1:0]; + end 32'h5: SD_DMA_PARTIAL_ENDr[8:0] <= {param_data, 1'b0}; endcase diff --git a/verilog/sd2snes/sd_dma.v b/verilog/sd2snes/sd_dma.v index 2137370..ad3ace6 100644 --- a/verilog/sd2snes/sd_dma.v +++ b/verilog/sd2snes/sd_dma.v @@ -29,7 +29,9 @@ module sd_dma( output [7:0] SD_DMA_SRAM_DATA, input SD_DMA_PARTIAL, input [10:0] SD_DMA_PARTIAL_START, - input [10:0] SD_DMA_PARTIAL_END + input [10:0] SD_DMA_PARTIAL_END, + input SD_DMA_START_MID_BLOCK, + input SD_DMA_END_MID_BLOCK ); reg [10:0] SD_DMA_STARTr; @@ -85,7 +87,9 @@ always @(posedge CLK) begin end always @(posedge CLK) begin - if(cyclecnt == 1042) SD_DMA_DONEr <= 1; + if(cyclecnt == 1042 + || ((SD_DMA_END_MID_BLOCK & SD_DMA_PARTIALr) && cyclecnt == SD_DMA_PARTIAL_END)) + SD_DMA_DONEr <= 1; else SD_DMA_DONEr <= 0; end @@ -100,8 +104,10 @@ always @(posedge CLK) begin end always @(posedge CLK) begin - if(SD_DMA_EN_rising || !SD_DMA_STATUSr) cyclecnt <= 0; - else if(clkcnt[1:0] == 2'b11) cyclecnt <= cyclecnt + 1; + if(SD_DMA_EN_rising) + cyclecnt <= (SD_DMA_PARTIALr && SD_DMA_START_MID_BLOCK) ? SD_DMA_PARTIAL_START : 0; + else if(!SD_DMA_STATUSr) cyclecnt <= 0; + else if(clkcnt[1:0] == 2'b10) cyclecnt <= cyclecnt + 1; end // we have 8 clk cycles to complete one RAM write