📄 sdcard_spi.vhd
字号:
elsif cnt_sw=5 then
sendnum_out<=cnt_writed(7 downto 0);
elsif cnt_sw=6 then
sendnum_out<=s_crc_out(15 downto 8);
elsif cnt_sw=7 then
sendnum_out<=s_crc_out(7 downto 0);
else
sendnum_out<=idle_out;
end if;
end process;
--- reading functional block ---
process(res, clk0, cs, current_state, next_state)
begin
if res='1' then
cnt_reading<=(others=>'0');
elsif clk0='1' and clk0'event and cs='0' then
if current_state(5)='1' and next_state(6)='1' then
cnt_reading<=(others=>'0');
elsif current_state(6)='1' and reading_finished='0' then
cnt_reading<=cnt_reading+1;
end if;
end if;
end process;
process(cnt_reading,address_error,num_toread, valid_cmd, cmd_id, current_state)
begin
if address_error='1' then
reading_finished<='1';
elsif valid_cmd='1' and cmd_id=12 and current_state(6)='1' then
reading_finished<='1';
elsif cnt_reading=num_toread+3 then
reading_finished<='1';
else
reading_finished<='0';
end if;
end process;
process(cnt_reading,address_error,num_toread)
begin
if address_error='1' then
reading_enable<='0';
elsif cnt_reading<num_toread then
reading_enable<='1';
else
reading_enable<='0';
end if;
end process;
reading_wren<='0';
process(cnt_reading, cur_address)
variable temp:std_logic_vector(31 downto 0);
begin
temp:=cnt_reading+cur_address;
reading_address<=temp(12 downto 0);
end process;
process(res, clk0, ram_out)
begin
if res='1' then
info_buf<=(others=>'1');
elsif clk0='1' and clk0'event then
if current_state(6)='1' then
info_buf(15 downto 8)<=info_buf(7 downto 0);
info_buf(7 downto 0)<=ram_out;
end if;
end if;
end process;
process(cnt_reading, clk0)
begin
if cnt_reading=0 then
r_crc_res<=clk0;
else
r_crc_res<='0';
end if;
end process;
process(cnt_reading, num_toread, ram_out)
begin
if cnt_reading<num_toread then
r_crc_data<=ram_out;
else
r_crc_data<=empty_byte;
end if;
end process;
process(cnt_reading, num_toread)
begin
if cnt_reading<num_toread+2 then
r_crc_hold<='0';
else
r_crc_hold<='1';
end if;
end process;
CRC16Generator_D8b:CRC16Generator_D8 port map(TestData=>r_crc_data, Clock=>clk0, Hold=>r_crc_hold, RST=>r_crc_res, CRC=>r_crc_out);
process(cnt_reading, num_toread, info_buf, r_crc_out, address_error)
begin
if address_error='1' then
reading_out<=data_error;
elsif cnt_reading=0 then
reading_out<=idle_out;
elsif cnt_reading=1 then
reading_out<=start_block_token;
elsif cnt_reading<num_toread+2 then
reading_out<=info_buf(15 downto 8);
elsif cnt_reading=num_toread+2 then
reading_out<=r_crc_out(15 downto 8);
else
reading_out<=r_crc_out(7 downto 0);
end if;
end process;
--- buffering functional block--
process(cnt_buf)
begin
if cnt_buf=write_block_length+1 then
buf_ended<='1';
else
buf_ended<='0';
end if;
end process;
process(res, clk0, cs, current_state, next_state)
begin
if res='1' then
cnt_buf<=(others=>'0');
elsif clk0='1' and clk0'event and cs='0' then
if current_state(7)='1' and next_state(8)='1' then
cnt_buf<=(others=>'0');
elsif current_state(8)='1' and buf_ended='0' then
cnt_buf<=cnt_buf+1;
end if;
end if;
end process;
b_fifo_aclr<=current_state(7) and next_state(8);
b_fifo_data<=din_8(7 downto 0);
b_fifo_rdreq<='0';
process(current_state, cs, cnt_buf)
begin
if current_state(8)='1' and cs='0' then
if cnt_buf<write_block_length then
b_fifo_wrreq<='1';
else
b_fifo_wrreq<='0';
end if;
else
b_fifo_wrreq<='0';
end if;
end process;
--- writing functional block
process(res, clk0, current_state, next_state)
begin
if res='1' then
cnt_write<=(others=>'0');
elsif clk0='1' and clk0'event then
if current_state(8)='1' and next_state(9)='1' then
cnt_write<=(others=>'0');
elsif current_state(9)='1' and writing_finished='0' then
cnt_write<=cnt_write+1;
end if;
end if;
end process;
process(cnt_write)
begin
if cnt_write=write_block_length then
writing_finished<='1';
else
writing_finished<='0';
end if;
end process;
w_fifo_data<=empty_byte;
w_fifo_wrreq<='0';
process(writing_finished, current_state)
begin
if current_state(9)='1' then
w_fifo_rdreq<=not writing_finished;
else
w_fifo_rdreq<='0';
end if;
end process;
process(res, clk0)
begin
if res='1' then
write_tmp_buf<=(others=>'0');
elsif clk0='1' and clk0'event then
write_tmp_buf<=w_fifo_out;
end if;
end process;
process(cur_address, cnt_write)
variable temp:std_logic_vector(31 downto 0);
begin
temp:=cur_address+cnt_write-1;
writing_address<=temp(12 downto 0);
end process;
process(cnt_write)
begin
if cnt_write/=0 then
writing_enable<='1';
else
writing_enable<='0';
end if;
end process;
writing_data<=write_tmp_buf;
writing_wren<='1';
--- controll the w_fifo --
w_f_aclr<=current_state(7) and b_fifo_aclr;
process(current_state, b_fifo_data, w_fifo_data)
begin
if current_state(8)='1' then
w_f_data<=b_fifo_data;
elsif current_state(9)='1' then
w_f_data<=w_fifo_data;
else
w_f_data<=empty_byte;
end if;
end process;
w_f_rdreq<=(current_state(8) and b_fifo_rdreq) or (current_state(9) and w_fifo_rdreq);
w_f_wrreq<=(current_state(8) and b_fifo_wrreq) or (current_state(9) and w_fifo_wrreq);
w_fifo_a:w_fifo port map(aclr=>w_f_aclr, clock=>r_clk0, data=>w_f_data, rdreq=>w_f_rdreq, wrreq=>w_f_wrreq, q=>w_fifo_out);
--- main ram controll --
process(current_state, erasing_address, reading_address, writing_address)
begin
if current_state(10)='1' then
ram_address<=erasing_address;
elsif current_state(6)='1' then
ram_address<=reading_address;
elsif current_state(9)='1' then
ram_address<=writing_address;
else
ram_address<=(others=>'0');
end if;
end process;
process(current_state, erasing_wren, reading_wren, writing_wren)
begin
if current_state(10)='1' then
ram_wren<=erasing_wren;
elsif current_state(6)='1' then
ram_wren<=reading_wren;
elsif current_state(9)='1' then
ram_wren<=writing_wren;
else
ram_wren<='0';
end if;
end process;
process(current_state, erasing_enable, reading_enable, writing_enable)
begin
if current_state(10)='1' then
ram_clken<=erasing_enable;
elsif current_state(6)='1' then
ram_clken<=reading_enable;
elsif current_state(9)='1' then
ram_clken<=writing_enable;
else
ram_clken<='0';
end if;
end process;
process(current_state, erasing_data, writing_data)
begin
if current_state(10)='1' then
ram_data<=erasing_data;
elsif current_state(9)='1' then
ram_data<=writing_data;
else
ram_data<=empty_byte;
end if;
end process;
main_ram_a:main_ram port map(address=>ram_address, clken=>ram_clken, clock=>r_clk0, data=>ram_data, wren=>ram_wren, q=>ram_out);
--- to handle the final output of main ---
in_idle_state<=next_state(0) or next_state(1);
process(res, clk0, valid_cmd, cur_address, cs)
begin
if res='1' then
address_error<='0';
elsif clk0='1' and clk0'event then
if cs='0' then
if cur_address>sd_card_size-write_block_length and real_address='1' then
address_error<='1';
elsif valid_cmd='1' or valid_cmd_a='1' then
address_error<='0';
end if;
end if;
end if;
end process;
process(cmd_id, valid_cmd, din_8)
begin
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 or cmd_id=33)
and (din_8(39 downto 8)>=sd_card_size) then
parameter_error<='1';
elsif (cmd_id=16) and (din_8(39 downto 8)>max_block_length) then
parameter_error<='1';
else
parameter_error<='0';
end if;
else
parameter_error<='0';
end if;
end process;
crc_error<=is_cmd and crc_result_cmd;
process(current_state, valid_cmd, valid_cmd_a, cmd_id)
begin
if valid_cmd='1' then
if current_state(0)='1' then
if cmd_id/=0 then
illegal_command<='1';
else
illegal_command<='0';
end if;
elsif current_state(1)='1' then
if cmd_id/=0 and cmd_id/=1 and cmd_id/=55 then
illegal_command<='1';
else
illegal_command<='0';
end if;
else
if cmd_id=0 or cmd_id=9 or cmd_id=10 or cmd_id=13 or cmd_id=12 or cmd_id=16 or cmd_id=17 or cmd_id=18
or cmd_id=24 or cmd_id=25 or cmd_id=32 or cmd_id=33 or cmd_id=38 or cmd_id=55 or cmd_id=56
or cmd_id=58 or cmd_id=59 then
illegal_command<='0';
else
illegal_command<='1';
end if;
end if;
elsif valid_cmd_a='1' then
if current_state(0)='1' then
illegal_command<='1';
elsif current_state(1)='1' then
if cmd_id/=41 then
illegal_command<='1';
else
illegal_command<='0';
end if;
else
if cmd_id=13 and cmd_id=22 and cmd_id=23 and cmd_id=42 and cmd_id=51 then
illegal_command<='0';
else
illegal_command<='1';
end if;
end if;
else
illegal_command<='0';
end if;
end process;
norm_r1(7)<='0';
norm_r1(0)<=in_idle_state;
norm_r1(1)<=erase_reset;
norm_r1(2)<=illegal_command;
norm_r1(3)<=crc_error;
norm_r1(4)<=erase_seq_error;
norm_r1(5)<=address_error;
norm_r1(6)<=parameter_error;
process(clk0, res)
begin
if res='1' then
dout_8<=(others=>'0');
elsif clk0='1' and clk0'event then
dout_8<=next_dout_8;
end if;
end process;
process(current_state, valid_cmd, valid_cmd_a, cmd_id, norm_r1, reading_out, sendnum_out, sendr3_out, data_ended, delayed_response, delayed_r1, cur_address, crc_result_data, real_address)
begin
if current_state(0)='1' then
if valid_cmd='1' or valid_cmd_a='1' then
next_dout_8<=norm_r1;
else
next_dout_8<=idle_out;
end if;
elsif current_state(1)='1' then
if valid_cmd='1' or valid_cmd_a='1' then
next_dout_8<=norm_r1;
else
next_dout_8<=idle_out;
end if;
elsif current_state(2)='1' then
if delayed_r1='1' then
next_dout_8<=delayed_response;
elsif valid_cmd='1' or valid_cmd_a='1' then
next_dout_8<=norm_r1;
else
next_dout_8<=idle_out;
end if;
elsif current_state(3)='1' then
next_dout_8<=norm_r2;
elsif current_state(4)='1' then
next_dout_8<=sendr3_out;
elsif current_state(5)='1' then
next_dout_8<=idle_out;
elsif current_state(6)='1' then
next_dout_8<=reading_out;
elsif current_state(7)='1' then
next_dout_8<=idle_out;
elsif current_state(8)='1' then
if data_ended='1' then
if cur_address>sd_card_size-write_block_length and real_address='1' then
next_dout_8<=dresponse_write_error;
elsif crc_result_data='1' then
next_dout_8<=dresponse_crc_error;
else
next_dout_8<=dresponse_accept;
end if;
else
next_dout_8<=idle_out;
end if;
elsif current_state(9)='1' then
next_dout_8<=buzy_response;
elsif current_state(10)='1' then
next_dout_8<=buzy_response;
else
next_dout_8<=sendnum_out;
end if;
end process;
---output part, change byte to bit
process(res, clk)
begin
if res='1' then
do_buf<=(others=>'1');
elsif clk='0' and clk'event then
if cnt_8=0 then
do_buf<=dout_8;
else
do_buf(7 downto 1)<=do_buf(6 downto 0);
do_buf(0)<='1';
end if;
end if;
end process;
process(cs, do_buf)
begin
if cs='0' then
do<=do_buf(7);
else
do<='Z';
end if;
end process;
test_clk0<=clk0;
test_ram_out<=ram_out;
test_current_state<=current_state;
end architecture;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -