Partially working sd card reader.

This commit is contained in:
Ross Thompson 2021-10-11 10:23:45 -05:00
parent 047bbcf3d7
commit bfe633d087
9 changed files with 187 additions and 123 deletions

View File

@ -27,6 +27,7 @@
// include shared configuration
`include "wally-shared.vh"
`define FPGA 1
`define QEMU 1
`define BUILDROOT 1
`define BUSYBEAR 0
@ -78,9 +79,15 @@
`define BOOTTIM_SUPPORTED 1'b1
`define BOOTTIM_BASE 56'h00001000
`define BOOTTIM_RANGE 56'h00000FFF
`define TIM_SUPPORTED 1'b1
`define TIM_SUPPORTED 1'b0
`define TIM_BASE 56'h80000000
`define TIM_RANGE 56'h07FFFFFF
`define EXT_SUPPORTED 1'b1
`define EXT_BASE 56'h80000000
`define EXT_RANGE 56'h07FFFFFF
`define CLINT_SUPPORTED 1'b1
`define CLINT_BASE 56'h02000000
`define CLINT_RANGE 56'h0000FFFF

View File

@ -549,6 +549,10 @@ add wave -noupdate -expand -group SDC /testbench/dut/wallypipelinedsoc/uncore/sd
add wave -noupdate -expand -group SDC /testbench/dut/wallypipelinedsoc/uncore/sdc/SDC/WordCount
add wave -noupdate -expand -group SDC /testbench/dut/wallypipelinedsoc/uncore/sdc/SDC/HREADSDC
add wave -noupdate -expand -group SDC /testbench/dut/wallypipelinedsoc/uncore/sdc/SDC/sd_top/o_READY_FOR_READ
add wave -noupdate -expand -group SDC -group {Instruction Counter control} /testbench/dut/wallypipelinedsoc/uncore/sdc/SDC/sd_top/w_IC_EN
add wave -noupdate -expand -group SDC -group {Instruction Counter control} /testbench/dut/wallypipelinedsoc/uncore/sdc/SDC/sd_top/w_IC_RST
add wave -noupdate -expand -group SDC -group {Instruction Counter control} /testbench/dut/wallypipelinedsoc/uncore/sdc/SDC/sd_top/w_IC_UP_DOWN
add wave -noupdate -expand -group SDC -group {Instruction Counter control} /testbench/dut/wallypipelinedsoc/uncore/sdc/SDC/sd_top/r_IC_OUT
add wave -noupdate -group boottim /testbench/dut/wallypipelinedsoc/uncore/bootdtim/bootdtim/HADDR
add wave -noupdate -group boottim /testbench/dut/wallypipelinedsoc/uncore/bootdtim/bootdtim/A
add wave -noupdate -group boottim /testbench/dut/wallypipelinedsoc/uncore/bootdtim/bootdtim/HWADDR
@ -556,34 +560,55 @@ add wave -noupdate -group boottim /testbench/dut/wallypipelinedsoc/uncore/bootdt
add wave -noupdate -group boottim /testbench/dut/wallypipelinedsoc/uncore/bootdtim/bootdtim/HREADYTim
add wave -noupdate -group boottim /testbench/dut/wallypipelinedsoc/uncore/bootdtim/bootdtim/HRESPTim
add wave -noupdate -group boottim /testbench/dut/wallypipelinedsoc/uncore/bootdtim/bootdtim/initTrans
add wave -noupdate /testbench/dut/wallypipelinedsoc/uncore/sdc/SDC/SDCDataValid
add wave -noupdate /testbench/dut/wallypipelinedsoc/uncore/sdc/SDC/sd_top/w_instruction_control_bits
add wave -noupdate /testbench/dut/wallypipelinedsoc/uncore/sdc/SDC/sd_top/my_sd_cmd_fsm/w_error_result
add wave -noupdate /testbench/dut/wallypipelinedsoc/uncore/sdc/SDC/sd_top/my_sd_cmd_fsm/o_RX_SIPO48_EN
add wave -noupdate /testbench/dut/wallypipelinedsoc/uncore/sdc/SDC/sd_top/my_sd_cmd_fsm/i_RESPONSE_CONTENT
add wave -noupdate /testbench/dut/wallypipelinedsoc/uncore/sdc/SDC/sd_top/my_sd_cmd_fsm/i_NO_ERROR_MASK
add wave -noupdate /testbench/dut/wallypipelinedsoc/uncore/sdc/SDC/sd_top/my_sd_cmd_fsm/i_NO_ERROR_ANS
add wave -noupdate /testbench/dut/wallypipelinedsoc/uncore/sdc/SDC/sd_top/w_command_head
add wave -noupdate /testbench/dut/wallypipelinedsoc/uncore/sdc/SDC/sd_top/w_command_content
add wave -noupdate /testbench/dut/wallypipelinedsoc/uncore/sdc/SDC/sd_top/my_sd_cmd_fsm/i_ERROR_CRC16
add wave -noupdate /testbench/dut/wallypipelinedsoc/uncore/sdc/SDC/sd_top/r_DAT3_CRC16
add wave -noupdate /testbench/dut/wallypipelinedsoc/uncore/sdc/SDC/sd_top/r_DAT2_CRC16
add wave -noupdate /testbench/dut/wallypipelinedsoc/uncore/sdc/SDC/sd_top/r_DAT1_CRC16
add wave -noupdate /testbench/dut/wallypipelinedsoc/uncore/sdc/SDC/sd_top/r_DAT0_CRC16
add wave -noupdate /testbench/dut/wallypipelinedsoc/uncore/sdc/SDC/sd_top/w_DATA_CRC16_GOOD
add wave -noupdate -radix binary /testbench/sdcard/dataState
add wave -noupdate /testbench/sdcard/last_din
add wave -noupdate /testbench/sdcard/wide_data
add wave -noupdate /testbench/sdcard/write_out_index
add wave -noupdate /testbench/dut/wallypipelinedsoc/uncore/sdc/SDC/sd_top/w_R_TYPE
add wave -noupdate /testbench/dut/wallypipelinedsoc/uncore/sdc/SDC/sd_top/w_command_index
add wave -noupdate /testbench/dut/wallypipelinedsoc/uncore/sdc/SDC/sd_top/r_ACMD_Q
add wave -noupdate /testbench/dut/wallypipelinedsoc/uncore/sdc/SDC/sd_top/w_command_content
add wave -noupdate /testbench/dut/wallypipelinedsoc/uncore/sdc/SDC/sd_top/w_IC_EN
add wave -noupdate /testbench/dut/wallypipelinedsoc/uncore/sdc/SDC/sd_top/w_IC_RST
add wave -noupdate /testbench/dut/wallypipelinedsoc/uncore/sdc/SDC/sd_top/r_IC_OUT
add wave -noupdate -group other /testbench/dut/wallypipelinedsoc/uncore/sdc/SDC/SDCDataValid
add wave -noupdate -group other /testbench/dut/wallypipelinedsoc/uncore/sdc/SDC/sd_top/my_sd_cmd_fsm/w_error_result
add wave -noupdate -group other /testbench/dut/wallypipelinedsoc/uncore/sdc/SDC/sd_top/my_sd_cmd_fsm/o_RX_SIPO48_EN
add wave -noupdate -group other /testbench/dut/wallypipelinedsoc/uncore/sdc/SDC/sd_top/my_sd_cmd_fsm/i_RESPONSE_CONTENT
add wave -noupdate -group other /testbench/dut/wallypipelinedsoc/uncore/sdc/SDC/sd_top/my_sd_cmd_fsm/i_NO_ERROR_MASK
add wave -noupdate -group other /testbench/dut/wallypipelinedsoc/uncore/sdc/SDC/sd_top/my_sd_cmd_fsm/i_NO_ERROR_ANS
add wave -noupdate -group other /testbench/dut/wallypipelinedsoc/uncore/sdc/SDC/sd_top/w_command_head
add wave -noupdate -group other /testbench/dut/wallypipelinedsoc/uncore/sdc/SDC/sd_top/w_command_content
add wave -noupdate -group other /testbench/dut/wallypipelinedsoc/uncore/sdc/SDC/sd_top/my_sd_cmd_fsm/i_ERROR_CRC16
add wave -noupdate -group other /testbench/dut/wallypipelinedsoc/uncore/sdc/SDC/sd_top/r_DAT3_CRC16
add wave -noupdate -group other /testbench/dut/wallypipelinedsoc/uncore/sdc/SDC/sd_top/r_DAT2_CRC16
add wave -noupdate -group other /testbench/dut/wallypipelinedsoc/uncore/sdc/SDC/sd_top/r_DAT1_CRC16
add wave -noupdate -group other /testbench/dut/wallypipelinedsoc/uncore/sdc/SDC/sd_top/r_DAT0_CRC16
add wave -noupdate -group other /testbench/dut/wallypipelinedsoc/uncore/sdc/SDC/sd_top/w_DATA_CRC16_GOOD
add wave -noupdate -group other -radix binary /testbench/sdcard/dataState
add wave -noupdate -group other /testbench/sdcard/last_din
add wave -noupdate -group other /testbench/sdcard/wide_data
add wave -noupdate -group other /testbench/sdcard/write_out_index
add wave -noupdate -group other /testbench/dut/wallypipelinedsoc/uncore/sdc/SDC/sd_top/w_R_TYPE
add wave -noupdate -group other /testbench/dut/wallypipelinedsoc/uncore/sdc/SDC/sd_top/w_command_index
add wave -noupdate -group other /testbench/dut/wallypipelinedsoc/uncore/sdc/SDC/sd_top/r_ACMD_Q
add wave -noupdate -group other /testbench/dut/wallypipelinedsoc/uncore/sdc/SDC/sd_top/w_command_content
add wave -noupdate -group other /testbench/dut/wallypipelinedsoc/uncore/sdc/SDC/sd_top/my_sd_cmd_fsm/i_ERROR_CRC16
add wave -noupdate -group other /testbench/dut/wallypipelinedsoc/uncore/sdc/SDC/sd_top/my_sd_cmd_fsm/w_resend_last_command
add wave -noupdate -group other /testbench/dut/wallypipelinedsoc/uncore/sdc/SDC/sd_top/my_sd_cmd_fsm/w_redo_result
add wave -noupdate -group other /testbench/dut/wallypipelinedsoc/uncore/sdc/SDC/sd_top/my_sd_cmd_fsm/i_NO_REDO_ANS
add wave -noupdate -group other /testbench/dut/wallypipelinedsoc/uncore/sdc/SDC/sd_top/my_sd_cmd_fsm/i_OPCODE
add wave -noupdate -group other /testbench/dut/wallypipelinedsoc/uncore/sdc/SDC/sd_top/my_sd_cmd_fsm/i_NO_ERROR_ANS
add wave -noupdate -group other /testbench/dut/wallypipelinedsoc/uncore/sdc/SDC/sd_top/r_COUNTER_OUT
add wave -noupdate -group other /testbench/dut/wallypipelinedsoc/uncore/sdc/SDC/sd_top/w_COUNTER_EN
add wave -noupdate -group other /testbench/dut/wallypipelinedsoc/uncore/sdc/SDC/sd_top/w_COUNTER_LOAD
add wave -noupdate -group other /testbench/sdcard/OCR
add wave -noupdate -group other /testbench/sdcard/startUppCnt
add wave -noupdate -group other /testbench/sdcard/Busy
add wave -noupdate -group other /testbench/dut/wallypipelinedsoc/uncore/sdc/SDC/sd_top/my_sd_cmd_fsm/r_fail_count_out
add wave -noupdate -group other /testbench/dut/wallypipelinedsoc/uncore/sdc/SDC/sd_top/my_sd_cmd_fsm/w_fail_cnt_en
add wave -noupdate -group other /testbench/dut/wallypipelinedsoc/uncore/sdc/SDC/sd_top/my_sd_cmd_fsm/c_MAX_ATTEMPTS
add wave -noupdate -group other /testbench/dut/wallypipelinedsoc/uncore/sdc/SDC/sd_top/my_sd_cmd_fsm/w_ACMD41_times_out_FLAG
add wave -noupdate -group other /testbench/dut/wallypipelinedsoc/uncore/sdc/SDC/sd_top/my_sd_cmd_fsm/w_ACMD41_busy_timer_START
add wave -noupdate -group other /testbench/dut/wallypipelinedsoc/uncore/sdc/SDC/sd_top/my_sd_cmd_fsm/w_ACMD41_busy_timer_RST
add wave -noupdate -group other /testbench/dut/wallypipelinedsoc/uncore/sdc/SDC/sd_top/my_sd_cmd_fsm/w_bad_card
add wave -noupdate -group other /testbench/dut/wallypipelinedsoc/uncore/sdc/SDC/sd_top/my_sd_cmd_fsm/w_error_result
add wave -noupdate -group other -expand -group response /testbench/dut/wallypipelinedsoc/uncore/sdc/SDC/sd_top/my_sd_cmd_fsm/i_RESPONSE_CONTENT
add wave -noupdate -group other -expand -group response /testbench/dut/wallypipelinedsoc/uncore/sdc/SDC/sd_top/my_sd_cmd_fsm/i_NO_ERROR_MASK
add wave -noupdate -group other -expand -group response /testbench/dut/wallypipelinedsoc/uncore/sdc/SDC/sd_top/my_sd_cmd_fsm/i_NO_ERROR_ANS
add wave -noupdate /testbench/dut/wallypipelinedsoc/uncore/sdc/SDC/sd_top/my_sd_dat_fsm/i_DATA_CRC16_GOOD
TreeUpdate [SetDefaultTree]
WaveRestoreCursors {{Cursor 6} {8741 ns} 0} {{Cursor 3} {603500 ns} 1}
WaveRestoreCursors {{Cursor 6} {3445297 ns} 0} {{Cursor 3} {603500 ns} 1}
quietly wave cursor active 1
configure wave -namecolwidth 250
configure wave -valuecolwidth 297
@ -599,4 +624,4 @@ configure wave -griddelta 40
configure wave -timeline 0
configure wave -timelineunits ns
update
WaveRestoreZoom {0 ns} {5272104 ns}
WaveRestoreZoom {3445186 ns} {3445416 ns}

