[SC64][FW][SW] Slightly speed up DMA write transfer speed + USB speed test fixes

This commit is contained in:
Mateusz Faderewski 2024-07-21 22:15:06 +02:00
parent 912f356650
commit e9ee025e21
3 changed files with 31 additions and 43 deletions

View File

@ -178,9 +178,8 @@ module memory_dma (
// RX FIFO controller // RX FIFO controller
typedef enum bit [2:0] { typedef enum bit [1:0] {
RX_FIFO_BUS_STATE_IDLE, RX_FIFO_BUS_STATE_IDLE,
RX_FIFO_BUS_STATE_WAIT,
RX_FIFO_BUS_STATE_TRANSFER_1, RX_FIFO_BUS_STATE_TRANSFER_1,
RX_FIFO_BUS_STATE_TRANSFER_2, RX_FIFO_BUS_STATE_TRANSFER_2,
RX_FIFO_BUS_STATE_ACK RX_FIFO_BUS_STATE_ACK
@ -191,7 +190,6 @@ module memory_dma (
logic rx_fifo_shift; logic rx_fifo_shift;
logic rx_fifo_shift_delayed; logic rx_fifo_shift_delayed;
logic [1:0] rx_fifo_valid;
always_ff @(posedge clk) begin always_ff @(posedge clk) begin
if (reset || dma_stop) begin if (reset || dma_stop) begin
@ -211,29 +209,24 @@ module memory_dma (
case (rx_fifo_bus_state) case (rx_fifo_bus_state)
RX_FIFO_BUS_STATE_IDLE: begin RX_FIFO_BUS_STATE_IDLE: begin
if (dma_start && dma_scb.direction) begin if (dma_start && dma_scb.direction) begin
next_rx_fifo_bus_state = RX_FIFO_BUS_STATE_WAIT;
end
end
RX_FIFO_BUS_STATE_WAIT: begin
if (mem_bus_wdata_end) begin
next_rx_fifo_bus_state = RX_FIFO_BUS_STATE_IDLE;
end else if (mem_bus_wdata_empty) begin
next_rx_fifo_bus_state = RX_FIFO_BUS_STATE_TRANSFER_1; next_rx_fifo_bus_state = RX_FIFO_BUS_STATE_TRANSFER_1;
end end
end end
RX_FIFO_BUS_STATE_TRANSFER_1: begin RX_FIFO_BUS_STATE_TRANSFER_1: begin
fifo_bus.rx_read = (!fifo_bus.rx_empty && rx_fifo_valid[1]); fifo_bus.rx_read = (!fifo_bus.rx_empty && mem_bus_wdata_empty && mem_bus_wdata_valid[1] && !mem_bus_wdata_end);
if (!fifo_bus.rx_empty || !rx_fifo_valid[1]) begin if ((!fifo_bus.rx_empty && mem_bus_wdata_empty) || !mem_bus_wdata_valid[1]) begin
next_rx_fifo_bus_state = RX_FIFO_BUS_STATE_TRANSFER_2; next_rx_fifo_bus_state = RX_FIFO_BUS_STATE_TRANSFER_2;
rx_fifo_shift = 1'b1; rx_fifo_shift = 1'b1;
end end
if (mem_bus_wdata_end) begin
next_rx_fifo_bus_state = RX_FIFO_BUS_STATE_IDLE;
end
end end
RX_FIFO_BUS_STATE_TRANSFER_2: begin RX_FIFO_BUS_STATE_TRANSFER_2: begin
fifo_bus.rx_read = (!fifo_bus.rx_empty && rx_fifo_valid[1]); fifo_bus.rx_read = (!fifo_bus.rx_empty && mem_bus_wdata_valid[0]);
if (!fifo_bus.rx_empty || !rx_fifo_valid[1]) begin if (!fifo_bus.rx_empty || !mem_bus_wdata_valid[0]) begin
next_rx_fifo_bus_state = RX_FIFO_BUS_STATE_ACK; next_rx_fifo_bus_state = RX_FIFO_BUS_STATE_ACK;
rx_fifo_shift = 1'b1; rx_fifo_shift = 1'b1;
end end
@ -241,7 +234,7 @@ module memory_dma (
RX_FIFO_BUS_STATE_ACK: begin RX_FIFO_BUS_STATE_ACK: begin
if (mem_bus_wdata_ready) begin if (mem_bus_wdata_ready) begin
next_rx_fifo_bus_state = RX_FIFO_BUS_STATE_WAIT; next_rx_fifo_bus_state = RX_FIFO_BUS_STATE_TRANSFER_1;
end end
end end
@ -255,26 +248,12 @@ module memory_dma (
mem_bus_wdata_ready <= 1'b0; mem_bus_wdata_ready <= 1'b0;
rx_fifo_shift_delayed <= rx_fifo_shift; rx_fifo_shift_delayed <= rx_fifo_shift;
if (rx_fifo_shift) begin
rx_fifo_valid <= {rx_fifo_valid[0], 1'bX};
end
if (rx_fifo_shift_delayed) begin if (rx_fifo_shift_delayed) begin
if (rx_fifo_bus_state == RX_FIFO_BUS_STATE_ACK) begin if (rx_fifo_bus_state == RX_FIFO_BUS_STATE_ACK) begin
mem_bus_wdata_ready <= 1'b1; mem_bus_wdata_ready <= 1'b1;
end end
mem_bus_wdata_buffer <= {mem_bus_wdata_buffer[7:0], fifo_bus.rx_rdata}; mem_bus_wdata_buffer <= {mem_bus_wdata_buffer[7:0], fifo_bus.rx_rdata};
end end
case (rx_fifo_bus_state)
RX_FIFO_BUS_STATE_WAIT: begin
if (mem_bus_wdata_empty) begin
rx_fifo_valid <= mem_bus_wdata_valid;
end
end
default: begin end
endcase
end end

View File

@ -892,12 +892,19 @@ fn handle_test_command(connection: Connection) -> Result<(), sc64::Error> {
println!("{}: USB", "[SC64 Tests]".bold()); println!("{}: USB", "[SC64 Tests]".bold());
print!(" Performing USB speed test... "); print!(" Performing USB write speed test... ");
stdout().flush().unwrap(); stdout().flush().unwrap();
println!(
"{}",
format!("{:.2} MiB/s", sc64.test_usb_speed(true)?).bright_green()
);
let (read_speed, write_speed) = sc64.test_usb_speed()?; print!(" Performing USB read speed test... ");
stdout().flush().unwrap();
println!("Read speed: {read_speed:.2} MiB/s, Write speed: {write_speed:.2} MiB/s"); println!(
"{}",
format!("{:.2} MiB/s", sc64.test_usb_speed(false)?).bright_green()
);
println!("{}: SDRAM (pattern)", "[SC64 Tests]".bold()); println!("{}: SDRAM (pattern)", "[SC64 Tests]".bold());

View File

@ -752,20 +752,22 @@ impl SC64 {
} }
} }
pub fn test_usb_speed(&mut self) -> Result<(f64, f64), Error> { pub fn test_usb_speed(&mut self, write: bool) -> Result<f64, Error> {
const TEST_ADDRESS: u32 = SDRAM_ADDRESS; const TEST_ADDRESS: u32 = SDRAM_ADDRESS;
const TEST_LENGTH: usize = SDRAM_LENGTH; const TEST_LENGTH: usize = 8 * 1024 * 1024;
const MIB_DIVIDER: f64 = 1024.0 * 1024.0; const MIB_DIVIDER: f64 = 1024.0 * 1024.0;
let read_time = std::time::Instant::now(); let data = vec![0x00; TEST_LENGTH];
let data = self.command_memory_read(TEST_ADDRESS, TEST_LENGTH)?;
let read_speed = (TEST_LENGTH as f64 / MIB_DIVIDER) / read_time.elapsed().as_secs_f64();
let write_time = std::time::Instant::now(); let time = std::time::Instant::now();
if write {
self.command_memory_write(TEST_ADDRESS, &data)?; self.command_memory_write(TEST_ADDRESS, &data)?;
let write_speed = (TEST_LENGTH as f64 / MIB_DIVIDER) / write_time.elapsed().as_secs_f64(); } else {
self.command_memory_read(TEST_ADDRESS, TEST_LENGTH)?;
}
Ok((read_speed, write_speed)) Ok((TEST_LENGTH as f64 / MIB_DIVIDER) / time.elapsed().as_secs_f64())
} }
pub fn test_sdram_pattern( pub fn test_sdram_pattern(