Handle the reset state in the driver, not the parser, triggered by another button.
[bos2k9.git] / fhw_sd_t / sd_parser_t.vhd
1 -----------------------------------------------------------------------
2 -- Copyright (c) 2009 Malte S. Stretz <http://msquadrat.de> 
3 --
4 -- Testing the sd_parser.
5 -----------------------------------------------------------------------
6 -- This entity is part of the following library:
7 -- pragma library fhw_sd_t
8 library fhw_sd_t;
9 library fhw_sd;
10 use fhw_sd.all;
11 use fhw_sd.sd_globals_p.all;
12 use fhw_sd.sd_commands_p.all;
13
14 library fhw_tools;
15 use fhw_tools.types.all;
16
17 library ieee;
18 use ieee.std_logic_1164.all;
19 use ieee.numeric_std.all;
20
21 -----------------------------------------------------------------------
22
23 entity sd_parser_t is
24   generic(
25     clock_interval : time := 20 ns);
26 end sd_parser_t;
27
28 -----------------------------------------------------------------------
29
30 architecture test of sd_parser_t is
31   component sd_parser_e is
32     port(
33       clock : in std_logic;
34       reset : in std_logic;
35     
36       command  : in  std_logic_cmd_t;
37       argument : in  std_logic_arg_t;
38       trigger  : in  std_logic;
39       shifting : out std_logic;
40       error    : out std_logic;
41       idled    : out std_logic;
42       
43       pipe     : out std_logic;
44       
45       spi_start : out std_logic;
46       spi_busy  : in  std_logic;
47       spi_txd   : out std_logic_byte_t;
48       spi_rxd   : in  std_logic_byte_t);
49   end component;
50
51   signal test_s : integer;
52   
53   signal clock_s  : std_logic;
54   signal reset_s  : std_logic;
55   
56   signal command_i_s  : std_logic_cmd_t;
57   signal argument_i_s : std_logic_arg_t;
58   signal trigger_i_s  : std_logic;
59   signal shifting_o_s : std_logic;
60   signal error_o_s    : std_logic;
61   signal idled_o_s    : std_logic;
62   signal pipe_o_s     : std_logic;
63   signal start_o_s    : std_logic;
64   signal busy_i_s     : std_logic;
65   signal txd_o_s      : std_logic_byte_t;
66   signal rxd_i_s      : std_logic_byte_t;
67   
68   constant address_c  : std_logic_block_address_t := "10101010101010101010101";
69   
70   signal counter_s : natural;
71   signal delay_s   : natural;
72   signal data_s    : std_logic_byte_t;
73 begin
74   dut : sd_parser_e port map(clock_s, reset_s,
75     command_i_s,
76     argument_i_s,
77     trigger_i_s,
78     shifting_o_s,
79     error_o_s,
80     idled_o_s,
81     pipe_o_s,
82     start_o_s,
83     busy_i_s,
84     txd_o_s,
85     rxd_i_s);
86   
87   stimulus : process
88     procedure send(
89       cmd : std_logic_cmd_t;
90       arg : std_logic_arg_t;
91       cnt : natural;
92       dat : std_logic_byte_t) is
93     begin
94       delay_s <= cnt;
95       data_s  <= dat;
96       command_i_s  <= cmd;
97       argument_i_s <= arg;
98       trigger_i_s  <= '1';
99       wait until rising_edge(clock_s);
100       trigger_i_s  <= '0';
101       wait until falling_edge(shifting_o_s);
102       wait until rising_edge(clock_s);
103     end send;
104   begin
105     wait for clock_interval / 4;
106     
107     command_i_s  <= (others => '0');
108     argument_i_s <= (others => '0');
109     trigger_i_s  <= '0';
110     wait until falling_edge(reset_s);
111     
112     -- Test the internal command with an argument shorter than frame 
113     -- size which ignores the input and thus always runs into a 
114     -- (non-fatal) timeout.
115     send(cmd_do_skip_c,
116       arg_do_skip_c,
117       1, x"00");
118
119     -- Test standard command with argument.
120     send(cmd_read_single_block_c,
121       address_c & pad_read_single_block_c,
122       6 + 2, x"00");
123     
124     -- Test internal command with long argument and piping.
125     send(cmd_do_pipe_c,
126       arg_do_pipe_c,
127       1, x"00");
128     
129     wait;
130   end process;
131   
132   io_data : process
133   begin
134     rxd_i_s <= (others => 'U');
135     
136     wait until rising_edge(start_o_s);
137     
138     while shifting_o_s = '1' loop
139       if start_o_s = '1' then
140         rxd_i_s <= (others => 'U');
141       elsif counter_s = delay_s then
142         rxd_i_s <= data_s;
143       else
144         rxd_i_s <= (others => '1');
145       end if;
146       wait until rising_edge(clock_s);
147     end loop;
148   end process;
149   
150   io_flow : process
151   begin
152     busy_i_s  <= '0';
153     
154     wait until rising_edge(start_o_s);
155     busy_i_s  <= '1';
156     wait until rising_edge(clock_s);
157     wait until rising_edge(clock_s);
158     wait until rising_edge(clock_s);
159     wait until rising_edge(clock_s);
160     wait until rising_edge(clock_s);
161     wait until rising_edge(clock_s);
162     wait until rising_edge(clock_s);
163     wait until rising_edge(clock_s);
164   end process;
165   
166   io_count : process
167     variable busy_v : std_logic;
168   begin
169     counter_s <= 0;
170     busy_v    := '0';
171     
172     wait until rising_edge(shifting_o_s);
173     while shifting_o_s = '1' loop
174       if busy_i_s = '1' and not busy_i_s = busy_v then
175         counter_s <= counter_s + 1;
176       end if;
177       busy_v := busy_i_s;
178       wait until rising_edge(clock_s);
179     end loop;
180   end process;
181   
182   reset : process
183   begin
184     reset_s <= '1';
185     wait until rising_edge(clock_s);
186     wait until rising_edge(clock_s);
187     reset_s <= '0';
188     wait;
189   end process;
190   
191   clock : process
192   begin
193     clock_s <= '0';
194     wait for clock_interval / 2;
195     clock_s <= '1';
196     wait for clock_interval / 2;
197   end process;
198   
199 end test;