updateStateVariables: process(clk, reset) BEGIN IF reset = '0' THEN state <= RST; return_state <= RST; sr_return_state <= RST; cmd_out <= (others=>'1'); data_in <= (others=>'0'); dout <= (others=>'0'); address <= (others=>'0'); data_out <= (others=>'1'); card_type <= ct_None; byte_counter <= 0; bit_counter <= 0; crc7 <= (others => '0'); in_crc16 <= (others => '0'); out_crc16 <= (others => '0'); crcLow <= (others => '0'); error <= '1'; error_code <= ec_NoSDError; sdAvail <= '0'; error <= '0'; slow_clock <= true; clock_divider <= 0; transfer_data_out <= false; sCs <= '1'; sDin_taken <= '0'; wr_erase_count <= "00000001"; -- SD outputs sclk <= '0'; cs <= '1'; mosi <= '1'; -- Interface outputs sd_type <= "00"; sd_busy <= '1'; sd_error <= '1'; sd_error_code <= ec_NoSDError; dout <= "00000000"; dout_avail <= '0'; din_taken <= '0'; multiple <= false; skipFirstR1Byte <= false; ELSIF clk'event AND clk = '1' THEN -- State variables state <= new_state; if (set_return_state) then return_state <= new_return_state; end if; if (set_sr_return_state) then sr_return_state <= new_sr_return_state; end if; if (set_cmd_out) then cmd_out <= new_cmd_out; end if; data_in <= new_data_in; if (set_address) then address <= new_address; end if; data_out <= new_data_out; if (set_byte_counter) then byte_counter <= new_byte_counter; end if; bit_counter <= new_bit_counter; error <= new_error; error_code <= new_error_code; card_type <= new_card_type; slow_clock <= new_slow_clock; clock_divider <= new_clock_divider; crc7 <= new_crc7; in_crc16 <= new_in_crc16; out_crc16 <= new_out_crc16; crcLow <= new_crcLow; transfer_data_out <= new_transfer_data_out; sCs <= new_cs; -- SD outputs sclk <= new_sclk; cs <= new_cs; mosi <= new_data_out(7); wr_erase_count <= new_wr_erase_count; -- Interface outputs sd_type <= new_card_type; sd_busy <= new_busy; sd_error <= new_error; sd_error_code <= new_error_code; if set_davail then -- NB can't do this at the same cycle as we set data_in sDavail <= '1'; dout <= data_in; dout_avail <= '1'; elsif sDavail='1' and dout_taken='1' then sDavail <= '0'; dout_avail <= '0'; end if; multiple <= new_multiple; skipFirstR1Byte <= new_skipFirstR1Byte; -- This latches the din_valid and generates din_latch and din_taken if din_valid='0' or (wr='0' and wr_multiple='0') then -- Reset din_latch when din_valid is false, or no write in progress sDin_taken <= '0'; din_taken <= '0'; din_latch <= false; elsif din_valid='1' and last_din_valid='0' then -- Set din_latch on rising edge of din_valid sDin_taken <= '0'; din_taken <= '0'; din_latch <= true; elsif din_latch and new_din_taken='1' then -- Reset din_latch when din_taken rises sDin_taken <= '1'; din_taken <= '1'; din_latch <= false; end if; last_din_valid <= din_valid; end if; end process;