-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
--
|
--
|
-- SD/MMC Bootloader
|
-- SD/MMC Bootloader
|
-- Simple SD and MMC model
|
-- Simple SD and MMC model
|
--
|
--
|
-- $Id: card.vhd,v 1.1 2005-02-08 21:09:20 arniml Exp $
|
-- $Id: card.vhd,v 1.2 2005-02-13 17:06:22 arniml Exp $
|
--
|
--
|
-- Copyright (c) 2005, Arnim Laeuger (arniml@opencores.org)
|
-- Copyright (c) 2005, Arnim Laeuger (arniml@opencores.org)
|
--
|
--
|
-- All rights reserved, see COPYING.
|
-- All rights reserved, see COPYING.
|
--
|
--
|
-- Redistribution and use in source and synthezised forms, with or without
|
-- Redistribution and use in source and synthezised forms, with or without
|
-- modification, are permitted provided that the following conditions are met:
|
-- modification, are permitted provided that the following conditions are met:
|
--
|
--
|
-- Redistributions of source code must retain the above copyright notice,
|
-- Redistributions of source code must retain the above copyright notice,
|
-- this list of conditions and the following disclaimer.
|
-- this list of conditions and the following disclaimer.
|
--
|
--
|
-- Redistributions in synthesized form must reproduce the above copyright
|
-- Redistributions in synthesized form must reproduce the above copyright
|
-- notice, this list of conditions and the following disclaimer in the
|
-- notice, this list of conditions and the following disclaimer in the
|
-- documentation and/or other materials provided with the distribution.
|
-- documentation and/or other materials provided with the distribution.
|
--
|
--
|
-- Neither the name of the author nor the names of other contributors may
|
-- Neither the name of the author nor the names of other contributors may
|
-- be used to endorse or promote products derived from this software without
|
-- be used to endorse or promote products derived from this software without
|
-- specific prior written permission.
|
-- specific prior written permission.
|
--
|
--
|
-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
-- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
-- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
-- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
-- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
-- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE
|
-- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE
|
-- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
-- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
-- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
-- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
-- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
-- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
-- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
-- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
-- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
-- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
-- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
-- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
-- POSSIBILITY OF SUCH DAMAGE.
|
-- POSSIBILITY OF SUCH DAMAGE.
|
--
|
--
|
-- Please report bugs to the author, but before you do so, please
|
-- Please report bugs to the author, but before you do so, please
|
-- make sure that this is not a derivative work and that
|
-- make sure that this is not a derivative work and that
|
-- you have the latest version of this file.
|
-- you have the latest version of this file.
|
--
|
--
|
-- The latest version of this file can be found at:
|
-- The latest version of this file can be found at:
|
-- http://www.opencores.org/projects.cgi/web/spi_boot/overview
|
-- http://www.opencores.org/projects.cgi/web/spi_boot/overview
|
--
|
--
|
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
|
|
library ieee;
|
library ieee;
|
use ieee.std_logic_1164.all;
|
use ieee.std_logic_1164.all;
|
|
|
|
|
entity card is
|
entity card is
|
|
|
generic (
|
generic (
|
card_type_g : string := "none";
|
card_type_g : string := "none";
|
is_sd_card_g : integer := 1
|
is_sd_card_g : integer := 1
|
);
|
);
|
|
|
port (
|
port (
|
spi_clk_i : in std_logic;
|
spi_clk_i : in std_logic;
|
spi_cs_n_i : in std_logic;
|
spi_cs_n_i : in std_logic;
|
spi_data_i : in std_logic;
|
spi_data_i : in std_logic;
|
spi_data_o : out std_logic
|
spi_data_o : out std_logic
|
);
|
);
|
|
|
end card;
|
end card;
|
|
|
|
|
library ieee;
|
library ieee;
|
use ieee.numeric_std.all;
|
use ieee.numeric_std.all;
|
library std;
|
library std;
|
use std.textio.all;
|
use std.textio.all;
|
|
|
use work.tb_pack.all;
|
use work.tb_pack.all;
|
|
|
architecture behav of card is
|
architecture behav of card is
|
|
|
signal power_on_n_s : std_logic;
|
signal power_on_n_s : std_logic;
|
signal soft_res_n_s : std_logic;
|
signal soft_res_n_s : std_logic;
|
signal res_n_s : std_logic;
|
signal res_n_s : std_logic;
|
|
|
signal rx_s : std_logic_vector(47 downto 0);
|
signal rx_s : std_logic_vector(47 downto 0);
|
|
|
signal set_spi_mode_s,
|
signal set_spi_mode_s,
|
spi_mode_q : boolean;
|
spi_mode_q : boolean;
|
signal set_idle_mode_s,
|
signal set_idle_mode_s,
|
poll_idle_mode_s : boolean;
|
poll_idle_mode_s : boolean;
|
signal idle_mode_q : natural;
|
signal idle_mode_q : natural;
|
|
|
signal block_len_q,
|
signal block_len_q,
|
block_len_s : unsigned(31 downto 0);
|
block_len_s : unsigned(31 downto 0);
|
signal set_block_len_s : boolean;
|
signal set_block_len_s : boolean;
|
|
|
signal new_read_addr_s,
|
signal new_read_addr_s,
|
read_addr_q : unsigned(31 downto 0);
|
read_addr_q : unsigned(31 downto 0);
|
signal set_read_addr_s,
|
signal set_read_addr_s,
|
inc_read_addr_s : boolean;
|
inc_read_addr_s : boolean;
|
|
|
signal cmd_spi_data_s,
|
signal cmd_spi_data_s,
|
read_spi_data_s : std_logic;
|
read_spi_data_s : std_logic;
|
signal start_read_s : boolean;
|
signal start_read_s : boolean;
|
signal reading_s : boolean;
|
signal reading_s : boolean;
|
|
|
procedure rise_clk is
|
procedure rise_clk is
|
begin
|
begin
|
wait until spi_clk_i'event and to_X01(spi_clk_i) = '1';
|
wait until spi_clk_i'event and to_X01(spi_clk_i) = '1';
|
end rise_clk;
|
end rise_clk;
|
|
|
-- procedure rise_clk(num : natural) is
|
-- procedure rise_clk(num : natural) is
|
-- begin
|
-- begin
|
-- for i in 1 to num loop
|
-- for i in 1 to num loop
|
-- rise_clk;
|
-- rise_clk;
|
-- end loop;
|
-- end loop;
|
-- end rise_clk;
|
-- end rise_clk;
|
|
|
procedure fall_clk is
|
procedure fall_clk is
|
begin
|
begin
|
wait until spi_clk_i'event and to_X01(spi_clk_i) = '0';
|
wait until spi_clk_i'event and to_X01(spi_clk_i) = '0';
|
end fall_clk;
|
end fall_clk;
|
|
|
procedure fall_clk(num : natural) is
|
procedure fall_clk(num : natural) is
|
begin
|
begin
|
for i in 1 to num loop
|
for i in 1 to num loop
|
fall_clk;
|
fall_clk;
|
end loop;
|
end loop;
|
end fall_clk;
|
end fall_clk;
|
|
|
begin
|
begin
|
|
|
res_n_s <= power_on_n_s and soft_res_n_s;
|
res_n_s <= power_on_n_s and soft_res_n_s;
|
|
|
-----------------------------------------------------------------------------
|
-----------------------------------------------------------------------------
|
-- Power on reset
|
-- Power on reset
|
-----------------------------------------------------------------------------
|
-----------------------------------------------------------------------------
|
por: process
|
por: process
|
begin
|
begin
|
power_on_n_s <= '0';
|
power_on_n_s <= '0';
|
wait for 200 ns;
|
wait for 200 ns;
|
power_on_n_s <= '1';
|
power_on_n_s <= '1';
|
wait;
|
wait;
|
end process por;
|
end process por;
|
|
|
|
|
-----------------------------------------------------------------------------
|
-----------------------------------------------------------------------------
|
--
|
--
|
ctrl: process
|
ctrl: process
|
|
|
function check_crc(payload : in std_logic_vector(47 downto 0))
|
function check_crc(payload : in std_logic_vector(47 downto 0))
|
return boolean is
|
return boolean is
|
|
|
begin
|
begin
|
|
|
return calc_crc(payload(47 downto 8)) = payload(7 downto 1);
|
return calc_crc(payload(47 downto 8)) = payload(7 downto 1);
|
end check_crc;
|
end check_crc;
|
|
|
variable rx_v : std_logic_vector(47 downto 0);
|
variable rx_v : std_logic_vector(47 downto 0);
|
variable cmd_v : std_logic_vector( 5 downto 0);
|
variable cmd_v : std_logic_vector( 5 downto 0);
|
variable arg_v : std_logic_vector(31 downto 0);
|
variable arg_v : std_logic_vector(31 downto 0);
|
variable crc_v : std_logic_vector( 6 downto 0);
|
variable crc_v : std_logic_vector( 6 downto 0);
|
variable wrong_v : std_logic;
|
variable wrong_v : std_logic;
|
variable read_data_v : boolean;
|
variable read_data_v : boolean;
|
|
|
begin
|
begin
|
rx_s <= (others => '0');
|
rx_s <= (others => '0');
|
set_spi_mode_s <= false;
|
set_spi_mode_s <= false;
|
set_idle_mode_s <= false;
|
set_idle_mode_s <= false;
|
poll_idle_mode_s <= false;
|
poll_idle_mode_s <= false;
|
cmd_spi_data_s <= '1';
|
cmd_spi_data_s <= '1';
|
soft_res_n_s <= '1';
|
soft_res_n_s <= '1';
|
set_block_len_s <= false;
|
set_block_len_s <= false;
|
block_len_s <= (others => '0');
|
block_len_s <= (others => '0');
|
new_read_addr_s <= (others => '0');
|
new_read_addr_s <= (others => '0');
|
set_read_addr_s <= false;
|
set_read_addr_s <= false;
|
start_read_s <= false;
|
start_read_s <= false;
|
read_data_v := false;
|
read_data_v := false;
|
|
|
loop
|
loop
|
|
|
rise_clk;
|
rise_clk;
|
-- wait for startbit of command
|
-- wait for startbit of command
|
while to_X01(spi_data_i) = '1' loop
|
while to_X01(spi_data_i) = '1' loop
|
rise_clk;
|
rise_clk;
|
end loop;
|
end loop;
|
rx_v(47) := '0';
|
rx_v(47) := '0';
|
|
|
-- read remaining 47 bits of command
|
-- read remaining 47 bits of command
|
for i in 46 downto 0 loop
|
for i in 46 downto 0 loop
|
rise_clk;
|
rise_clk;
|
rx_v(i) := to_X01(spi_data_i);
|
rx_v(i) := to_X01(spi_data_i);
|
end loop;
|
end loop;
|
rx_s <= rx_v;
|
rx_s <= rx_v;
|
|
|
-- dissect received data
|
-- dissect received data
|
cmd_v := rx_v(45 downto 40);
|
cmd_v := rx_v(45 downto 40);
|
arg_v := rx_v(39 downto 8);
|
arg_v := rx_v(39 downto 8);
|
crc_v := rx_v( 7 downto 1);
|
crc_v := rx_v( 7 downto 1);
|
|
|
assert spi_mode_q or check_crc(payload => rx_v)
|
assert spi_mode_q or check_crc(payload => rx_v)
|
report "CRC mismatch"
|
report "CRC mismatch"
|
severity error;
|
severity error;
|
|
|
wrong_v := '0';
|
wrong_v := '0';
|
case cmd_v is
|
case cmd_v is
|
-- CMD0: GO_IDLE_STATE ------------------------------------------------
|
-- CMD0: GO_IDLE_STATE ------------------------------------------------
|
when "000000" =>
|
when "000000" =>
|
set_spi_mode_s <= true;
|
set_spi_mode_s <= true;
|
set_idle_mode_s <= true;
|
set_idle_mode_s <= true;
|
-- CMD1: SEND_OP_COND -------------------------------------------------
|
-- CMD1: SEND_OP_COND -------------------------------------------------
|
when "000001" =>
|
when "000001" =>
|
poll_idle_mode_s <= true;
|
poll_idle_mode_s <= true;
|
-- CMD12: STOP_TRANSMISSION -------------------------------------------
|
-- CMD12: STOP_TRANSMISSION -------------------------------------------
|
when "001100" =>
|
when "001100" =>
|
start_read_s <= false;
|
start_read_s <= false;
|
read_data_v := false;
|
read_data_v := false;
|
-- CMD16: SET_BLOCKLEN ------------------------------------------------
|
-- CMD16: SET_BLOCKLEN ------------------------------------------------
|
when "010000" =>
|
when "010000" =>
|
block_len_s <= unsigned(arg_v);
|
block_len_s <= unsigned(arg_v);
|
set_block_len_s <= true;
|
set_block_len_s <= true;
|
-- CMD18: READ_MULTIPLE_BLOCK -----------------------------------------
|
-- CMD18: READ_MULTIPLE_BLOCK -----------------------------------------
|
when "010010" =>
|
when "010010" =>
|
new_read_addr_s <= unsigned(arg_v);
|
new_read_addr_s <= unsigned(arg_v);
|
set_read_addr_s <= true;
|
set_read_addr_s <= true;
|
read_data_v := true;
|
read_data_v := true;
|
-- CMD55: APPL_CMD ----------------------------------------------------
|
-- CMD55: APPL_CMD ----------------------------------------------------
|
when "110111" =>
|
when "110111" =>
|
-- command only available for SD card
|
-- command only available for SD card
|
if is_sd_card_g /= 1 then
|
if is_sd_card_g /= 1 then
|
wrong_v := '1';
|
wrong_v := '1';
|
end if;
|
end if;
|
-- ACMD41: SEND_OP_COND -----------------------------------------------
|
-- ACMD41: SEND_OP_COND -----------------------------------------------
|
when "101001" =>
|
when "101001" =>
|
-- command only available for SD card
|
-- command only available for SD card
|
if is_sd_card_g /= 1 then
|
if is_sd_card_g /= 1 then
|
wrong_v := '1';
|
wrong_v := '1';
|
else
|
else
|
poll_idle_mode_s <= true;
|
poll_idle_mode_s <= true;
|
end if;
|
end if;
|
|
|
when others =>
|
when others =>
|
wrong_v := '1';
|
wrong_v := '1';
|
null;
|
null;
|
end case;
|
end case;
|
|
|
|
|
-- spend some time before removing control signals
|
-- spend some time before removing control signals
|
fall_clk(2);
|
fall_clk(2);
|
poll_idle_mode_s <= false;
|
poll_idle_mode_s <= false;
|
set_idle_mode_s <= false;
|
set_idle_mode_s <= false;
|
fall_clk(6);
|
fall_clk(6);
|
set_spi_mode_s <= false;
|
set_spi_mode_s <= false;
|
set_block_len_s <= false;
|
set_block_len_s <= false;
|
set_read_addr_s <= false;
|
set_read_addr_s <= false;
|
|
|
if reading_s then
|
if reading_s then
|
wait until not reading_s;
|
wait until not reading_s;
|
end if;
|
end if;
|
|
|
|
|
-- wait for a total two "bytes" before sending out response
|
-- wait for a total two "bytes" before sending out response
|
for i in 1 to 8 loop
|
for i in 1 to 8 loop
|
fall_clk;
|
fall_clk;
|
end loop;
|
end loop;
|
|
|
for i in 7 downto 0 loop
|
for i in 7 downto 0 loop
|
fall_clk;
|
fall_clk;
|
case i is
|
case i is
|
when 2 =>
|
when 2 =>
|
cmd_spi_data_s <= wrong_v;
|
cmd_spi_data_s <= wrong_v;
|
when 0 =>
|
when 0 =>
|
if idle_mode_q = 0 then
|
if idle_mode_q = 0 then
|
cmd_spi_data_s <= '0';
|
cmd_spi_data_s <= '0';
|
else
|
else
|
cmd_spi_data_s <= '1';
|
cmd_spi_data_s <= '1';
|
end if;
|
end if;
|
when others =>
|
when others =>
|
cmd_spi_data_s <= '0';
|
cmd_spi_data_s <= '0';
|
end case;
|
end case;
|
end loop;
|
end loop;
|
fall_clk;
|
fall_clk;
|
cmd_spi_data_s <= '1';
|
cmd_spi_data_s <= '1';
|
|
|
-- transmit data if requested
|
-- transmit data if requested
|
start_read_s <= read_data_v;
|
start_read_s <= read_data_v;
|
|
|
end loop;
|
end loop;
|
end process ctrl;
|
end process ctrl;
|
--
|
--
|
-----------------------------------------------------------------------------
|
-----------------------------------------------------------------------------
|
|
|
|
|
-----------------------------------------------------------------------------
|
-----------------------------------------------------------------------------
|
--
|
--
|
seq: process (res_n_s,
|
seq: process (res_n_s,
|
spi_clk_i,
|
spi_clk_i,
|
set_spi_mode_s,
|
set_spi_mode_s,
|
set_idle_mode_s,
|
set_idle_mode_s,
|
poll_idle_mode_s,
|
poll_idle_mode_s,
|
set_block_len_s,
|
set_block_len_s,
|
block_len_s)
|
block_len_s)
|
|
|
begin
|
begin
|
if res_n_s = '0' then
|
if res_n_s = '0' then
|
spi_mode_q <= false;
|
spi_mode_q <= false;
|
idle_mode_q <= 5;
|
idle_mode_q <= 5;
|
block_len_q <= (others => '0');
|
block_len_q <= (others => '0');
|
read_addr_q <= (others => '0');
|
read_addr_q <= (others => '0');
|
|
|
elsif spi_clk_i'event and spi_clk_i = '1' then
|
elsif spi_clk_i'event and spi_clk_i = '1' then
|
if set_spi_mode_s then
|
if set_spi_mode_s then
|
spi_mode_q <= true;
|
spi_mode_q <= true;
|
end if;
|
end if;
|
|
|
if set_idle_mode_s then
|
if set_idle_mode_s then
|
idle_mode_q <= 5;
|
idle_mode_q <= 5;
|
elsif poll_idle_mode_s then
|
elsif poll_idle_mode_s then
|
if idle_mode_q > 0 then
|
if idle_mode_q > 0 then
|
idle_mode_q <= idle_mode_q - 1;
|
idle_mode_q <= idle_mode_q - 1;
|
end if;
|
end if;
|
end if;
|
end if;
|
|
|
if set_block_len_s then
|
if set_block_len_s then
|
block_len_q <= block_len_s;
|
block_len_q <= block_len_s;
|
end if;
|
end if;
|
|
|
if set_read_addr_s then
|
if set_read_addr_s then
|
read_addr_q <= new_read_addr_s;
|
read_addr_q <= new_read_addr_s;
|
elsif inc_read_addr_s then
|
elsif inc_read_addr_s then
|
read_addr_q <= read_addr_q + 1;
|
read_addr_q <= read_addr_q + 1;
|
end if;
|
end if;
|
|
|
end if;
|
end if;
|
end process seq;
|
end process seq;
|
--
|
--
|
-----------------------------------------------------------------------------
|
-----------------------------------------------------------------------------
|
|
|
|
|
-----------------------------------------------------------------------------
|
-----------------------------------------------------------------------------
|
--
|
--
|
read_block: process
|
read_block: process
|
|
|
variable t_v : unsigned(7 downto 0);
|
variable t_v : unsigned(7 downto 0);
|
|
|
begin
|
begin
|
-- default assignments
|
-- default assignments
|
inc_read_addr_s <= false;
|
inc_read_addr_s <= false;
|
reading_s <= false;
|
reading_s <= false;
|
read_spi_data_s <= '1';
|
read_spi_data_s <= '1';
|
|
|
loop
|
loop
|
if not start_read_s then
|
if not start_read_s then
|
wait until start_read_s;
|
wait until start_read_s;
|
end if;
|
end if;
|
|
|
reading_s <= true;
|
reading_s <= true;
|
|
|
fall_clk(8); -- delay for one "byte"
|
fall_clk(8); -- delay for one "byte"
|
|
|
-- send data token
|
-- send data token
|
fall_clk(7); -- 7 ones in a data token
|
fall_clk(7); -- 7 ones in a data token
|
read_spi_data_s <= '0';
|
read_spi_data_s <= '0';
|
|
|
-- send payload
|
-- send payload
|
for i in 0 to to_integer(block_len_q)-1 loop
|
payload: for i in 0 to to_integer(block_len_q)-1 loop
|
t_v := read_addr_q(0) & calc_crc(read_addr_q);
|
t_v := read_addr_q(0) & calc_crc(read_addr_q);
|
for bit in 7 downto 0 loop
|
for bit in 7 downto 0 loop
|
fall_clk;
|
fall_clk;
|
read_spi_data_s <= t_v(bit);
|
read_spi_data_s <= t_v(bit);
|
|
|
|
exit payload when not start_read_s;
|
end loop;
|
end loop;
|
inc_read_addr_s <= true;
|
inc_read_addr_s <= true;
|
rise_clk;
|
rise_clk;
|
inc_read_addr_s <= false;
|
inc_read_addr_s <= false;
|
wait for 10 ns;
|
wait for 10 ns;
|
end loop;
|
end loop;
|
|
|
|
if start_read_s then
|
-- send crc
|
-- send crc
|
for i in 0 to 15 loop
|
for i in 0 to 15 loop
|
fall_clk;
|
fall_clk;
|
t_v := to_unsigned(i, 8);
|
t_v := to_unsigned(i, 8);
|
read_spi_data_s <= t_v(0);
|
read_spi_data_s <= t_v(0);
|
end loop;
|
end loop;
|
fall_clk;
|
fall_clk;
|
|
end if;
|
|
|
read_spi_data_s <= '1';
|
read_spi_data_s <= '1';
|
reading_s <= false;
|
reading_s <= false;
|
-- loop for one "byte"
|
-- loop for one "byte"
|
fall_clk(8);
|
fall_clk(8);
|
|
|
end loop;
|
end loop;
|
end process read_block;
|
end process read_block;
|
--
|
--
|
-----------------------------------------------------------------------------
|
-----------------------------------------------------------------------------
|
|
|
|
|
-----------------------------------------------------------------------------
|
-----------------------------------------------------------------------------
|
--
|
--
|
clk_check: process (spi_clk_i)
|
clk_check: process (spi_clk_i)
|
|
|
variable last_rising_v : time := 0 ns;
|
variable last_rising_v : time := 0 ns;
|
variable dump_line : line;
|
variable dump_line : line;
|
|
|
begin
|
begin
|
if spi_clk_i'event and spi_clk_i = '1' then
|
if spi_clk_i'event and spi_clk_i = '1' then
|
if is_sd_card_g = 0 and card_type_g /= "Minimal Chip" and
|
if is_sd_card_g = 0 and card_type_g /= "Minimal Chip" and
|
idle_mode_q > 0 then
|
idle_mode_q > 0 then
|
if now - last_rising_v < 2.5 us and last_rising_v > 0 ns then
|
if now - last_rising_v < 2.5 us and last_rising_v > 0 ns then
|
write(dump_line, card_type_g);
|
write(dump_line, card_type_g);
|
write(dump_line, string'(" @ "));
|
write(dump_line, string'(" @ "));
|
write(dump_line, now);
|
write(dump_line, now);
|
write(dump_line, string'(": Last rising edge of SPI clock "));
|
write(dump_line, string'(": Last rising edge of SPI clock "));
|
write(dump_line, now - last_rising_v);
|
write(dump_line, now - last_rising_v);
|
write(dump_line, string'(" ago."));
|
write(dump_line, string'(" ago."));
|
writeline(output, dump_line);
|
writeline(output, dump_line);
|
end if;
|
end if;
|
|
|
last_rising_v := now;
|
last_rising_v := now;
|
end if;
|
end if;
|
end if;
|
end if;
|
end process clk_check;
|
end process clk_check;
|
--
|
--
|
-----------------------------------------------------------------------------
|
-----------------------------------------------------------------------------
|
|
|
|
|
-----------------------------------------------------------------------------
|
-----------------------------------------------------------------------------
|
-- Output Mapping
|
-- Output Mapping
|
-----------------------------------------------------------------------------
|
-----------------------------------------------------------------------------
|
spi_data_o <= cmd_spi_data_s and read_spi_data_s
|
spi_data_o <= cmd_spi_data_s and read_spi_data_s
|
when spi_cs_n_i = '0' else
|
when spi_cs_n_i = '0' else
|
'Z';
|
'Z';
|
|
|
end behav;
|
end behav;
|
|
|
|
|
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
-- File History:
|
-- File History:
|
--
|
--
|
-- $Log: not supported by cvs2svn $
|
-- $Log: not supported by cvs2svn $
|
|
-- Revision 1.1 2005/02/08 21:09:20 arniml
|
|
-- initial check-in
|
|
--
|
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
|
|