mirror of
https://github.com/openhwgroup/cvw
synced 2025-02-11 06:05:49 +00:00
Fixed sdc byte and nibble orders.
This commit is contained in:
parent
2e0dcaaff9
commit
cbf4e76d1c
@ -79,6 +79,7 @@ module SDC
|
||||
|
||||
logic SDCDataValid;
|
||||
logic [`XLEN-1:0] SDCReadData;
|
||||
logic [`XLEN-1:0] SDCReadDataPreNibbleSwap;
|
||||
logic [`XLEN-1:0] SDCWriteData;
|
||||
logic FatalError;
|
||||
|
||||
@ -206,7 +207,16 @@ module SDC
|
||||
assign ReadData512ByteWords[index] = ReadData512Byte[(index+1)*`XLEN-1:index*`XLEN];
|
||||
end
|
||||
|
||||
assign SDCReadData = ReadData512ByteWords[WordCount];
|
||||
assign SDCReadDataPreNibbleSwap = ReadData512ByteWords[WordCount];
|
||||
assign SDCReadData = {SDCReadDataPreNibbleSwap[59:56], SDCReadDataPreNibbleSwap[63:60],
|
||||
SDCReadDataPreNibbleSwap[51:48], SDCReadDataPreNibbleSwap[55:52],
|
||||
SDCReadDataPreNibbleSwap[43:40], SDCReadDataPreNibbleSwap[47:44],
|
||||
SDCReadDataPreNibbleSwap[35:32], SDCReadDataPreNibbleSwap[39:36],
|
||||
SDCReadDataPreNibbleSwap[27:24], SDCReadDataPreNibbleSwap[31:28],
|
||||
SDCReadDataPreNibbleSwap[19:16], SDCReadDataPreNibbleSwap[23:20],
|
||||
SDCReadDataPreNibbleSwap[11:8], SDCReadDataPreNibbleSwap[15:12],
|
||||
SDCReadDataPreNibbleSwap[3:0], SDCReadDataPreNibbleSwap[7:4]};
|
||||
|
||||
|
||||
flopenr #($clog2(4096/`XLEN)) WordCountReg
|
||||
(.clk(HCLK),
|
||||
|
@ -216,6 +216,23 @@ module sd_cmd_fsm
|
||||
localparam c_increment = 1'b1; // count <= count + 1
|
||||
localparam c_decrement = 1'b0; // count <= count - 1
|
||||
|
||||
|
||||
logic COUNTER_OUT_GT_ZERO;
|
||||
logic COUNTER_OUT_GE_ZERO;
|
||||
logic COUNTER_OUT_GT_8;
|
||||
logic COUNTER_OUT_EQ_8;
|
||||
logic COUNTER_OUT_EQ_ZERO;
|
||||
logic TIMER_OUT_GT_ZERO;
|
||||
logic TIMER_OUT_EQ_ZERO;
|
||||
logic fail_count_out_le_max_attempts;
|
||||
logic fail_count_out_lt_max_attempts;
|
||||
logic fail_count_out_gt_max_attempts;
|
||||
logic IC_OUT_EQ_2;
|
||||
logic IC_OUT_EQ_3;
|
||||
logic IC_OUT_LT_9;
|
||||
logic IC_OUT_GE_9;
|
||||
|
||||
|
||||
assign Timer_In = LIMIT_SD_TIMERS ? 19'b0000000000000000011 : 19'b0011000011010100000; // 250 ms
|
||||
|
||||
//Fail Counter, tracks how many failed attempts at command transmission
|
||||
@ -260,12 +277,12 @@ module sd_cmd_fsm
|
||||
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 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 IC_OUT_GE_9 = i_IC_OUT >= 9;
|
||||
|
||||
assign w_next_state = i_RST ? s_reset_clear_error_reg :
|
||||
|
||||
|
@ -98,6 +98,18 @@ module sd_dat_fsm
|
||||
localparam logic c_HS_clock = 1'b0; // use after CMD6 switches clock frequency (CMD17)
|
||||
|
||||
|
||||
logic TIMER_OUT_GT_0;
|
||||
logic TIMER_OUT_EQ_0;
|
||||
logic COUNTER_OUT_EQ_1023;
|
||||
logic COUNTER_OUT_LT_1023;
|
||||
logic COUNTER_OUT_LT_128;
|
||||
logic COUNTER_OUT_EQ_128;
|
||||
logic COUNTER_OUT_LT_144;
|
||||
logic COUNTER_OUT_EQ_144;
|
||||
logic COUNTER_OUT_LT_1040;
|
||||
logic COUNTER_OUT_EQ_1040;
|
||||
|
||||
|
||||
assign Identify_Timer_In = LIMIT_SD_TIMERS ? 23'b00000000000000001100011 : 23'b00000001001110001000000; // 40,000 unsigned.
|
||||
assign Data_TX_Timer_In = LIMIT_SD_TIMERS ? 23'b00000000000000001100011 : 23'b11110100001001000000000; // 8,000,000 unsigned.
|
||||
|
||||
@ -107,12 +119,23 @@ module sd_dat_fsm
|
||||
.d(w_next_state),
|
||||
.q(r_curr_state));
|
||||
|
||||
assign TIMER_OUT_GT_0 = i_TIMER_OUT > 0;
|
||||
assign TIMER_OUT_EQ_0 = i_TIMER_OUT == 0;
|
||||
assign COUNTER_OUT_EQ_1023 = i_COUNTER_OUT == 1023;
|
||||
assign COUNTER_OUT_LT_1023 = i_COUNTER_OUT < 1023;
|
||||
assign COUNTER_OUT_LT_128 = i_COUNTER_OUT < 128;
|
||||
assign COUNTER_OUT_EQ_128 = i_COUNTER_OUT == 128;
|
||||
assign COUNTER_OUT_LT_144 = i_COUNTER_OUT < 144;
|
||||
assign COUNTER_OUT_EQ_144 = i_COUNTER_OUT == 144;
|
||||
assign COUNTER_OUT_LT_1040 = i_COUNTER_OUT < 1040;
|
||||
assign COUNTER_OUT_EQ_1040 = i_COUNTER_OUT == 1040;
|
||||
|
||||
assign w_next_state = ((i_RST) |
|
||||
(r_curr_state == s_error_time_out) | // noticed this change is needed during emulation
|
||||
(r_curr_state == s_notify_r1b_completed) |
|
||||
(r_curr_state == s_error_crc16_fail) |
|
||||
(r_curr_state == s_publish_wide_data) |
|
||||
((r_curr_state == s_publish_block_data) & (i_COUNTER_OUT == 1023))) ? s_reset :
|
||||
((r_curr_state == s_publish_block_data) & (COUNTER_OUT_EQ_1023))) ? s_reset :
|
||||
|
||||
((r_curr_state == s_reset) |
|
||||
((r_curr_state == s_idle) & ((i_USES_DAT == c_DAT_none) | ((i_USES_DAT != c_DAT_none) & (~i_CMD_TX_DONE))))) ? s_idle :
|
||||
@ -124,46 +147,46 @@ module sd_dat_fsm
|
||||
((r_curr_state == s_reset_wide_data) |
|
||||
((r_curr_state == s_idle) & (i_USES_DAT == c_DAT_busy) & (i_CMD_TX_DONE)) |
|
||||
(r_curr_state == s_reset_block_data) |
|
||||
((r_curr_state == s_idle_for_start_bit) & (i_TIMER_OUT > 0) & (i_DAT0_Q != c_start_bit))) ? s_idle_for_start_bit :
|
||||
((r_curr_state == s_idle_for_start_bit) & (TIMER_OUT_GT_0) & (i_DAT0_Q != c_start_bit))) ? s_idle_for_start_bit :
|
||||
|
||||
((r_curr_state == s_idle_for_start_bit) & // Apparently R1b's busy signal is optional,
|
||||
(i_TIMER_OUT == 0) & // Even if it never shows up,
|
||||
(TIMER_OUT_EQ_0) & // Even if it never shows up,
|
||||
(i_USES_DAT == c_DAT_busy)) ? s_notify_r1b_completed : // pretend it did, & move on
|
||||
|
||||
(((r_curr_state == s_idle_for_start_bit) & (i_TIMER_OUT > 0) &
|
||||
(((r_curr_state == s_idle_for_start_bit) & (TIMER_OUT_GT_0) &
|
||||
(i_DAT0_Q == c_start_bit) & (i_USES_DAT == c_DAT_busy)) |
|
||||
((r_curr_state == s_read_r1b) & (i_TIMER_OUT > 0) & (i_DAT0_Q == c_busy_bit))) ? s_read_r1b :
|
||||
((r_curr_state == s_read_r1b) & (TIMER_OUT_GT_0) & (i_DAT0_Q == c_busy_bit))) ? s_read_r1b :
|
||||
|
||||
(((r_curr_state == s_read_r1b) & (i_TIMER_OUT == 0)) |
|
||||
((r_curr_state == s_idle_for_start_bit) & (i_TIMER_OUT == 0) &
|
||||
(((r_curr_state == s_read_r1b) & (TIMER_OUT_EQ_0)) |
|
||||
((r_curr_state == s_idle_for_start_bit) & (TIMER_OUT_EQ_0) &
|
||||
(i_USES_DAT != c_DAT_busy))) ? s_error_time_out :
|
||||
|
||||
((r_curr_state == s_read_r1b) & (i_DAT0_Q != c_busy_bit)) ? s_notify_r1b_completed :
|
||||
|
||||
(((r_curr_state == s_idle_for_start_bit) & (i_TIMER_OUT > 0) & (i_DAT0_Q == c_start_bit) &
|
||||
(((r_curr_state == s_idle_for_start_bit) & (TIMER_OUT_GT_0) & (i_DAT0_Q == c_start_bit) &
|
||||
(i_USES_DAT == c_DAT_wide)) |
|
||||
((r_curr_state == s_rx_wide_data) & (i_COUNTER_OUT < 128))) ? s_rx_wide_data :
|
||||
((r_curr_state == s_rx_wide_data) & (COUNTER_OUT_LT_128))) ? s_rx_wide_data :
|
||||
|
||||
(((r_curr_state == s_idle_for_start_bit) & (i_TIMER_OUT > 0) &
|
||||
(((r_curr_state == s_idle_for_start_bit) & (TIMER_OUT_GT_0) &
|
||||
(i_DAT0_Q == c_start_bit) & (i_USES_DAT == c_DAT_block)) |
|
||||
((r_curr_state == s_rx_block_data) & (i_COUNTER_OUT < 1023))) ? s_rx_block_data :
|
||||
((r_curr_state == s_rx_block_data) & (COUNTER_OUT_LT_1023))) ? s_rx_block_data :
|
||||
|
||||
(((r_curr_state == s_rx_wide_data) & (i_COUNTER_OUT == 128)) |
|
||||
((r_curr_state == s_rx_block_data) & (i_COUNTER_OUT == 1023)) |
|
||||
(((r_curr_state == s_rx_wide_data) & (COUNTER_OUT_EQ_128)) |
|
||||
((r_curr_state == s_rx_block_data) & (COUNTER_OUT_EQ_1023)) |
|
||||
((r_curr_state == s_rx_crc16) &
|
||||
(((i_USES_DAT == c_DAT_wide) & (i_COUNTER_OUT < 144)) |
|
||||
((i_USES_DAT == c_DAT_block) & (i_COUNTER_OUT < 1040))))) ? s_rx_crc16 :
|
||||
(((i_USES_DAT == c_DAT_wide) & (COUNTER_OUT_LT_144)) |
|
||||
((i_USES_DAT == c_DAT_block) & (COUNTER_OUT_LT_1040))))) ? s_rx_crc16 :
|
||||
|
||||
((r_curr_state == s_rx_crc16) &
|
||||
(((i_USES_DAT == c_DAT_wide) & (i_COUNTER_OUT == 144)) |
|
||||
((i_USES_DAT == c_DAT_block) & (i_COUNTER_OUT == 1040))) &
|
||||
(((i_USES_DAT == c_DAT_wide) & (COUNTER_OUT_EQ_144)) |
|
||||
((i_USES_DAT == c_DAT_block) & (COUNTER_OUT_EQ_1040))) &
|
||||
(~i_DATA_CRC16_GOOD)) ? s_error_crc16_fail :
|
||||
|
||||
((r_curr_state == s_rx_crc16) & (i_USES_DAT == c_DAT_wide) & (i_COUNTER_OUT == 144) &
|
||||
((r_curr_state == s_rx_crc16) & (i_USES_DAT == c_DAT_wide) & (COUNTER_OUT_EQ_144) &
|
||||
(i_DATA_CRC16_GOOD)) ? s_publish_wide_data :
|
||||
|
||||
((r_curr_state == s_rx_crc16) &
|
||||
(i_USES_DAT == c_DAT_block) & (i_COUNTER_OUT == 1040) & (i_DATA_CRC16_GOOD)) ? s_reset_nibble_counter :
|
||||
(i_USES_DAT == c_DAT_block) & (COUNTER_OUT_EQ_1040) & (i_DATA_CRC16_GOOD)) ? s_reset_nibble_counter :
|
||||
|
||||
((r_curr_state == s_reset_nibble_counter)) ? s_publish_block_data :
|
||||
|
||||
@ -219,7 +242,7 @@ module sd_dat_fsm
|
||||
assign o_DATA_VALID = (r_curr_state == s_publish_block_data);
|
||||
|
||||
assign o_LAST_NIBBLE = ((r_curr_state == s_publish_block_data)
|
||||
& (i_COUNTER_OUT == 1023)) | (r_curr_state == s_error_time_out); // notify done if errors occur
|
||||
& (COUNTER_OUT_EQ_1023)) | (r_curr_state == s_error_time_out); // notify done if errors occur
|
||||
|
||||
// o_ERROR_CRC16 (note: saved to flip flop because otherwise is only 1 clock cycle, not what I want)
|
||||
assign o_DAT_ERROR_FD_RST = (r_curr_state == s_reset_block_data) | (r_curr_state == s_reset_wide_data);
|
||||
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user