/**** * read_command.sv - reads the sd command line and listens for sd command * responses. * * @author: Waylon Cude, Dilanthi Prentice * @date: 6/12/2025 * * **/ 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 received_reg; logic [2:0] response_type_reg; // recevied was set a cycle before the data was actually ready // and if it's just a register it holds for too long // use both for maximum reactivity assign received = received_reg && !listen; 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 // This defaulted to 1 ... oops received_reg <= 0; out_data <= 0; if (listen) response_type_reg <= response_type; end START: begin received_reg <= 0; // off-by-one/cycle timing issues accumulated to a counter offset // of 3. // 3 in simulation, 2 in reality???? counter <= get_bits(response_type_reg) - 2; data_reg <= 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 out_data <= data_reg; received_reg <= 1; if (listen) begin received_reg <= 0; response_type_reg <= response_type; end 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