Some refactoring and yet another state machine.
[bos2k9.git] / fhw_sd / sd_host.vhd
1 -----------------------------------------------------------------------
2 -- Copyright (c) 2009 Malte S. Stretz <http://msquadrat.de> 
3 --
4 -- TODO: description
5 -- NOTE: No SDHC (max. 4 GiB)
6
7 -----------------------------------------------------------------------
8 -- This entity is part of the following library:
9 -- pragma library fhw_sd
10 library fhw_sd;
11 use fhw_sd.sd_globals_p.all;
12
13 library fhw_spi;
14 use fhw_spi.spi_master;
15
16 library fhw_tools;
17 use fhw_tools.types.all;
18
19 library ieee;
20 use ieee.std_logic_1164.all;
21 use ieee.numeric_std.all;
22
23 entity sd_host is
24   generic(
25     clock_interval : time;
26     clock_divider  : positive); -- TODO: calculate this based on clock_interval
27   port(
28     clk : in  std_logic;
29     rst : in  std_logic;
30
31     ready : out std_logic;
32     busy  : out std_logic;
33     error : out std_logic;
34     
35     address : in  std_logic_block_address_t;
36     start   : in  std_logic;
37     rxd     : out std_logic_byte_t;
38     shd     : out std_logic;
39     
40     miso  : in  std_logic;
41     mosi  : out std_logic;
42     sck   : out std_logic;
43     cs    : out std_logic);
44  end sd_host;
45  
46 -----------------------------------------------------------------------
47
48 architecture rtl of sd_host is
49   
50   component sd_manager_e is
51     port(
52       clock : in std_logic;
53       reset : in std_logic;
54     
55       address : in std_logic_block_address_t;
56       start   : in std_logic;
57       
58       ready : out std_logic;
59       busy  : out std_logic;
60       error : out std_logic;
61     
62       command  : out std_logic_cmd_t;
63       argument : out std_logic_arg_t;
64       trigger  : out std_logic;
65       response : in  std_logic_rsp_t;
66       shifting : in  std_logic);
67   end component;
68   
69   component sd_parser_e is
70     port(
71       clock : in std_logic;
72       reset : in std_logic;
73     
74       command  : in  std_logic_cmd_t;
75       argument : in  std_logic_arg_t;
76       trigger  : in  std_logic;
77       response : out std_logic_rsp_t;
78       shifting : out std_logic;
79       
80       pipe     : out std_logic;
81       
82       io_frame : out std_logic_frame_t;
83       io_start : out std_logic;
84       io_busy  : in  std_logic;
85       io_data  : in  std_logic_byte_t;
86       io_shift : in  std_logic;
87       
88       cnt_top  : out counter_top_t);
89   end component;
90   
91   component sd_io_e is
92     port(
93       clock : in std_logic;
94       reset : in std_logic;
95     
96       frame  : in  std_logic_frame_t;
97       start  : in  std_logic;
98       busy   : out std_logic;
99       data   : out std_logic_byte_t;
100       shift  : out std_logic;
101     
102       cnt_tick : out std_logic;
103       cnt_done : in  std_logic;
104     
105       spi_start : out std_logic;
106       spi_busy  : in  std_logic;
107       spi_txd   : out std_logic_byte_t;
108       spi_rxd   : in  std_logic_byte_t);
109   end component;
110
111   component sd_counter_e is
112     generic(
113       max : positive := counter_max_c);
114     port(
115       clock  : in  std_logic;
116       reset  : in  std_logic;
117       enable : in  std_logic;
118     
119       top  : in  counter_top_t;
120       done : out std_logic);
121   end component;
122   
123   component spi_master 
124     generic(
125       clk_div    : positive := clock_divider;
126       data_width : positive := std_logic_byte_t'length);
127     port(
128       clk : in  std_logic;
129       rst : in  std_logic;
130     
131       start : in  std_logic;
132       busy  : out std_logic;
133     
134       txd   : in  std_logic_byte_t;
135       rxd   : out std_logic_byte_t;
136     
137       miso  : in  std_logic;
138       mosi  : out std_logic;
139       sck   : out std_logic);
140   end component;
141   
142   signal sd_command_s  : std_logic_cmd_t;
143   signal sd_argument_s : std_logic_arg_t;
144   signal sd_trigger_s  : std_logic;
145   signal sd_response_s : std_logic_rsp_t;
146   signal sd_shifting_s : std_logic;
147   
148   signal io_frame_s : std_logic_frame_t;
149   signal io_start_s : std_logic;
150   signal io_busy_s  : std_logic;
151   signal io_data_s  : std_logic_byte_t;
152   signal io_shift_s : std_logic;
153   
154   signal cnt_top_s  : counter_top_t;
155   signal cnt_tick_s : std_logic;
156   signal cnt_done_s : std_logic;
157   
158   signal spi_start_s : std_logic;
159   signal spi_busy_s  : std_logic;
160   signal spi_txd_s   : std_logic_byte_t;
161   signal spi_rxd_s   : std_logic_byte_t;
162   signal spi_cs_n    : std_logic;
163   
164 begin
165   rxd <= spi_rxd_s;
166   
167   driver : sd_manager_e port map(
168     clock => clk,
169     reset => rst,
170     
171     address => address,
172     start   => start,
173     
174     ready => ready,
175     busy  => busy,
176     error => error,
177     
178     command  => sd_command_s,
179     argument => sd_argument_s,
180     trigger  => sd_trigger_s,
181     response => sd_response_s,
182     shifting => sd_shifting_s);
183   
184   parser : sd_parser_e port map(
185     clock => clk,
186     reset => rst,
187     
188     command  => sd_command_s,
189     argument => sd_argument_s,
190     trigger  => sd_trigger_s,
191     response => sd_response_s,
192     shifting => sd_shifting_s,
193     
194     pipe => shd,
195     
196     io_frame  => io_frame_s,
197     io_start  => io_start_s,
198     io_busy   => io_busy_s,
199     io_data   => io_data_s,
200     io_shift  => io_shift_s,
201     
202     cnt_top   => cnt_top_s);
203     
204   io : sd_io_e port map(
205     clock => clk,
206     reset => rst,
207   
208     frame  => io_frame_s,
209     start  => io_start_s,
210     busy   => io_busy_s,
211     data   => io_data_s,
212     shift  => io_shift_s,
213     
214     cnt_tick => cnt_tick_s,
215     cnt_done => cnt_done_s,
216   
217     spi_start => spi_start_s,
218     spi_busy  => spi_busy_s,
219     spi_txd   => spi_txd_s,
220     spi_rxd   => spi_rxd_s);
221   
222   counter : sd_counter_e port map(
223     clock => clk,
224     reset => rst,
225     enable => cnt_tick_s,
226     
227     top  => cnt_top_s,
228     done => cnt_done_s);
229   
230   spi : spi_master port map(
231     clk => clk,
232     rst => rst,
233     
234     start => spi_start_s,
235     busy  => spi_busy_s,
236     txd   => spi_txd_s,
237     rxd   => spi_rxd_s,
238     
239     miso  => miso,
240     mosi  => mosi,
241     sck   => sck);
242   cs <= spi_cs_n;
243 end rtl;