View File

@ -30,7 +30,7 @@ vlib work
# default to config/rv64ic, but allow this to be overridden at the command line. For example:
# do wally-pipelined.do ../config/rv32ic
switch $argc {
0 {vlog +incdir+../config/rv64BP +incdir+../config/shared ../testbench/testbench-fpga.sv ../testbench/common/*.sv ../src/*/*.sv ../src/wally/wallypipelinedsocwrapper.v -suppress 2583}
0 {vlog +incdir+../config/fpga +incdir+../config/shared ../testbench/testbench-fpga.sv ../testbench/common/*.sv ../src/*/*.sv ../src/wally/wallypipelinedsocwrapper.v ../../fpga/sim/*.sv -suppress 2583}
1 {vlog +incdir+$1 +incdir+../config/shared ../testbench/testbench-imperas.sv ../testbench/common/*.sv ../src/*/*.sv -suppress 2583}
}
# start and run simulation

View File

@ -28,35 +28,29 @@
module clockgater
(input logic E,
input logic SE,
(* gated_clock = "yes" *) input logic CLK,
input logic CLK,
output logic ECLK);
// VERY IMPORTANT.
// This part functionally models a clock gater, but does not necessarily meet the timing constrains a real standard cell would.
// Do not use this in synthesis!
logic enable_q;
/* -----\/----- EXCLUDED -----\/-----
always_latch begin
if(~CLK) begin
enable_q <= E | SE;
end
end
assign ECLK = enable_q & CLK;
-----/\----- EXCLUDED -----/\----- */
assign ECLK = CLK;
/* -----\/----- EXCLUDED -----\/-----
if (`XILINX) begin
if (`FPGA) begin
BUFGCE bufgce_i0 (
.I(CLK),
.CE(E | SE),
.O(ECLK)
);
end
-----/\----- EXCLUDED -----/\----- */
end else begin
// *** BUG
// VERY IMPORTANT.
// This part functionally models a clock gater, but does not necessarily meet the timing constrains a real standard cell would.
// Do not use this in synthesis!
logic enable_q;
always_latch begin
if(~CLK) begin
enable_q <= E | SE;
end
end
assign ECLK = enable_q & CLK;
end
endmodule

