SDVD/design/sd/read_data.sv
Waylon Cude f840d27b8e
All checks were successful
ci/woodpecker/push/test-workflow Pipeline was successful
Demo commit
The audio output is still messed up, but this commit gets everything as
ready as it can get. Fixed up all the testbenches and added state
machines for everything
2025-06-10 13:26:35 -07:00

70 lines
2.1 KiB
Systemverilog

// Whenever we receive a data block, start spitting bytes out into the audio
// buffer bram. This could always be clocked at the 25MHz default speed clock,
// or it could switch over like the writer has to
module read_data(
input clk,
input reset,
input [3:0] sd_data,
audio_buffer_interface.driver buffer
);
// Block data is a start bit, 512 bytes sent msb first, then a CRC16 and end
// bit.
// NOTE: This doesn't check which side of the buffer the audio player is
// reading from, so theoretically it could overwrite audio that's being
// played. However, as long as the sd card controller doesn't request extra
// blocks this shouldn't be an issue
localparam BLOCK_SIZE=512*2+16*4+2;
logic [$clog2(BLOCK_SIZE):0] counter;
logic [7:0] byte_shift;
logic [3:0] byte_counter;
assign buffer.clka = clk;
always_ff @(posedge clk) begin
if (reset) begin
buffer.ena <= 0;
// Start negative so adding bytes will get us to the right address
buffer.addra <= 0 - 512;
buffer.dina <= 0;
end
else begin
// We ignore the lower 16*4+1 bits of the block
// CRC is apparently sent on each line, back to back
if (counter > 16*4) begin
counter <= counter - 1;
byte_shift <= {byte_shift[3:0],sd_data};
byte_counter <= byte_counter - 1;
// Store received byte in audio buffer and reset counter
if (byte_counter == 0) begin
byte_counter <= 1;
buffer.dina <= {byte_shift[3:0],sd_data};
buffer.ena <= 1;
end
// Turn the enable signal off so we don't accidentally write
// anything weird
if (byte_counter == 1) begin
buffer.addra <= buffer.addra - 1;
end
end
else if (counter != 0) begin
counter<=counter-1;
buffer.ena <= 0;
end
else if (sd_data == 0) begin
// In wide bus mode we read bytes in a descending order
buffer.addra <= buffer.addra + 1024;
counter <= BLOCK_SIZE;
byte_counter <= 3;
end
end
end
endmodule