Browse Source

FPGA: optimize non-sector-aligned SD DMA reads

ikari 12 years ago
parent
commit
a50522b4e9
3 changed files with 27 additions and 8 deletions
  1. 5 1
      verilog/sd2snes/main.v
  2. 12 3
      verilog/sd2snes/mcu_cmd.v
  3. 10 4
      verilog/sd2snes/sd_dma.v

+ 5 - 1
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),

+ 12 - 3
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

+ 10 - 4
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