LIBRARY ieee; USE ieee.std_logic_1164.all; use IEEE.numeric_std.all; library sdcard; ENTITY sdcard_tb IS PORT ( SD_CMD : inout std_logic := '1'; SD_CLK : in std_logic; SD_WP_N : out std_logic; SD_DAT : inout std_logic_vector(3 downto 0) := (others => 'Z') ); END sdcard_tb; ARCHITECTURE SYN OF sdcard_tb IS signal SD_dataBuf : std_logic_vector(47 downto 0); signal SD_dataBuf_long : std_logic_vector(135 downto 0); signal SD_received_command : unsigned(5 downto 0); signal send_buffer : std_logic_vector(31 downto 0); signal rec_buffer : std_logic_vector(31 downto 0); type treaddata is array(0 to 127) of std_logic_vector(31 downto 0); signal readdata : treaddata := (others => (others => '0')); -- crc 7 signal crc_clk : std_logic := '0'; signal crc_reset : std_logic := '0'; signal crc_enable : std_logic := '0'; signal crc_input : std_logic := '0'; signal crc_out : std_logic_vector(6 downto 0); -- crc16 signal crc16_reset : std_logic := '0'; signal crc16_enable : std_logic := '0'; signal crc16_input : std_logic := '0'; signal crc16_out : std_logic_vector(15 downto 0); signal crc16_rec : std_logic_vector(15 downto 0); begin crc_clk <= not crc_clk after 5 ns; icrc7 : entity sdcard.crc7 port map ( clk => crc_clk, reset => crc_reset, enable => crc_enable, input => crc_input, crc => crc_out ); SD_WP_N <= '1'; SD_CMD <= 'H'; SD_DAT <= "HHHH"; process begin SD_CMD <= 'Z'; crc_reset <= '1'; wait for 20 ns; crc_reset <= '0'; wait until SD_CMD = '0'; -- start bit SD_dataBuf <= (others => '0'); for i in 0 to 46 loop -- read all bits without stop bit wait until SD_CLK = '0'; wait until SD_CLK = '1'; SD_dataBuf <= SD_dataBuf(46 downto 0) & SD_CMD; if (i < 39) then crc_input <= SD_CMD; crc_enable <= '1'; wait for 10 ns; crc_enable <= '0'; end if; end loop; wait until SD_CLK = '0'; wait until SD_CLK = '1'; assert (crc_out = SD_dataBuf(7 downto 1)) report "SDCard CRC received at SDCard is not correct!" severity warning; SD_received_command <= unsigned(SD_dataBuf(45 downto 40)); wait until SD_CLK = '0'; wait until SD_CLK = '1'; SD_dataBuf(46) <= '0'; -- in response, host bit is set to zero if (SD_received_command = 3) then -- some special answers.... SD_dataBuf <= x"030002050047"; end if; if (SD_received_command = 41) then SD_dataBuf <= x"3F80FF8000FF"; end if; -- supported commands will return answer, correct crc is not yet done if (SD_received_command = 3 or SD_received_command = 7 or SD_received_command = 8 or SD_received_command = 17 or SD_received_command = 24 or SD_received_command = 55 or SD_received_command = 41 ) then wait for 10 us; for i in 0 to 47 loop wait until SD_CLK = '0'; wait until SD_CLK = '1'; SD_CMD <= SD_dataBuf(47); SD_dataBuf <= SD_dataBuf(46 downto 0) & '1'; end loop; SD_received_command <= (others => '0'); end if; -- cmd 2 sends back long answer if (SD_received_command = 2) then SD_dataBuf_long <= x"3f00000000000000000000000000000001"; wait for 10 us; for i in 0 to 135 loop wait until SD_CLK = '0'; wait until SD_CLK = '1'; SD_CMD <= SD_dataBuf_long(135); SD_dataBuf_long <= SD_dataBuf_long(134 downto 0) & '1'; end loop; SD_received_command <= (others => '0'); end if; end process; icrc16 : entity sdcard.crc16 port map ( clk => crc_clk, reset => crc16_reset, enable => crc16_enable, input => crc16_input, crc => crc16_out ); -- read and write(17/24) process begin wait until SD_received_command > 0; if (SD_received_command = 17) then -- block read wait for 20 us; SD_DAT(0) <= '0'; -- start bit wait until SD_CLK = '0'; wait until SD_CLK = '1'; for dword in 0 to 127 loop -- 512 bytes = 128 dwords --send_buffer <= x"55AA55AA"; send_buffer <= readdata(dword); wait for 10 ns; for i in 0 to 31 loop SD_DAT(0) <= send_buffer(31); send_buffer <= send_buffer(30 downto 0) & '0'; wait until SD_CLK = '0'; wait until SD_CLK = '1'; end loop; end loop; SD_DAT(0) <= 'Z'; elsif (SD_received_command = 24) then -- block write wait until SD_received_command = 0; -- wait until response on CMD line is fully send crc16_reset <= '1'; wait until SD_DAT(0) = '0'; -- start bit crc16_reset <= '0'; wait until SD_CLK = '0'; wait until SD_CLK = '1'; for dword in 0 to 127 loop -- 512 bytes receive rec_buffer <= (others => '0'); wait for 10 ns; for i in 0 to 31 loop crc16_input <= SD_DAT(0); crc16_enable <= '1'; wait for 10 ns; crc16_enable <= '0'; rec_buffer <= rec_buffer(30 downto 0) & SD_DAT(0); wait until SD_CLK = '0'; wait until SD_CLK = '1'; end loop; readdata(dword) <= rec_buffer; end loop; for i in 0 to 15 loop -- receive crc crc16_rec <= crc16_rec(14 downto 0) & SD_DAT(0); wait until SD_CLK = '0'; wait until SD_CLK = '1'; end loop; assert (crc16_out = crc16_rec) report "SDCard CRC16 received at SDCard is not correct!" severity warning; wait for 50 us; SD_DAT(0) <= '0'; -- pull down dat line for some time -> sd card busy wait for 50 us; SD_DAT(0) <= 'Z'; end if; end process; END SYN;