Added modules to read sdcard data and cmd response
ci/woodpecker/push/test-workflow Pipeline was successful
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:
@@ -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
|
||||
@@ -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
|
||||
Reference in New Issue
Block a user