Added modules to read sdcard data and cmd response
ci/woodpecker/push/test-workflow Pipeline was successful

These were realy headaches but the testbenches are passing. We need to
take a look at the audio_buffer testbench for sure, it is way wrong and
needs reworked to use the interface. Should do a pass through every
module probably.
This commit is contained in:
2025-06-07 21:57:17 -07:00
parent e32563131f
commit 71eecd18e8
8 changed files with 662 additions and 4 deletions
+119
View File
@@ -0,0 +1,119 @@
module read_command(
input logic clk,
input logic reset,
input logic listen,
// 8 types of responses??? so hard to tell
input logic[2:0] response_type,
input logic sd_cmd,
output logic received,
// This has to be large enough to capture each possible response
output logic [135:0] out_data
);
enum logic [2:0] {IDLE,START,LISTEN,RECEIVING,DONE} state, next_state;
// This should be large enough to capture the largest 136-bit response
logic [$clog2(136):0] counter;
logic [135:0] data_reg;
logic [2:0] response_type_reg;
always_comb begin
case (state)
IDLE:
if (listen)
next_state=START;
else
next_state=IDLE;
START:
if (sd_cmd == 0)
next_state=RECEIVING;
else
next_state=LISTEN;
LISTEN:
// check for the start bit
if (sd_cmd == 0)
next_state=RECEIVING;
else
next_state=LISTEN;
RECEIVING:
if (counter == 0)
next_state=DONE;
else
next_state=RECEIVING;
DONE:
if (listen)
next_state=START;
else
next_state=DONE;
default:
next_state=IDLE;
endcase
end
always_ff @(posedge clk) begin
case (state)
IDLE:
begin
received <= 0;
out_data <= 0;
if (listen)
response_type_reg <= response_type;
end
START:
begin
// off-by-one/cycle timing issues accumulated to a counter offset
// of 3.
counter <= get_bits(response_type_reg) - 3;
data_reg <= 0;
received <= 0;
end
LISTEN:
// This is kinda a hack
// I don't fully understand why the receiving state misses two
// whole bits, I get why it misses the first but not the second...
data_reg[0] <= sd_cmd;
RECEIVING:
begin
counter <= counter - 1;
data_reg <= {data_reg[134:0],sd_cmd};
end
DONE:
begin
received <= 1;
out_data <= data_reg;
if (listen)
response_type_reg <= response_type;
end
default: ;
endcase
end
always_ff @(posedge clk) begin
if (reset)
state<=IDLE;
else
state<=next_state;
end
function automatic logic [$clog2(136):0] get_bits(logic [2:0] response);
case (response)
// Response 2 is extra long
2:
return 136;
// Most responses are 48 bits
default:
return 48;
endcase
endfunction
endmodule
+64
View File
@@ -0,0 +1,64 @@
// 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 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*8+16+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;
buffer.addra <= '1;
buffer.dina <= 0;
end
else begin
// We ignore the lower 17 bits of the block
if (counter > 16) begin
counter <= counter - 1;
byte_shift <= {byte_shift[6:0],sd_data};
byte_counter <= byte_counter - 1;
// Store received byte in audio buffer and reset counter
if (byte_counter == 0) begin
byte_counter <= 7;
buffer.dina <= byte_shift;//{byte_shift[6:0],sd_data};
buffer.ena <= 1;
end
// Turn the enable signal off so we don't accidentally write
// anything weird
if (byte_counter == 4) begin
buffer.ena <= 0;
buffer.addra <= buffer.addra + 1;
end
end
else if (counter != 0)
counter<=counter-1;
else if (sd_data == 0) begin
counter <= BLOCK_SIZE-1;
byte_counter <= 8;
end
end
end
endmodule