📄 sdcard_spi.vhd
字号:
process(cnt_8)
begin
if cnt_8>3 then
clk0<='1';
else
clk0<='0';
end if;
end process;
-- test_is_cmd<=is_cmd;
-- test_is_start_block<=is_start_block;
-- test_din_8<=din_8;
-- test_crc_result_cmd<=crc_result_cmd;
-- test_crc_result_data<=crc_result_data;
-- do<=clk0;
------main part------
r_clk0 <= not clk0;
process(res, clk0, cs)
begin
if res='1' then
current_state<=inactive_state;
elsif clk0='1' and clk0'event and cs='0' then
current_state<=next_state;
end if;
end process;
cmd_id<=conv_integer(din_8(45 downto 40));
--it is the process to calculate the next state of state machine
process(current_state, valid_cmd, reading_finished, writing_finished, sendr3_finished, sendnum_finished, erasing_finished, din_8, is_cmd, is_start_block, crc_result_cmd, crc_result_data, last_is_cmd55, write_terminated, read_terminated, data_ended, callingcmd58_state, cmd_id, cur_address, real_address)
begin
if current_state(0)='1' then
if is_cmd='1' and crc_result_cmd='0' and cmd_id=0 then
next_state<=standby_state;
else
next_state<=current_state;
end if;
elsif current_state(1)='1' then
if valid_cmd='1' and cmd_id=0 then
next_state<=inactive_state;
elsif is_cmd='1' and crc_result_cmd='0' and ((cmd_id=1 and last_is_cmd55='0') or (cmd_id=41 and last_is_cmd55='1')) then
next_state<=working_state;
elsif is_cmd='1' and crc_result_cmd='0' and cmd_id=58 and last_is_cmd55='0' then
next_state<=sendr3_state;
else
next_state<=current_state;
end if;
elsif current_state(2)='1' then
if is_cmd='1' and crc_result_cmd='0' then
if (cmd_id=0 and last_is_cmd55='0') then
next_state<=inactive_state;
elsif (cmd_id=9 or cmd_id=10 or cmd_id=17 or cmd_id=18) and last_is_cmd55='0' then
next_state<=toread_state;
elsif cmd_id=13 and last_is_cmd55='0' then
next_state<=sendr2_state;
elsif cmd_id=58 and last_is_cmd55='0' then
next_state<=sendr3_state;
elsif (cmd_id=24 or cmd_id=25) and last_is_cmd55='0' then
next_state<=towrite_state;
elsif cmd_id=38 and last_is_cmd55='0' then
next_state<=erasing_state;
elsif cmd_id=22 and last_is_cmd55='1' then
next_state<=swrited_block_state;
else
next_state<=current_state;
end if;
else
next_state<=current_state;
end if;
elsif current_state(3)='1' then
next_state<=working_state;
elsif current_state(4)='1' then
if sendr3_finished='1' then
next_state<=callingcmd58_state;
else
next_state<=current_state;
end if;
elsif current_state(5)='1' then
if read_terminated='1' then
next_state<=working_state;
else
next_state<=reading_state;
end if;
elsif current_state(6)='1' then
if reading_finished='1' then
next_state<=toread_state;
else
next_state<=current_state;
end if;
elsif current_state(7)='1' then
if write_terminated='1' then
next_state<=working_state;
elsif is_start_block='1' then
next_state<=buffering_state;
else
next_state<=current_state;
end if;
elsif current_state(8)='1' then
if data_ended='1' then
if crc_result_data='1' or (cur_address>sd_card_size-write_block_length and real_address='1') then
next_state<=towrite_state;
else
next_state<=writing_state;
end if;
else
next_state<=current_state;
end if;
elsif current_state(9)='1' then
if writing_finished='1' then
next_state<=towrite_state;
else
next_state<=current_state;
end if;
elsif current_state(10)='1' then
if erasing_finished='1' then
next_state<=working_state;
else
next_state<=current_state;
end if;
else
if sendnum_finished='1' then
next_state<=working_state;
else
next_state<=current_state;
end if;
end if;
end process;
valid_cmd<=is_cmd and (not crc_result_cmd) and (not last_is_cmd55);
valid_cmd_a<=is_cmd and (not crc_result_cmd) and last_is_cmd55;
process(clk0, res, cs)
begin
if res='1' then
last_is_cmd55<='0';
elsif clk0='1' and clk0'event and cs='0' then
if is_cmd='1' then
if cmd_id=55 and current_state(0)/='1' and last_is_cmd55='0' then
last_is_cmd55<='1';
else
last_is_cmd55<='0';
end if;
end if;
end if;
end process;
process(clk0, res, cs)
begin
if res='1' then
callingcmd58_state<=(others=>'0');
elsif clk0='1' and clk0'event and cs='0' then
if valid_cmd='1' and cmd_id=58 then
if current_state(1)='1' or current_state(2)='1' then
callingcmd58_state<=current_state;
end if;
end if;
end if;
end process;
process(clk0, res, cmd_id, is_multi_read, reading_finished, valid_cmd, cs)
begin
if res='1' then
read_terminated<='0';
elsif clk0='1' and clk0'event and cs='0' then
if (is_multi_read='0' and current_state(6)='1' and reading_finished='1') or
(valid_cmd='1' and cmd_id=12 and (current_state(5)='1' or current_state(6)='1')) then
read_terminated<='1';
elsif (current_state(2)='1' and next_state(5)='1') or (current_state(5)='1' and read_terminated='1') then
read_terminated<='0';
end if;
end if;
end process;
process(clk0, res, is_multi_write, writing_finished, cs)
begin
if res='1' then
write_terminated<='0';
elsif clk0='1' and clk0'event and cs='0' then
if (is_multi_write='0' and current_state(9)='1' and writing_finished='1') or
((current_state(7)='1' or current_state(8)='1' or current_state(9)='1') and is_stop_tran='1') then
write_terminated<='1';
elsif (current_state(7)='1' and write_terminated='1') or (current_state(2)='1' and next_state(7)='1') then
write_terminated<='0';
end if;
end if;
end process;
process(clk0, res, cmd_id, valid_cmd, cs)
begin
if res='1' then
is_multi_read<='0';
elsif clk0='1' and clk0'event and cs='0' then
if current_state(2)='1' and valid_cmd='1' then
if cmd_id=18 then
is_multi_read<='1';
elsif cmd_id=17 then
is_multi_read<='0';
end if;
end if;
end if;
end process;
process(clk0, res, cmd_id, valid_cmd, cs)
begin
if res='1' then
is_multi_write<='1';
elsif clk0='1' and clk0'event and cs='0' then
if valid_cmd='1' and current_state(2)='1' then
if cmd_id=25 then
is_multi_write<='1';
elsif cmd_id=24 then
is_multi_write<='0';
end if;
end if;
end if;
end process;
process(res, clk0, current_state, valid_cmd, cmd_id, cs)
begin
if res='1' then
delayed_r1<='0';
elsif clk0='1' and clk0'event and cs='0' then
if (current_state(5)='1' or current_state(6)='1') and valid_cmd='1' and cmd_id=12 then
delayed_r1<='1';
elsif current_state(2)='1' then
delayed_r1<='0';
end if;
end if;
end process;
process(res, clk0, current_state, valid_cmd, cmd_id, norm_r1, cs)
begin
if res='1' then
delayed_response<=(others=>'0');
elsif clk0='1' and clk0'event and cs='0' then
if (current_state(5)='1' or current_state(6)='1') and valid_cmd='1' and cmd_id=12 then
delayed_response<=norm_r1;
end if;
end if;
end process;
process(clk0, res, current_state, next_state, valid_cmd, valid_cmd_a, cmd_id, din_8, cs, is_multi_read, is_multi_write, read_terminated, reading_finished, write_terminated, writing_finished)
begin
if res='1' then
cur_address<=(others=>'0');
real_address<='0';
elsif clk0='1' and clk0'event and cs='0' then
if current_state(2)='1' then
if valid_cmd='1' then
if cmd_id=17 or cmd_id=18 or cmd_id=24 or cmd_id=25 or cmd_id=32 then
cur_address<=din_8(39 downto 8);
real_address<='1';
elsif cmd_id=9 then
cur_address(31 downto 13)<=(others=>'0');
cur_address(12)<='1';
cur_address(11 downto 0)<=(others=>'0');
real_address<='0';
elsif cmd_id=10 then
cur_address(31 downto 13)<=(others=>'0');
cur_address(12)<='1';
cur_address(11 downto 0)<="000000010000";
real_address<='0';
end if;
elsif valid_cmd_a='1' then
if cmd_id=13 then
cur_address(31 downto 13)<=(others=>'0');
cur_address(12)<='1';
cur_address(11 downto 0)<="000000101000";
real_address<='0';
elsif cmd_id=51 then
cur_address(31 downto 13)<=(others=>'0');
cur_address(12)<='1';
cur_address(11 downto 0)<="000000100000";
real_address<='0';
end if;
end if;
elsif current_state(2)='0' and next_state(2)='1' then
cur_address<=(others=>'0');
real_address<='0';
elsif current_state(6)='1' and reading_finished='1' and read_terminated='0' and is_multi_read='1' then
cur_address<=cur_address+cur_block_len;
elsif current_state(9)='1' and writing_finished='1' and write_terminated='0' and is_multi_write='1' then
cur_address<=cur_address+write_block_length;
end if;
end if;
end process;
process(res, clk0, current_state, next_state, valid_cmd, cmd_id, valid_cmd_a, din_8, cs)
begin
if res='1' then
num_toread<=(others=>'0');
elsif clk0='1' and clk0'event and cs='0' then
if current_state(2)='1' then
if valid_cmd='1' then
if cmd_id=17 or cmd_id=18 or cmd_id=24 or cmd_id=25 or cmd_id=32 then
num_toread<=cur_block_len;
elsif cmd_id=9 or cmd_id=10 then
num_toread<="0000010000";
end if;
elsif valid_cmd_a='1' then
if cmd_id=13 then
num_toread<="0001000000";
elsif cmd_id=51 then
num_toread<="0000001000";
end if;
end if;
end if;
end if;
end process;
process(res, clk0, current_state, valid_cmd, cmd_id, din_8, cs)
begin
if res='1' then
crc_enable<='0';
elsif clk0='1' and clk0'event then
if cs='0' then
if current_state(2)='1' and valid_cmd='1' and cmd_id=59 then
crc_enable<=din_8(8);
end if;
end if;
end if;
end process;
process(res, clk0, current_state, valid_cmd, cmd_id, din_8, cs)
begin
if res='1' then
cur_block_len<="1000000000";
elsif clk0='1' and clk0'event then
if cs='0' then
if current_state(2)='1' and valid_cmd='1' and cmd_id=16 then
if din_8(39 downto 8)<=max_block_length then
cur_block_len<=din_8(17 downto 8);
end if;
end if;
end if;
end if;
end process;
process(res, clk0, current_state, valid_cmd, cmd_id, din_8)
begin
if res='1' then
end_address<=(others=>'0');
elsif clk0='1' and clk0'event then
if cs='0' then
if current_state(2)='1' and valid_cmd='1' and cmd_id=33 then
if din_8(39 downto 8)<sd_card_size then
end_address<=din_8(39 downto 8);
end if;
end if;
end if;
end if;
end process;
process(res, clk0, current_state, next_state, cs)
begin
if res='1' then
cnt_writed<=(others=>'0');
elsif clk0='1' and clk0'event and cs='0' then
if current_state(2)='1' and next_state(7)='1' then
cnt_writed<=(others=>'0');
elsif current_state(8)='1' and next_state(9)='1' then
cnt_writed<=cnt_writed+1;
end if;
end if;
end process;
--- send r3 response block ---
process(res, clk0, cs, current_state, next_state)
begin
if res='1' then
cnt_r3<=(others=>'0');
elsif clk0='1' and clk0'event and cs='0' then
if current_state(2)='1' and next_state(4)='1' then
cnt_r3<=(others=>'0');
elsif current_state(4)='1' and cnt_r3/=3 then
cnt_r3<=cnt_r3+1;
end if;
end if;
end process;
process(cnt_r3)
begin
if cnt_r3=0 then
sendr3_out<=first_ocr_byte;
elsif cnt_r3=3 then
sendr3_out<=last_ocr_byte;
else
sendr3_out<=mid_ocr_byte;
end if;
end process;
sendr3_finished<=cnt_r3(1) and cnt_r3(0);
--- functional erasing block------
erasing_data<=after_erase;
erasing_enable<='1';
now_address_erase<=cur_address+cnt_erasing;
erasing_address<=now_address_erase(12 downto 0);
erasing_wren<='1';
process(res, clk0, current_state, next_state)
begin
if res='1' then
cnt_erasing<=(others=>'0');
elsif clk0='1' and clk0'event then
if current_state(2)='1' and next_state(10)='1' then
cnt_erasing<=(others=>'0');
elsif erasing_finished='0' then
cnt_erasing<=cnt_erasing+1;
end if;
end if;
end process;
process(now_address_erase, end_address)
begin
if now_address_erase=end_address then
erasing_finished<='1';
else
erasing_finished<='0';
end if;
end process;
--- send writed block num --
process(res, clk0, current_state, next_state, cs)
begin
if res='1' then
cnt_sw<=(others=>'0');
elsif clk0='1' and clk0'event and cs='0' then
if current_state(2)='1' and next_state(11)='1' then
cnt_sw<=(others=>'0');
elsif current_state(11)='1' and sendnum_finished='0' then
cnt_sw<=cnt_sw+1;
end if;
end if;
end process;
sendnum_finished<=cnt_sw(0) and cnt_sw(1) and cnt_sw(2);
s_crc_res<=(not cnt_sw(0)) and (not cnt_sw(1)) and (not cnt_sw(2)) and clk0;
process(cnt_sw)
begin
if cnt_sw>5 then
s_crc_hold<='1';
else
s_crc_hold<='0';
end if;
end process;
process(cnt_sw, cnt_writed)
begin
if cnt_sw=0 then
s_crc_data<=cnt_writed(31 downto 24);
elsif cnt_sw=1 then
s_crc_data<=cnt_writed(23 downto 16);
elsif cnt_sw=2 then
s_crc_data<=cnt_writed(15 downto 8);
elsif cnt_sw=3 then
s_crc_data<=cnt_writed(7 downto 0);
else
s_crc_data<=empty_byte;
end if;
end process;
CRC16Generator_D8a:CRC16Generator_D8 port map(RST=>s_crc_res, Hold=>s_crc_hold, TestData=>s_crc_data, Clock=>clk0, CRC=>s_crc_out);
process(cnt_sw, s_crc_out, cnt_writed)
begin
if cnt_sw=2 then
sendnum_out<=cnt_writed(31 downto 24);
elsif cnt_sw=3 then
sendnum_out<=cnt_writed(23 downto 16);
elsif cnt_sw=4 then
sendnum_out<=cnt_writed(15 downto 8);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -