OpenCores
URL https://opencores.org/ocsvn/spi_boot/spi_boot/trunk

Subversion Repositories spi_boot

Compare Revisions

  • This comparison shows the changes necessary to convert path
    /spi_boot/trunk/bench/vhdl
    from Rev 42 to Rev 74
    Reverse comparison

Rev 42 → Rev 74

/tb_rl-c.vhd
0,0 → 1,27
-------------------------------------------------------------------------------
--
-- SD/MMC Bootloader
--
-- $Id: tb_rl-c.vhd,v 1.1 2005-04-10 18:07:26 arniml Exp $
--
-------------------------------------------------------------------------------
 
configuration tb_rl_behav_c0 of tb_rl is
 
for behav
 
for dut_b : chip
use configuration work.chip_full_c0;
end for;
 
for card_b : card
use configuration work.card_behav_c0;
end for;
 
for rl_b : ram_loader
use configuration work.ram_loader_rtl_c0;
end for;
 
end for;
 
end tb_rl_behav_c0;
/tb_rl.vhd
0,0 → 1,256
-------------------------------------------------------------------------------
--
-- SD/MMC Bootloader
-- Testbench for ram_loader
--
-- $Id: tb_rl.vhd,v 1.1 2005-04-10 18:07:25 arniml Exp $
--
-- Copyright (c) 2005, Arnim Laeuger (arniml@opencores.org)
--
-- All rights reserved, see COPYING.
--
-- Redistribution and use in source and synthezised forms, with or without
-- modification, are permitted provided that the following conditions are met:
--
-- Redistributions of source code must retain the above copyright notice,
-- this list of conditions and the following disclaimer.
--
-- Redistributions in synthesized form must reproduce the above copyright
-- notice, this list of conditions and the following disclaimer in the
-- documentation and/or other materials provided with the distribution.
--
-- 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
-- specific prior written permission.
--
-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
-- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
-- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE
-- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-- 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
-- POSSIBILITY OF SUCH DAMAGE.
--
-- Please report bugs to the author, but before you do so, please
-- make sure that this is not a derivative work and that
-- you have the latest version of this file.
--
-- The latest version of this file can be found at:
-- http://www.opencores.org/projects.cgi/web/spi_boot/overview
--
-------------------------------------------------------------------------------
 
entity tb_rl is
 
end tb_rl;
 
 
library ieee;
use ieee.std_logic_1164.all;
 
architecture behav of tb_rl is
 
component chip
port (
clk_i : in std_logic;
reset_i : in std_logic;
set_sel_n_i : in std_logic_vector(3 downto 0);
spi_clk_o : out std_logic;
spi_cs_n_o : out std_logic;
spi_data_in_i : in std_logic;
spi_data_out_o : out std_logic;
start_i : in std_logic;
mode_i : in std_logic;
config_n_o : out std_logic;
detached_o : out std_logic;
cfg_init_n_i : in std_logic;
cfg_done_i : in std_logic;
dat_done_i : in std_logic;
cfg_clk_o : out std_logic;
cfg_dat_o : out std_logic
);
end component;
 
component card
generic (
card_type_g : string := "none";
is_sd_card_g : integer := 1
);
port (
spi_clk_i : in std_logic;
spi_cs_n_i : in std_logic;
spi_data_i : in std_logic;
spi_data_o : out std_logic
);
end component;
 
component ram_loader
port (
clk_i : in std_logic;
reset_i : in std_logic;
lamp_o : out std_logic;
cfg_clk_i : in std_logic;
cfg_data_i : in std_logic;
start_o : out std_logic;
mode_o : out std_logic;
done_o : out std_logic;
detached_i : in std_logic;
ram_addr_o : out std_logic_vector(15 downto 0);
ram_data_b : out std_logic_vector( 7 downto 0);
ram_ce_no : out std_logic_vector( 3 downto 0);
ram_oe_no : out std_logic;
ram_we_no : out std_logic
);
end component;
 
constant period_c : time := 100 ns;
constant rl_period_c : time := 20 ns;
constant reset_level_c : integer := 0;
 
signal clk_s : std_logic;
signal rl_clk_s: std_logic;
signal reset_s : std_logic;
 
-- SPI interface signals
signal spi_clk_s : std_logic;
signal spi_data_to_card_s : std_logic;
signal spi_data_from_card_s : std_logic;
signal spi_cs_n_s : std_logic;
 
-- config related signals
signal start_s : std_logic;
signal mode_s : std_logic;
signal config_n_s : std_logic;
signal cfg_init_n_s : std_logic;
signal cfg_done_s : std_logic;
signal dat_done_s : std_logic;
signal cfg_clk_s : std_logic;
signal cfg_dat_s : std_logic;
signal detached_s : std_logic;
 
signal set_sel_n_s : std_logic_vector(3 downto 0);
 
begin
 
set_sel_n_s <= (others => '1');
cfg_init_n_s <= '1';
cfg_done_s <= '1';
 
-----------------------------------------------------------------------------
-- DUT
-----------------------------------------------------------------------------
dut_b : chip
port map (
clk_i => clk_s,
reset_i => reset_s,
set_sel_n_i => set_sel_n_s,
spi_clk_o => spi_clk_s,
spi_cs_n_o => spi_cs_n_s,
spi_data_in_i => spi_data_from_card_s,
spi_data_out_o => spi_data_to_card_s,
start_i => start_s,
mode_i => mode_s,
config_n_o => config_n_s,
detached_o => detached_s,
cfg_init_n_i => cfg_init_n_s,
cfg_done_i => cfg_done_s,
dat_done_i => dat_done_s,
cfg_clk_o => cfg_clk_s,
cfg_dat_o => cfg_dat_s
);
 
card_b : card
generic map (
card_type_g => "Full Chip",
is_sd_card_g => 1
)
port map (
spi_clk_i => spi_clk_s,
spi_cs_n_i => spi_cs_n_s,
spi_data_i => spi_data_to_card_s,
spi_data_o => spi_data_from_card_s
);
 
rl_b : ram_loader
port map (
clk_i => rl_clk_s,
reset_i => reset_s,
lamp_o => open,
cfg_clk_i => cfg_clk_s,
cfg_data_i => cfg_dat_s,
start_o => start_s,
mode_o => mode_s,
done_o => dat_done_s,
detached_i => detached_s,
ram_addr_o => open,
ram_data_b => open,
ram_ce_no => open,
ram_oe_no => open,
ram_we_no => open
);
 
-----------------------------------------------------------------------------
-- Clock Generator
-----------------------------------------------------------------------------
clk: process
begin
clk_s <= '0';
wait for period_c / 2;
clk_s <= '1';
wait for period_c / 2;
end process clk;
 
rl_clk: process
begin
rl_clk_s <= '0';
wait for rl_period_c / 2;
rl_clk_s <= '1';
wait for rl_period_c / 2;
end process rl_clk;
 
 
-----------------------------------------------------------------------------
-- Reset Generator
-----------------------------------------------------------------------------
reset: process
begin
if reset_level_c = 0 then
reset_s <= '0';
else
reset_s <= '1';
end if;
 
wait for period_c * 4 + 10 ns;
 
reset_s <= not reset_s;
 
wait;
end process reset;
 
 
-----------------------------------------------------------------------------
-- End of Simulation
-----------------------------------------------------------------------------
eos: process
begin
wait for 4 ms;
assert false
report "No checks have been performed. Investigate waveforms."
severity note;
assert false
report "End of simulation."
severity failure;
end process eos;
 
end behav;
 
 
-------------------------------------------------------------------------------
-- File History:
--
-- $Log: not supported by cvs2svn $
-------------------------------------------------------------------------------
/tb_elem.vhd
0,0 → 1,373
-------------------------------------------------------------------------------
--
-- SD/MMC Bootloader
-- Generic testbench element for a specific feature set
--
-- $Id: tb_elem.vhd,v 1.7 2005-04-07 20:43:36 arniml Exp $
--
-- Copyright (c) 2005, Arnim Laeuger (arniml@opencores.org)
--
-- All rights reserved, see COPYING.
--
-- Redistribution and use in source and synthezised forms, with or without
-- modification, are permitted provided that the following conditions are met:
--
-- Redistributions of source code must retain the above copyright notice,
-- this list of conditions and the following disclaimer.
--
-- Redistributions in synthesized form must reproduce the above copyright
-- notice, this list of conditions and the following disclaimer in the
-- documentation and/or other materials provided with the distribution.
--
-- 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
-- specific prior written permission.
--
-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
-- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
-- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE
-- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-- 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
-- POSSIBILITY OF SUCH DAMAGE.
--
-- Please report bugs to the author, but before you do so, please
-- make sure that this is not a derivative work and that
-- you have the latest version of this file.
--
-- The latest version of this file can be found at:
-- http://www.opencores.org/projects.cgi/web/spi_boot/overview
--
-------------------------------------------------------------------------------
 
library ieee;
use ieee.std_logic_1164.all;
 
 
entity tb_elem is
 
generic (
chip_type_g : string := "none";
has_sd_card_g : integer := 1
);
port (
clk_i : in std_logic;
reset_i : in std_logic;
eos_o : out boolean
);
 
end tb_elem;
 
 
library ieee;
use ieee.numeric_std.all;
library std;
use std.textio.all;
 
use work.spi_boot_pack.all;
use work.tb_pack.all;
 
architecture behav of tb_elem is
 
component chip
port (
clk_i : in std_logic;
reset_i : in std_logic;
set_sel_n_i : in std_logic_vector(3 downto 0);
spi_clk_o : out std_logic;
spi_cs_n_o : out std_logic;
spi_data_in_i : in std_logic;
spi_data_out_o : out std_logic;
start_i : in std_logic;
mode_i : in std_logic;
config_n_o : out std_logic;
detached_o : out std_logic;
cfg_init_n_i : in std_logic;
cfg_done_i : in std_logic;
dat_done_i : in std_logic;
cfg_clk_o : out std_logic;
cfg_dat_o : out std_logic
);
end component;
 
component card
generic (
card_type_g : string := "none";
is_sd_card_g : integer := 1
);
port (
spi_clk_i : in std_logic;
spi_cs_n_i : in std_logic;
spi_data_i : in std_logic;
spi_data_o : out std_logic
);
end component;
 
signal reset_s : std_logic;
 
-- SPI interface signals
signal spi_clk_s : std_logic;
signal spi_data_to_card_s : std_logic;
signal spi_data_from_card_s : std_logic;
signal spi_cs_n_s : std_logic;
 
-- config related signals
signal start_s : std_logic;
signal mode_s : std_logic;
signal config_n_s : std_logic;
signal cfg_init_n_s : std_logic;
signal cfg_done_s : std_logic;
signal dat_done_s : std_logic;
signal cfg_clk_s : std_logic;
signal cfg_dat_s : std_logic;
signal data_s : unsigned(7 downto 0);
 
signal set_sel_n_s : std_logic_vector(3 downto 0);
 
constant verbose_c : boolean := false;
 
begin
 
-- weak pull-ups
spi_clk_s <= 'H';
spi_cs_n_s <= 'H';
spi_data_to_card_s <= 'H';
 
-----------------------------------------------------------------------------
-- DUT
-----------------------------------------------------------------------------
dut_b : chip
port map (
clk_i => clk_i,
reset_i => reset_s,
set_sel_n_i => set_sel_n_s,
spi_clk_o => spi_clk_s,
spi_cs_n_o => spi_cs_n_s,
spi_data_in_i => spi_data_from_card_s,
spi_data_out_o => spi_data_to_card_s,
start_i => start_s,
mode_i => mode_s,
config_n_o => config_n_s,
detached_o => open,
cfg_init_n_i => cfg_init_n_s,
cfg_done_i => cfg_done_s,
dat_done_i => dat_done_s,
cfg_clk_o => cfg_clk_s,
cfg_dat_o => cfg_dat_s
);
 
card_b : card
generic map (
card_type_g => chip_type_g,
is_sd_card_g => has_sd_card_g
)
port map (
spi_clk_i => spi_clk_s,
spi_cs_n_i => spi_cs_n_s,
spi_data_i => spi_data_to_card_s,
spi_data_o => spi_data_from_card_s
);
 
 
-----------------------------------------------------------------------------
-- DUT Stimuli
--
stim: process
 
procedure rise_cfg_clk(num : integer) is
begin
for i in 1 to num loop
wait until cfg_clk_s'event and cfg_clk_s = '1';
end loop;
end rise_cfg_clk;
 
-- procedure fall_cfg_clk(num : integer) is
-- begin
-- for i in 1 to num loop
-- wait until cfg_clk_s'event and cfg_clk_s = '0';
-- end loop;
-- end fall_cfg_clk;
 
procedure rise_clk(num : integer) is
begin
for i in 1 to num loop
wait until clk_i'event and clk_i = '1';
end loop;
end rise_clk;
 
procedure read_check_byte(ref : unsigned(7 downto 0)) is
variable byte_v : unsigned(7 downto 0);
variable dump_line : line;
begin
for bit in 7 downto 0 loop
rise_cfg_clk(1);
byte_v(bit) := cfg_dat_s;
end loop;
data_s <= byte_v;
 