View File

@ -313,11 +313,16 @@ module SDC
.ECLK(CLKGate));
/* -----\/----- EXCLUDED -----\/-----
clkdivider #(8) clkdivider(.i_COUNT_IN_MAX(CLKDiv),
.i_EN(CLKDiv != 'b1),
.i_CLK(CLKGate),
.i_RST(~HRESETn | CLKDivUpdateEn),
.o_CLK(SDCCLKIn));
-----/\----- EXCLUDED -----/\----- */
assign SDCCLKIn = CLKGate;
sd_top sd_top(.CLK(SDCCLKIn),
.a_RST(~HRESETn),
@ -337,7 +342,7 @@ module SDC
.o_ERROR_CODE_Q(ErrorCode),
.o_FATAL_ERROR(FatalError),
.i_COUNT_IN_MAX(-8'd62),
.LIMIT_SD_TIMERS(1'b0)); // *** must change this to 0 for real hardware.
.LIMIT_SD_TIMERS(1'b1)); // *** must change this to 0 for real hardware.
endmodule

View File

@ -37,36 +37,56 @@ module clkdivider #(parameter integer g_COUNT_WIDTH)
);
logic [g_COUNT_WIDTH-1:0] r_count_out; // wider for sign
logic w_counter_overflowed;
generate
if(`FPGA) begin
logic CLKDiv8, CLKDiv64;
BUFGCE_DIV #("8") clkDivider1(.I(i_CLK),
.CLR(i_RST),
.CE(1'b1),
.O(CLKDiv8));
BUFGCE_DIV #("8") clkDivider2(.I(CLKDiv8),
.CLR(i_RST),
.CE(1'b1),
.O(CLKDiv64));
logic r_fd_Q;
logic w_fd_D;
BUFGMUX clkMux(.I1(CLKDiv64),
.I0(i_CLK),
.S(i_EN),
.O(o_CLK));
end else begin
logic [g_COUNT_WIDTH-1:0] r_count_out; // wider for sign
logic w_counter_overflowed;
logic w_load;
logic r_fd_Q;
logic w_fd_D;
assign w_load = i_RST | w_counter_overflowed; // reload when zero occurs or when set by outside
logic w_load;
counter #(.WIDTH(g_COUNT_WIDTH)) // wider for sign, this way the (MSB /= '1') only for zero
my_counter (.clk(i_CLK),
.Load(w_load), // reload when zero occurs or when set by outside
.CountIn(i_COUNT_IN_MAX), // negative signed integer
.CountOut(r_count_out),
.Enable(1'b1), // ALWAYS COUNT
.reset(1'b0)); // no reset, only load
assign w_load = i_RST | w_counter_overflowed; // reload when zero occurs or when set by outside
assign w_counter_overflowed = r_count_out[g_COUNT_WIDTH-1] == '0;
flopenr #(1) toggle_flip_flop
(.d(w_fd_D),
.q(r_fd_Q),
.clk(i_CLK),
.reset(i_RST), // reset when told by outside
.en(w_counter_overflowed)); // only update when counter overflows
counter #(.WIDTH(g_COUNT_WIDTH)) // wider for sign, this way the (MSB /= '1') only for zero
my_counter (.clk(i_CLK),
.Load(w_load), // reload when zero occurs or when set by outside
.CountIn(i_COUNT_IN_MAX), // negative signed integer
.CountOut(r_count_out),
.Enable(1'b1), // ALWAYS COUNT
.reset(1'b0)); // no reset, only load
assign w_fd_D = ~ r_fd_Q;
assign w_counter_overflowed = r_count_out[g_COUNT_WIDTH-1] == '0;
flopenr #(1) toggle_flip_flop
(.d(w_fd_D),
.q(r_fd_Q),
.clk(i_CLK),
.reset(i_RST), // reset when told by outside
.en(w_counter_overflowed)); // only update when counter overflows
assign o_CLK = i_EN ? r_fd_Q : i_CLK;
assign w_fd_D = ~ r_fd_Q;
assign o_CLK = i_EN ? r_fd_Q : i_CLK;
end
endgenerate
endmodule

View File

@ -136,7 +136,7 @@ module sd_cmd_fsm
localparam s_idle_for_read_request = 5'b11101; // After power up and initialization sequence is completed
localparam s_Error_TX_Failed = 5'b11110; // when fail_cnt_out exceeds c_max_attempts
localparam c_MAX_ATTEMPTS = 3; // Give up sending a command after 3 failed attempts
localparam c_MAX_ATTEMPTS = 1500; // Give up sending a command after 3 failed attempts
// (except ACMD41) so the processor is not locked up forever
localparam c_response_type_R0_NONE = 0;
@ -252,6 +252,20 @@ module sd_cmd_fsm
.clk(CLK));
assign o_ERROR_CODE_Q = r_ERROR_CODE_Q;
assign COUNTER_OUT_GT_ZERO = i_COUNTER_OUT > 0;
assign COUNTER_OUT_GE_ZERO = i_COUNTER_OUT >= 0;
assign COUNTER_OUT_GT_8 = i_COUNTER_OUT > 8;
assign COUNTER_OUT_EQ_8 = i_COUNTER_OUT == 8;
assign COUNTER_OUT_EQ_ZERO = i_COUNTER_OUT == 0;
assign TIMER_OUT_GT_ZERO = i_TIMER_OUT > 0;
assign TIMER_OUT_EQ_ZERO = i_TIMER_OUT == 0;
assign fail_count_out_le_max_attempts = r_fail_count_out <= (c_MAX_ATTEMPTS-1);
assign fail_count_out_lt_max_attempts = r_fail_count_out < (c_MAX_ATTEMPTS-1);
assign fail_count_out_gt_max_attempts = r_fail_count_out > (c_MAX_ATTEMPTS-1);
assign IC_OUT_EQ_2 = i_IC_OUT == 2;
assign IC_OUT_EQ_3 = i_IC_OUT == 3;
assign IC_OUT_LT_9 = i_IC_OUT < 9;
assign IC_OUT_GE_9 = i_IC_OUT >= 9;
assign w_next_state = i_RST ? s_reset_clear_error_reg :
@ -263,53 +277,53 @@ module sd_cmd_fsm
((r_curr_state == s_reset_from_error) |
((r_curr_state == s_idle_supply_no_clk) & (i_TIMER_OUT > 0))) ? s_idle_supply_no_clk :
((r_curr_state == s_idle_supply_no_clk) & (TIMER_OUT_GT_ZERO))) ? s_idle_supply_no_clk :
(((r_curr_state == s_idle_supply_no_clk) & (i_TIMER_OUT == 0)) |
((r_curr_state == s_idle_supply_sd_clk) & (i_COUNTER_OUT > 0))) ? s_idle_supply_sd_clk :
(((r_curr_state == s_idle_supply_no_clk) & (TIMER_OUT_EQ_ZERO)) |
((r_curr_state == s_idle_supply_sd_clk) & (COUNTER_OUT_GT_ZERO))) ? s_idle_supply_sd_clk :
(r_curr_state == s_ld_head) ? s_count_attempt :
(((r_curr_state == s_count_attempt) & (r_fail_count_out <= (c_MAX_ATTEMPTS-1))) |
(((r_curr_state == s_count_attempt) & (fail_count_out_le_max_attempts)) |
((r_curr_state == s_count_attempt) &
(((i_IC_OUT == 2) & (i_OPCODE[5:0] == c_App_Command)) |
((i_IC_OUT == 3) & (i_OPCODE == ({c_ACMD, c_SD_Send_OCR})))) // to work CMD55, ACMD41 MUST be lines 2, 3 of instruction fetch mux of sd_top.vhd
(((IC_OUT_EQ_2) & (i_OPCODE[5:0] == c_App_Command)) |
((IC_OUT_EQ_3) & (i_OPCODE == ({c_ACMD, c_SD_Send_OCR})))) // to work CMD55, ACMD41 MUST be lines 2, 3 of instruction fetch mux of sd_top.vhd
& (w_ACMD41_times_out_FLAG)
& (r_fail_count_out > (c_MAX_ATTEMPTS-1)))) ? s_tx_head :
& (fail_count_out_gt_max_attempts))) ? s_tx_head :
((r_curr_state == s_count_attempt) & (r_fail_count_out > (c_MAX_ATTEMPTS-1))) ? s_Error_TX_Failed :
((r_curr_state == s_count_attempt) & (fail_count_out_gt_max_attempts)) ? s_Error_TX_Failed :
((r_curr_state == s_tx_head) | ((r_curr_state == s_ld_tail) & (i_COUNTER_OUT > 8))) ? s_ld_tail :
((r_curr_state == s_tx_head) | ((r_curr_state == s_ld_tail) & (COUNTER_OUT_GT_8))) ? s_ld_tail :
(((r_curr_state == s_ld_tail) & (i_COUNTER_OUT == 8)) |
((r_curr_state == s_tx_tail) & (i_COUNTER_OUT > 0))) ? s_tx_tail :
(((r_curr_state == s_ld_tail) & (COUNTER_OUT_EQ_8)) |
((r_curr_state == s_tx_tail) & (COUNTER_OUT_GT_ZERO))) ? s_tx_tail :
(r_curr_state == s_tx_tail) & (i_COUNTER_OUT == 0) ? s_setup_rx :
(r_curr_state == s_tx_tail) & (COUNTER_OUT_EQ_ZERO) ? s_setup_rx :
(((r_curr_state == s_setup_rx) & (i_R_TYPE == c_response_type_R0_NONE)) |
((r_curr_state == s_idle_ncc) & (i_COUNTER_OUT > 0))) ? s_idle_ncc :
((r_curr_state == s_idle_ncc) & (COUNTER_OUT_GT_ZERO))) ? s_idle_ncc :
(((r_curr_state == s_setup_rx) & (i_R_TYPE != c_response_type_R0_NONE)) |
((r_curr_state == s_idle_for_start_bit) & (i_SD_CMD_RX != c_start_bit) &
(i_COUNTER_OUT > 0))) ? s_idle_for_start_bit :
(COUNTER_OUT_GT_ZERO))) ? s_idle_for_start_bit :
((r_curr_state == s_idle_for_start_bit) & (i_SD_CMD_RX != c_start_bit) &
(i_COUNTER_OUT == 0)) ? s_error_no_response :
(COUNTER_OUT_EQ_ZERO)) ? s_error_no_response :
(((r_curr_state == s_idle_for_start_bit) & (i_SD_CMD_RX == c_start_bit) &
/* verilator lint_off UNSIGNED */
(i_COUNTER_OUT >= 0) & (i_R_TYPE == c_response_type_R2_CID_CSD)) |
(COUNTER_OUT_GE_ZERO) & (i_R_TYPE == c_response_type_R2_CID_CSD)) |
/* verilator lint_on UNSIGNED */
((r_curr_state == s_rx_136) & (i_COUNTER_OUT > 0))) ? s_rx_136 :
((r_curr_state == s_rx_136) & (COUNTER_OUT_GT_ZERO))) ? s_rx_136 :
(((r_curr_state == s_idle_for_start_bit) & (i_SD_CMD_RX == c_start_bit) &
/* verilator lint_off UNSIGNED */
(i_COUNTER_OUT >= 0) & (i_R_TYPE != c_response_type_R2_CID_CSD)) |
(COUNTER_OUT_GE_ZERO) & (i_R_TYPE != c_response_type_R2_CID_CSD)) |
/* verilator lint_on UNSIGNED */
((r_curr_state == s_rx_48) & (i_COUNTER_OUT > 0))) ? s_rx_48 :
((r_curr_state == s_rx_48) & (COUNTER_OUT_GT_ZERO))) ? s_rx_48 :
(((r_curr_state == s_rx_136) & (i_COUNTER_OUT == 0)) |
((r_curr_state == s_rx_48) & (i_COUNTER_OUT) == 0)) ? s_study_response :
(((r_curr_state == s_rx_136) & (COUNTER_OUT_EQ_ZERO)) |
((r_curr_state == s_rx_48) & COUNTER_OUT_EQ_ZERO)) ? s_study_response :
(r_curr_state == s_study_response) & w_bad_card ? s_error_bad_card :
@ -322,32 +336,32 @@ module sd_cmd_fsm
(~i_ERROR_DAT_TIMES_OUT)) |
((r_curr_state == s_study_response) & (~w_bad_card) &
(i_USES_DAT == c_DAT_none)) |
((r_curr_state == s_idle_nrc) & (i_COUNTER_OUT > 0))) ? s_idle_nrc :
((r_curr_state == s_idle_nrc) & (COUNTER_OUT_GT_ZERO))) ? s_idle_nrc :
((r_curr_state == s_idle_nrc) & (i_COUNTER_OUT == 0) &
((r_curr_state == s_idle_nrc) & (COUNTER_OUT_EQ_ZERO) &
(w_resend_last_command) & ((i_OPCODE[6] == c_ACMD) &
((i_OPCODE[5:0]) != c_App_Command))) ? s_fetch_prev_cmd :
((r_curr_state == s_fetch_prev_cmd) |
((r_curr_state == s_idle_supply_sd_clk) & (i_COUNTER_OUT == 0)) |
((r_curr_state == s_idle_supply_sd_clk) & (COUNTER_OUT_EQ_ZERO)) |
((r_curr_state == s_fetch_next_cmd) & // before CMD17
(i_IC_OUT < 9)) | // blindly load head of next command
(IC_OUT_LT_9)) | // blindly load head of next command
((r_curr_state == s_idle_for_read_request) & (i_READ_REQUEST)) | // got the request, load head
((r_curr_state == s_idle_nrc) & (i_COUNTER_OUT == 0) &
((r_curr_state == s_idle_nrc) & (COUNTER_OUT_EQ_ZERO) &
(w_resend_last_command) & ((i_OPCODE[6] == c_CMD) |
((i_OPCODE[5:0]) == c_App_Command)))) ? s_ld_head :
(((r_curr_state == s_idle_nrc) & (i_COUNTER_OUT == 0) &
(((r_curr_state == s_idle_nrc) & (COUNTER_OUT_EQ_ZERO) &
(~w_resend_last_command) & ((i_OPCODE) == ({c_CMD, c_Switch_Function}))) |
((r_curr_state == s_idle_for_clock_change) & (~i_CLOCK_CHANGE_DONE))) ? s_idle_for_clock_change :
(((r_curr_state == s_idle_ncc) & (i_COUNTER_OUT == 0)) |
((r_curr_state == s_idle_nrc) & (i_COUNTER_OUT == 0) &
(((r_curr_state == s_idle_ncc) & (COUNTER_OUT_EQ_ZERO)) |
((r_curr_state == s_idle_nrc) & (COUNTER_OUT_EQ_ZERO) &
(~w_resend_last_command) & ((i_OPCODE) != ({c_CMD, c_Switch_Function}))) |
((r_curr_state == s_idle_for_clock_change) & (i_CLOCK_CHANGE_DONE))) ? s_fetch_next_cmd :
(((r_curr_state == s_fetch_next_cmd) &
(i_IC_OUT >= 9)) | // During and after CMD17, wait for request to send CMD17 from core
(IC_OUT_GE_9)) | // During and after CMD17, wait for request to send CMD17 from core
// waiting for request
(r_curr_state == s_idle_for_read_request)) ? s_idle_for_read_request :

View File

@ -28,14 +28,14 @@
module sd_top #(parameter g_COUNT_WIDTH = 8)
(
input logic CLK, // 1.2 GHz (1.0 GHz typical)
input logic a_RST, // Reset signal (Must be held for minimum of 24 clock cycles)
(* mark_debug = "true" *)input logic a_RST, // Reset signal (Must be held for minimum of 24 clock cycles)
// a_RST MUST COME OUT OF RESET SYNCHRONIZED TO THE 1.2 GHZ CLOCK!
// io_SD_CMD_z : inout std_logic; // SD CMD Bus
(* mark_debug = "true" *)input logic i_SD_CMD, // CMD Response from card
(* mark_debug = "true" *)output logic o_SD_CMD, // CMD Command from host
(* mark_debug = "true" *)output logic o_SD_CMD_OE, // Direction of SD_CMD
(* mark_debug = "true" *)input logic [3:0] i_SD_DAT, // SD DAT Bus
(* mark_debug = "true" *)output logic o_SD_CLK, // SD CLK Bus
(* mark_debug = "true" *)input logic i_SD_CMD, // CMD Response from card
(* mark_debug = "true" *)output logic o_SD_CMD, // CMD Command from host
(* mark_debug = "true" *)output logic o_SD_CMD_OE, // Direction of SD_CMD
(* mark_debug = "true" *)input logic [3:0] i_SD_DAT, // SD DAT Bus
(* mark_debug = "true" *)output logic o_SD_CLK, // SD CLK Bus
// For communication with core cpu
input logic [32:9] i_BLOCK_ADDR, // see "Addressing" in parts.fods (only 8GB total capacity is used)
output logic o_READY_FOR_READ, // tells core that initialization sequence is completed and
@ -140,10 +140,10 @@ module sd_top #(parameter g_COUNT_WIDTH = 8)
localparam logic [127:96] c_CMD17_mask_check_error_bits = 32'hCF398000;
localparam logic [127:96] c_CMD17_ans_error_free = 32'h00000000;
localparam logic [127:96] c_ACMD41_mask_check_redo_bits = 32'h80000000; // SD_Send_OCR
localparam logic [127:96] c_ACMD41_ans_dont_redo = 32'h80000000;
localparam logic [127:96] c_ACMD41_mask_check_error_bits = 32'h01FF8000; // 32'h41FF8000;
localparam logic [127:96] c_ACMD41_ans_error_free = 32'h00FF8000; // 32'h40FF8000
localparam logic [127:96] c_ACMD41_mask_check_redo_bits = 32'h80000000; //32'h80000000; // SD_Send_OCR
localparam logic [127:96] c_ACMD41_ans_dont_redo = 32'h80000000; //32'h80000000;
localparam logic [127:96] c_ACMD41_mask_check_error_bits = 32'h41FF8000; // 32'h41FF8000;
localparam logic [127:96] c_ACMD41_ans_error_free = 32'h40FF8000; // 32'h40FF8000
localparam logic [127:96] c_CMD55_mask_check_redo_bits = 32'h00000000; // App_Command
localparam logic [127:96] c_CMD55_ans_dont_redo = 32'h00000000;
@ -491,8 +491,8 @@ module sd_top #(parameter g_COUNT_WIDTH = 8)
// Clock selection
clkdivider #(g_COUNT_WIDTH) slow_clk_divider // Divide 50 MHz to <400 KHz (Initial clock)
(.i_COUNT_IN_MAX(i_COUNT_IN_MAX),
//.i_EN(w_SD_CLK_SELECTED),
.i_EN(1'b1),
.i_EN(w_SD_CLK_SELECTED),
//.i_EN(1'b1),
.i_RST(w_HS_TO_INIT_CLK_DIVIDER_RST),
.i_CLK(CLK),
.o_CLK(r_CLK_SD));
@ -596,20 +596,19 @@ module sd_top #(parameter g_COUNT_WIDTH = 8)
1'b0;
assign w_SD_CMD_RX = i_SD_CMD;
assign r_G_CLK_SD_n = ~r_G_CLK_SD;
flopenr #(1) sd_cmd_out_reg
(.d(w_SD_CMD_TX_Q),
.q(o_SD_CMD),
.en(1'b1),
.clk(r_G_CLK_SD_n),
.clk(~r_G_CLK_SD),
.reset(a_RST));
flopenr #(1) sd_cmd_out_oe_reg
(.d(w_SD_CMD_OE),
.q(o_SD_CMD_OE),
.en(1'b1),
.clk(r_G_CLK_SD_n),
.clk(~r_G_CLK_SD),
.reset(a_RST));
// RX

View File

@ -11,7 +11,7 @@
`define BLOCKSIZE 512
`define MEMSIZE 24643590 // 2mb block
`define BLOCK_BUFFER_SIZE 1
`define TIME_BUSY 63
`define TIME_BUSY 512
`define PRG 7
`define RCV 6
@ -137,7 +137,7 @@ module sdModel
reg stop;
reg appendCrc;
reg [5:0] startUppCnt;
reg [31:0] startUppCnt;
reg q_start_bit;