if byte_v /= ref then
write(dump_line, chip_type_g);
write(dump_line, string'(" at "));
write(dump_line, now);
write(dump_line, string'(": read_check_byte failed "));
write(dump_line, to_integer(byte_v));
write(dump_line, string'(" "));
write(dump_line, to_integer(ref));
writeline(output, dump_line);
end if;
end read_check_byte;
 
variable dump_line : line;
variable addr_v : unsigned(31 downto 0);
variable temp_v : unsigned( 7 downto 0);
variable set_sel_v : unsigned(3 downto 0);
 
begin
-- default assignments
-- these defaults show the required pull resistors
-- except start_i as this must be pulled high for automatic start
start_s <= '0';
mode_s <= '1';
cfg_init_n_s <= '1';
cfg_done_s <= '0';
dat_done_s <= '1';
data_s <= (others => '1');
addr_v := (others => '0');
eos_o <= false;
set_sel_n_s <= (others => '1');
reset_s <= '0';
 
-- loop through some sets
for set in 0 to 3 loop
set_sel_v := to_unsigned(set, 4);
addr_v(23 downto 20) := set_sel_v; -- must match num_bits_per_img_g
-- plus width_img_cnt_g
set_sel_n_s <= not std_logic_vector(set_sel_v);
 
assert not verbose_c
report chip_type_g & ": Processing set " & to_string(set)
severity note;
 
wait for 100 us;
reset_s <= '1';
 
assert not verbose_c
report chip_type_g & ": Requesting image 0"
severity note;
 
-- signal start
start_s <= '1';
mode_s <= '1';
cfg_done_s <= '0';
addr_v(19 downto 0) := (others => '0');
wait until config_n_s = '0';
-- run through configuration sequence
rise_clk(1);
cfg_init_n_s <= '0';
rise_clk(3);
cfg_init_n_s <= '1';
 
-- and receive 32 bytes from image 0
for i in 1 to 32 loop
temp_v := addr_v(0) & calc_crc(addr_v);
read_check_byte(temp_v);
addr_v := addr_v + 1;
end loop;
start_s <= '0';
cfg_done_s <= '1';
 
rise_clk(10);
 
assert not verbose_c
report chip_type_g & ": Requesting image 1"
severity note;
 
-- request next image
mode_s <= '0';
start_s <= '1';
addr_v(17 downto 0) := (others => '0');
addr_v(19 downto 18) := "01"; -- must match num_bits_per_img_g in chip-*-a.vhd
dat_done_s <= '0';
 
-- receive another 32 bytes from image 1
for i in 1 to 32 loop
temp_v := addr_v(0) & calc_crc(addr_v);
read_check_byte(temp_v);
addr_v := addr_v + 1;
end loop;
start_s <= '0';
dat_done_s <= '1';
 
rise_clk(10);
 
assert not verbose_c
report chip_type_g & ": Requesting image 2"
severity note;
 
-- request next image
mode_s <= '1';
start_s <= '1';
addr_v(17 downto 0) := (others => '0');
addr_v(19 downto 18) := "10"; -- must match num_bits_per_img_g in chip-*-a.vhd
 
wait until config_n_s = '0';
-- run through configuration sequence
rise_clk(1);
cfg_done_s <= '0';
cfg_init_n_s <= '0';
rise_clk(3);
cfg_init_n_s <= '1';
 
-- receive another 32 bytes from image 2
for i in 1 to 32 loop
temp_v := addr_v(0) & calc_crc(addr_v);
read_check_byte(temp_v);
addr_v := addr_v + 1;
end loop;
start_s <= '0';
cfg_done_s <= '1';
 
-- give dut a chance to stop current transfer
wait until spi_cs_n_s = '1';
rise_clk(10);
 
reset_s <= '0';
end loop;
 
eos_o <= true;
wait;
end process stim;
--
-----------------------------------------------------------------------------
 
end behav;
 
 
-------------------------------------------------------------------------------
-- File History:
--
-- $Log: not supported by cvs2svn $
-- Revision 1.6 2005/03/09 19:48:04 arniml
-- make verbosity level switchable
--
-- Revision 1.5 2005/03/08 22:06:21 arniml
-- added set selection
--
-- Revision 1.4 2005/02/17 18:59:23 arniml
-- clarify wording for images
--
-- Revision 1.3 2005/02/16 19:34:56 arniml
-- add weak pull-ups for SPI lines
--
-- Revision 1.2 2005/02/13 17:14:03 arniml
-- change dat_done handling
--
-- Revision 1.1 2005/02/08 21:09:20 arniml
-- initial check-in
--
-------------------------------------------------------------------------------
/tb_pack-p.vhd
0,0 → 1,90
-------------------------------------------------------------------------------
--
-- SD/MMC Bootloader
--
-- $Id: tb_pack-p.vhd,v 1.2 2005-03-08 22:06:39 arniml Exp $
--
-------------------------------------------------------------------------------
 
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
 
package tb_pack is
 
function calc_crc(payload : in std_logic_vector) return std_logic_vector;
function calc_crc(payload : in unsigned) return unsigned;
 
function to_string(value : in integer) return string;
 
end tb_pack;
 
 
package body tb_pack is
 
function calc_crc(payload : in std_logic_vector) return std_logic_vector is
 
variable crc_v : std_logic_vector(6 downto 0);
variable temp_v : std_logic;
 
begin
 
crc_v := (others => '0');
 
for i in payload'high downto payload'low loop
temp_v := payload(i) xor crc_v(6);
 
crc_v(6 downto 4) := crc_v(5 downto 3);
crc_v(3) := crc_v(2) xor temp_v;
crc_v(2 downto 1) := crc_v(1 downto 0);
crc_v(0) := temp_v;
end loop;
 
return crc_v;
end calc_crc;
 
function calc_crc(payload : in unsigned) return unsigned is
begin
return unsigned(calc_crc(std_logic_vector(payload)));
end calc_crc;
 
function to_string(value : in integer) return string is
variable str: string (11 downto 1);
variable val: integer := value;
variable digit: natural;
variable index: natural := 0;
begin
-- Taken from:
-- textio package body. This file is part of GHDL.
-- Copyright (C) 2002 Tristan Gingold.
-- Note: the absolute value of VAL cannot be directly taken, since
-- it may be greather that the maximum value of an INTEGER.
loop
-- LRM93 7.2.6
-- (A rem B) has the sign of A and an absolute value less then
-- the absoulte value of B.
digit := abs (val rem 10);
val := val / 10;
index := index + 1;
str (index) := character'val(48 + digit);
exit when val = 0;
end loop;
if value < 0 then
index := index + 1;
str(index) := '-';
end if;
 
return str;
end to_string;
 
end tb_pack;
 
 
-------------------------------------------------------------------------------
-- File History:
--
-- $Log: not supported by cvs2svn $
-- Revision 1.1 2005/02/08 21:09:20 arniml
-- initial check-in
--
-------------------------------------------------------------------------------
/card.vhd
0,0 → 1,443
-------------------------------------------------------------------------------
--
-- SD/MMC Bootloader
-- Simple SD and MMC model
--
-- $Id: card.vhd,v 1.2 2005-02-13 17:06:22 arniml Exp $
--
-- Copyright (c) 2005, Arnim Laeuger (arniml@opencores.org)
--
-- All rights reserved, see COPYING.
--
-- Redistribution and use in source and synthezised forms, with or without
-- modification, are permitted provided that the following conditions are met:
--
-- Redistributions of source code must retain the above copyright notice,
-- this list of conditions and the following disclaimer.
--
-- Redistributions in synthesized form must reproduce the above copyright
-- notice, this list of conditions and the following disclaimer in the
-- documentation and/or other materials provided with the distribution.
--
-- 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
-- specific prior written permission.
--
-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
-- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
-- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE
-- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-- 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
-- POSSIBILITY OF SUCH DAMAGE.
--
-- Please report bugs to the author, but before you do so, please
-- make sure that this is not a derivative work and that
-- you have the latest version of this file.
--
-- The latest version of this file can be found at:
-- http://www.opencores.org/projects.cgi/web/spi_boot/overview
--
-------------------------------------------------------------------------------
 
library ieee;
use ieee.std_logic_1164.all;
 
 
entity card is
 
generic (
card_type_g : string := "none";
is_sd_card_g : integer := 1
);
 
port (
spi_clk_i : in std_logic;
spi_cs_n_i : in std_logic;
spi_data_i : in std_logic;
spi_data_o : out std_logic
);
 
end card;
 
 
library ieee;
use ieee.numeric_std.all;
library std;
use std.textio.all;
 
use work.tb_pack.all;
 
architecture behav of card is
 
signal power_on_n_s : std_logic;
signal soft_res_n_s : std_logic;
signal res_n_s : std_logic;
 
signal rx_s : std_logic_vector(47 downto 0);
 
signal set_spi_mode_s,
spi_mode_q : boolean;
signal set_idle_mode_s,
poll_idle_mode_s : boolean;
signal idle_mode_q : natural;
 
signal block_len_q,
block_len_s : unsigned(31 downto 0);
signal set_block_len_s : boolean;
 
signal new_read_addr_s,
read_addr_q : unsigned(31 downto 0);
signal set_read_addr_s,
inc_read_addr_s : boolean;
 
signal cmd_spi_data_s,
read_spi_data_s : std_logic;
signal start_read_s : boolean;
signal reading_s : boolean;
 
procedure rise_clk is
begin
wait until spi_clk_i'event and to_X01(spi_clk_i) = '1';
end rise_clk;
 
-- procedure rise_clk(num : natural) is
-- begin
-- for i in 1 to num loop
-- rise_clk;
-- end loop;
-- end rise_clk;
 
procedure fall_clk is
begin
wait until spi_clk_i'event and to_X01(spi_clk_i) = '0';
end fall_clk;
 
procedure fall_clk(num : natural) is
begin
for i in 1 to num loop
fall_clk;
end loop;
end fall_clk;
 
begin
 
res_n_s <= power_on_n_s and soft_res_n_s;
 
-----------------------------------------------------------------------------
-- Power on reset
-----------------------------------------------------------------------------
por: process
begin
power_on_n_s <= '0';
wait for 200 ns;
power_on_n_s <= '1';
wait;
end process por;
 
 
-----------------------------------------------------------------------------
--
ctrl: process
 
function check_crc(payload : in std_logic_vector(47 downto 0))
return boolean is
 
begin
 
return calc_crc(payload(47 downto 8)) = payload(7 downto 1);
end check_crc;
 
variable rx_v : std_logic_vector(47 downto 0);
variable cmd_v : std_logic_vector( 5 downto 0);
variable arg_v : std_logic_vector(31 downto 0);
variable crc_v : std_logic_vector( 6 downto 0);
variable wrong_v : std_logic;
variable read_data_v : boolean;
 
begin
rx_s <= (others => '0');
set_spi_mode_s <= false;
set_idle_mode_s <= false;
poll_idle_mode_s <= false;
cmd_spi_data_s <= '1';
soft_res_n_s <= '1';
set_block_len_s <= false;
block_len_s <= (others => '0');
new_read_addr_s <= (others => '0');
set_read_addr_s <= false;
start_read_s <= false;
read_data_v := false;
 
loop
 
rise_clk;
-- wait for startbit of command
while to_X01(spi_data_i) = '1' loop
rise_clk;
end loop;
rx_v(47) := '0';
 
-- read remaining 47 bits of command
for i in 46 downto 0 loop
rise_clk;
rx_v(i) := to_X01(spi_data_i);
end loop;
rx_s <= rx_v;
 
-- dissect received data
cmd_v := rx_v(45 downto 40);
arg_v := rx_v(39 downto 8);
crc_v := rx_v( 7 downto 1);
 
assert spi_mode_q or check_crc(payload => rx_v)
report "CRC mismatch"
severity error;
 
wrong_v := '0';
case cmd_v is
-- CMD0: GO_IDLE_STATE ------------------------------------------------
when "000000" =>
set_spi_mode_s <= true;
set_idle_mode_s <= true;
-- CMD1: SEND_OP_COND -------------------------------------------------
when "000001" =>
poll_idle_mode_s <= true;
-- CMD12: STOP_TRANSMISSION -------------------------------------------
when "001100" =>
start_read_s <= false;
read_data_v := false;
-- CMD16: SET_BLOCKLEN ------------------------------------------------
when "010000" =>
block_len_s <= unsigned(arg_v);
set_block_len_s <= true;
-- CMD18: READ_MULTIPLE_BLOCK -----------------------------------------
when "010010" =>
new_read_addr_s <= unsigned(arg_v);
set_read_addr_s <= true;
read_data_v := true;
-- CMD55: APPL_CMD ----------------------------------------------------
when "110111" =>
-- command only available for SD card
if is_sd_card_g /= 1 then
wrong_v := '1';
end if;
-- ACMD41: SEND_OP_COND -----------------------------------------------
when "101001" =>
-- command only available for SD card
if is_sd_card_g /= 1 then
wrong_v := '1';
else
poll_idle_mode_s <= true;
end if;
 
when others =>
wrong_v := '1';
null;
end case;
 
 
-- spend some time before removing control signals
fall_clk(2);
poll_idle_mode_s <= false;
set_idle_mode_s <= false;
fall_clk(6);
set_spi_mode_s <= false;
set_block_len_s <= false;
set_read_addr_s <= false;
 
if reading_s then
wait until not reading_s;
end if;
 
 
-- wait for a total two "bytes" before sending out response
for i in 1 to 8 loop
fall_clk;
end loop;
 
for i in 7 downto 0 loop
fall_clk;
case i is
when 2 =>
cmd_spi_data_s <= wrong_v;
when 0 =>
if idle_mode_q = 0 then
cmd_spi_data_s <= '0';
else
cmd_spi_data_s <= '1';
end if;
when others =>
cmd_spi_data_s <= '0';
end case;
end loop;
fall_clk;
cmd_spi_data_s <= '1';
 
-- transmit data if requested
start_read_s <= read_data_v;
 
end loop;
end process ctrl;
--
-----------------------------------------------------------------------------
 
 
-----------------------------------------------------------------------------
--
seq: process (res_n_s,
spi_clk_i,
set_spi_mode_s,
set_idle_mode_s,
poll_idle_mode_s,
set_block_len_s,
block_len_s)
 
begin
if res_n_s = '0' then
spi_mode_q <= false;
idle_mode_q <= 5;
block_len_q <= (others => '0');
read_addr_q <= (others => '0');
 
elsif spi_clk_i'event and spi_clk_i = '1' then
if set_spi_mode_s then
spi_mode_q <= true;
end if;
 
if set_idle_mode_s then
idle_mode_q <= 5;
elsif poll_idle_mode_s then
if idle_mode_q > 0 then
idle_mode_q <= idle_mode_q - 1;
end if;
end if;
 
if set_block_len_s then
block_len_q <= block_len_s;
end if;
 
if set_read_addr_s then
read_addr_q <= new_read_addr_s;
elsif inc_read_addr_s then
read_addr_q <= read_addr_q + 1;
end if;
 
end if;
end process seq;
--
-----------------------------------------------------------------------------
 
 
-----------------------------------------------------------------------------
--
read_block: process
 
variable t_v : unsigned(7 downto 0);
 
begin
-- default assignments
inc_read_addr_s <= false;
reading_s <= false;
read_spi_data_s <= '1';
 
loop
if not start_read_s then
wait until start_read_s;
end if;
 
reading_s <= true;
 
fall_clk(8); -- delay for one "byte"
 
-- send data token
fall_clk(7); -- 7 ones in a data token
read_spi_data_s <= '0';
 
-- send payload
payload: for i in 0 to to_integer(block_len_q)-1 loop
t_v := read_addr_q(0) & calc_crc(read_addr_q);
for bit in 7 downto 0 loop
fall_clk;
read_spi_data_s <= t_v(bit);
 
exit payload when not start_read_s;
end loop;
inc_read_addr_s <= true;
rise_clk;
inc_read_addr_s <= false;
wait for 10 ns;
end loop;
 
if start_read_s then
-- send crc
for i in 0 to 15 loop
fall_clk;
t_v := to_unsigned(i, 8);
read_spi_data_s <= t_v(0);
end loop;
fall_clk;
end if;
 
read_spi_data_s <= '1';
reading_s <= false;
-- loop for one "byte"
fall_clk(8);
 
end loop;
end process read_block;
--
-----------------------------------------------------------------------------
 
 
-----------------------------------------------------------------------------
--
clk_check: process (spi_clk_i)
 
variable last_rising_v : time := 0 ns;
variable dump_line : line;
 
begin
if spi_clk_i'event and spi_clk_i = '1' then
if is_sd_card_g = 0 and card_type_g /= "Minimal Chip" and
idle_mode_q > 0 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, string'(" @ "));
write(dump_line, now);
write(dump_line, string'(": Last rising edge of SPI clock "));
write(dump_line, now - last_rising_v);
write(dump_line, string'(" ago."));
writeline(output, dump_line);
end if;
 
last_rising_v := now;
end if;
end if;
end process clk_check;
--
-----------------------------------------------------------------------------
 
 
-----------------------------------------------------------------------------
-- Output Mapping
-----------------------------------------------------------------------------
spi_data_o <= cmd_spi_data_s and read_spi_data_s
when spi_cs_n_i = '0' else
'Z';
 
end behav;
 
 
-------------------------------------------------------------------------------
-- File History:
--
-- $Log: not supported by cvs2svn $
-- Revision 1.1 2005/02/08 21:09:20 arniml
-- initial check-in
--
-------------------------------------------------------------------------------
/tb_elem-mmc-c.vhd
0,0 → 1,23
-------------------------------------------------------------------------------
--
-- SD/MMC Bootloader
--
-- $Id: tb_elem-mmc-c.vhd,v 1.1 2005-02-08 21:09:20 arniml Exp $
--
-------------------------------------------------------------------------------
 
configuration tb_elem_behav_mmc of tb_elem is
 
for behav
 
for dut_b : chip
use configuration work.chip_mmc_c0;
end for;
 
for card_b : card
use configuration work.card_behav_c0;
end for;
 
end for;
 
end tb_elem_behav_mmc;
/tb-c.vhd
0,0 → 1,31
-------------------------------------------------------------------------------
--
-- SD/MMC Bootloader
--
-- $Id: tb-c.vhd,v 1.1 2005-02-08 21:09:20 arniml Exp $
--
-------------------------------------------------------------------------------
 
configuration tb_behav_c0 of tb is
 
for behav
 
for tb_elem_full_b : tb_elem
use configuration work.tb_elem_behav_full;
end for;
 
for tb_elem_mmc_b : tb_elem
use configuration work.tb_elem_behav_mmc;
end for;
 
for tb_elem_sd_b : tb_elem
use configuration work.tb_elem_behav_sd;
end for;
 
for tb_elem_minimal_b : tb_elem
use configuration work.tb_elem_behav_minimal;
end for;
 
end for;
 
end tb_behav_c0;
/tb.vhd
0,0 → 1,198
-------------------------------------------------------------------------------
--
-- SD/MMC Bootloader
-- Testbench
--
-- $Id: tb.vhd,v 1.1 2005-02-08 21:09:20 arniml Exp $
--
-- Copyright (c) 2005, Arnim Laeuger (arniml@opencores.org)
--
-- All rights reserved, see COPYING.
--
-- Redistribution and use in source and synthezised forms, with or without
-- modification, are permitted provided that the following conditions are met:
--
-- Redistributions of source code must retain the above copyright notice,
-- this list of conditions and the following disclaimer.
--
-- Redistributions in synthesized form must reproduce the above copyright
-- notice, this list of conditions and the following disclaimer in the
-- documentation and/or other materials provided with the distribution.
--
-- 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
-- specific prior written permission.
--
-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
-- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
-- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE
-- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-- 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
-- POSSIBILITY OF SUCH DAMAGE.
--
-- Please report bugs to the author, but before you do so, please
-- make sure that this is not a derivative work and that
-- you have the latest version of this file.
--
-- The latest version of this file can be found at:
-- http://www.opencores.org/projects.cgi/web/spi_boot/overview
--
-------------------------------------------------------------------------------
 
entity tb is
 
end tb;
 
 
library ieee;
use ieee.std_logic_1164.all;
 
architecture behav of tb is
 
component tb_elem
generic (
chip_type_g : string := "none";
has_sd_card_g : integer := 1
);
port (
clk_i : in std_logic;
reset_i : in std_logic;
eos_o : out boolean
);
end component;
 
constant period_c : time := 100 ns;
constant reset_level_c : integer := 0;
 
signal clk_s : std_logic;
signal reset_s : std_logic;
 
signal eos_full_s,
eos_mmc_s,
eos_sd_s,
eos_minimal_s : boolean;
 
begin
 
 
-----------------------------------------------------------------------------
-- Testbench element including full featured chip
-----------------------------------------------------------------------------
tb_elem_full_b : tb_elem
generic map (
chip_type_g => "Full Chip",
has_sd_card_g => 1
)
port map (
clk_i => clk_s,
reset_i => reset_s,
eos_o => eos_full_s
);
 
 
-----------------------------------------------------------------------------
-- Testbench element including MMC chip
-----------------------------------------------------------------------------
tb_elem_mmc_b : tb_elem
generic map (
chip_type_g => "MMC Chip",
has_sd_card_g => 0
)
port map (
clk_i => clk_s,
reset_i => reset_s,
eos_o => eos_mmc_s
);
 
 
-----------------------------------------------------------------------------
-- Testbench element including SD chip
-----------------------------------------------------------------------------
tb_elem_sd_b : tb_elem
generic map (
chip_type_g => "SD Chip",
has_sd_card_g => 1
)
port map (
clk_i => clk_s,
reset_i => reset_s,
eos_o => eos_sd_s
);
 
 
-----------------------------------------------------------------------------
-- Testbench element including cip with minimal features
-----------------------------------------------------------------------------
tb_elem_minimal_b : tb_elem
generic map (
chip_type_g => "Minimal Chip",
has_sd_card_g => 0
)
port map (
clk_i => clk_s,
reset_i => reset_s,
eos_o => eos_minimal_s
);
 
 
-----------------------------------------------------------------------------
-- Clock Generator
-----------------------------------------------------------------------------
clk: process
begin
clk_s <= '0';
wait for period_c / 2;
clk_s <= '1';
wait for period_c / 2;
end process clk;
 
 
-----------------------------------------------------------------------------
-- Reset Generator
-----------------------------------------------------------------------------
reset: process
begin
if reset_level_c = 0 then
reset_s <= '0';
else
reset_s <= '1';
end if;
 
wait for period_c * 4 + 10 ns;
 
reset_s <= not reset_s;
 
wait;
end process reset;
 
 
-----------------------------------------------------------------------------
-- End Of Simulation Detection
-----------------------------------------------------------------------------
eos: process (eos_full_s,
eos_mmc_s,
eos_sd_s,
eos_minimal_s)
begin
 
if eos_full_s and eos_mmc_s and eos_sd_s and eos_minimal_s then
assert false
report "End of Simulation."
severity failure;
end if;
 
end process eos;
 
end behav;
 
 
-------------------------------------------------------------------------------
-- File History:
--
-- $Log: not supported by cvs2svn $
-------------------------------------------------------------------------------
/tb_elem-full-c.vhd
0,0 → 1,23
-------------------------------------------------------------------------------
--
-- SD/MMC Bootloader
--
-- $Id: tb_elem-full-c.vhd,v 1.1 2005-02-08 21:09:20 arniml Exp $
--
-------------------------------------------------------------------------------
 
configuration tb_elem_behav_full of tb_elem is
 
for behav
 
for dut_b : chip
use configuration work.chip_full_c0;
end for;
 
for card_b : card
use configuration work.card_behav_c0;
end for;
 
end for;
 
end tb_elem_behav_full;
/card-c.vhd
0,0 → 1,14
-------------------------------------------------------------------------------
--
-- SD/MMC Bootloader
--
-- $Id: card-c.vhd,v 1.1 2005-02-08 21:09:18 arniml Exp $
--
-------------------------------------------------------------------------------
 
configuration card_behav_c0 of card is
 
for behav
end for;
 
end card_behav_c0;
/tb_elem-minimal-c.vhd
0,0 → 1,23
-------------------------------------------------------------------------------
--
-- SD/MMC Bootloader
--
-- $Id: tb_elem-minimal-c.vhd,v 1.1 2005-02-08 21:09:20 arniml Exp $
--
-------------------------------------------------------------------------------
 
configuration tb_elem_behav_minimal of tb_elem is
 
for behav
 
for dut_b : chip
use configuration work.chip_minimal_c0;
end for;
 
for card_b : card
use configuration work.card_behav_c0;
end for;
 
end for;
 
end tb_elem_behav_minimal;
/tb_elem-sd-c.vhd
0,0 → 1,23
-------------------------------------------------------------------------------
--
-- SD/MMC Bootloader
--
-- $Id: tb_elem-sd-c.vhd,v 1.1 2005-02-08 21:09:20 arniml Exp $
--
-------------------------------------------------------------------------------
 
configuration tb_elem_behav_sd of tb_elem is
 
for behav
 
for dut_b : chip
use configuration work.chip_sd_c0;
end for;
 
for card_b : card
use configuration work.card_behav_c0;
end for;
 
end for;
 
end tb_elem_behav_sd;

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.