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

Subversion Repositories fat_32_file_parser

[/] [fat_32_file_parser/] [trunk/] [SdCardReadWrite.vhd] - Blame information for rev 2

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 craighaywo
----------------------------------------------------------------------------------
2
-- Company: 
3
-- Engineer: 
4
-- 
5
-- Create Date:    15:20:06 11/16/2014 
6
-- Design Name: 
7
-- Module Name:    SdCardReadWrite - Behavioral 
8
-- Project Name: 
9
-- Target Devices: 
10
-- Tool versions: 
11
-- Description: 
12
--
13
-- Dependencies: 
14
--
15
-- Revision: 
16
-- Revision 0.01 - File Created
17
-- Additional Comments: 
18
--
19
----------------------------------------------------------------------------------
20
library IEEE;
21
use IEEE.STD_LOGIC_1164.ALL;
22
use IEEE.NUMERIC_STD.ALL;
23
 
24
library UNISIM;
25
use UNISIM.VComponents.all;
26
 
27
entity SdCardReadWrite is
28
    Port ( CLK_IN : in  STD_LOGIC;
29
           RESET_IN : in  STD_LOGIC;
30
 
31
                          FAT_BEGIN_ADDR_IN                             : in  STD_LOGIC_VECTOR (31 downto 0);
32
                          SECTORS_PER_FAT_IN                            : in  STD_LOGIC_VECTOR (31 downto 0);
33
           CLUSTER_BEGIN_ADDR_IN                : in  STD_LOGIC_VECTOR (31 downto 0);
34
           SECTORS_PER_CLUSTER_IN               : in  STD_LOGIC_VECTOR (7 downto 0);
35
           ROOT_DIR_FIRST_CLUSTER_IN    : in  STD_LOGIC_VECTOR (31 downto 0);
36
 
37
                          SD_INIT_CMPLT_IN      : in STD_LOGIC;
38
 
39
                          SD_BLOCK_RD_OUT       : out STD_LOGIC;
40
           SD_BLOCK_ADDR_OUT    : out STD_LOGIC_VECTOR (31 downto 0);
41
           SD_DATA_IN                   : in  STD_LOGIC_VECTOR (7 downto 0);
42
           SD_BUSY_IN                   : in  STD_LOGIC;
43
           SD_BYTE_RD_OUT               : out STD_LOGIC;
44
           SD_BYTE_RD_ACK_IN    : in  STD_LOGIC;
45
 
46
                          GET_NEXT_DIRENT_IN                    : in STD_LOGIC;
47
                          NEXT_DIRENT_DONE_OUT          : out STD_LOGIC;
48
                          DIRENT_IS_FOLDER_OUT          : out STD_LOGIC;
49
                          RD_DIRENT_NAME_CHAR_IN        : in STD_LOGIC;
50
                          DIRENT_CHAR_OUT                               : out STD_LOGIC_VECTOR(7 downto 0);
51
                          END_OF_DIRENT_NAME_OUT        : out STD_LOGIC;
52
                          NO_MORE_DIRENTS_OUT           : out STD_LOGIC;
53
 
54
                          DEBUG_IN              : in STD_LOGIC_VECTOR(7 downto 0);
55
                          DEBUG_OUT     : out STD_LOGIC_VECTOR(15 downto 0);
56
                          DEBUG_OUT2    : out STD_LOGIC_VECTOR(7 downto 0));
57
end SdCardReadWrite;
58
 
59
architecture Behavioral of SdCardReadWrite is
60
 
61
        COMPONENT TDP_RAM
62
                Generic (G_DATA_A_SIZE  :natural :=32;
63
                                        G_ADDR_A_SIZE   :natural :=9;
64
                                        G_RELATION              :natural :=3;
65
                                        G_INIT_FILE             :string :="");--log2(SIZE_A/SIZE_B)
66
                Port ( CLK_A_IN         : in  STD_LOGIC;
67
                                 WE_A_IN        : in  STD_LOGIC;
68
                                 ADDR_A_IN      : in  STD_LOGIC_VECTOR (G_ADDR_A_SIZE-1 downto 0);
69
                                 DATA_A_IN      : in  STD_LOGIC_VECTOR (G_DATA_A_SIZE-1 downto 0);
70
                                 DATA_A_OUT     : out STD_LOGIC_VECTOR (G_DATA_A_SIZE-1 downto 0);
71
                                 CLK_B_IN       : in  STD_LOGIC;
72
                                 WE_B_IN        : in  STD_LOGIC;
73
                                 ADDR_B_IN      : in  STD_LOGIC_VECTOR (G_ADDR_A_SIZE+G_RELATION-1 downto 0);
74
                                 DATA_B_IN      : in  STD_LOGIC_VECTOR (G_DATA_A_SIZE/(2**G_RELATION)-1 downto 0);
75
                                 DATA_B_OUT : out STD_LOGIC_VECTOR (G_DATA_A_SIZE/(2**G_RELATION)-1 downto 0));
76
        END COMPONENT;
77
 
78
        COMPONENT lifo is
79
                Generic (       G_LOG2_DEPTH    : natural := 6;
80
                                                G_DATA_SIZE             : natural := 8  ); -- LOG2(lifo depth)
81
                 Port ( CLK_IN                  : in  STD_LOGIC;
82
                                  RESET_IN                      : in  STD_LOGIC;
83
                                  CACHE_ADDR_IN : in  STD_LOGIC;
84
                                  GOTO_CACHE_IN         : in  STD_LOGIC;
85
                                  WR_DATA_IN            : in  STD_LOGIC_VECTOR ((G_DATA_SIZE - 1) downto 0);
86
                                  WR_EN_IN                      : in  STD_LOGIC;
87
                                  RD_DATA_OUT           : out STD_LOGIC_VECTOR ((G_DATA_SIZE - 1) downto 0);
88
                                  RD_EN_IN                      : in  STD_LOGIC;
89
                                  EMPTY_OUT             : out STD_LOGIC;
90
                                  FULL_OUT                      : out STD_LOGIC);
91
        END COMPONENT;
92
 
93
subtype slv is std_logic_vector;
94
 
95
constant C_unused_entry                         : std_logic_vector(7 downto 0) := X"E5";
96
constant C_end_of_directory             : std_logic_vector(7 downto 0) := X"00";
97
constant C_file_name_type                       : std_logic_vector(7 downto 0) := X"0F";
98
constant C_folder_type                          : std_logic_vector(7 downto 0) := X"10";
99
constant C_file_type                            : std_logic_vector(7 downto 0) := X"20";
100
constant C_attrib_offset                        : unsigned(4 downto 0) := "01011";
101
constant C_lsb_word_lsb_offset  : unsigned(4 downto 0) := "11010";
102
constant C_lsb_word_msb_offset  : unsigned(4 downto 0) := "11011";
103
constant C_msb_word_lsb_offset  : unsigned(4 downto 0) := "10100";
104
constant C_msb_word_msb_offset  : unsigned(4 downto 0) := "10101";
105
 
106
signal sd_init_cmplt, sd_block_rd, perform_block_rd, block_rd_cmplt : std_logic := '0';
107
signal sd_busy, rd_byte, rd_byte_ack, get_next_dirent : std_logic := '0';
108
signal sd_data, block_rd_data   : std_logic_vector(7 downto 0) := (others => '0');
109
 
110
signal fat_begin_addr, sectors_per_fat : unsigned(31 downto 0);
111
signal sd_block_addr : unsigned(31 downto 0);
112
signal cluster_begin_addr : unsigned(31 downto 0);
113
signal find_dirent_addr, find_dirent_addr_rd, find_dirent_addr_cache : unsigned(8 downto 0) := (others => '0');
114
signal find_dirent_addr_rd_slv : std_logic_vector(8 downto 0);
115
 
116
signal dirent_found, dirent_is_folder : std_logic := '0';
117
signal dirent_lifo_we, dirent_lifo_rst, dirent_lifo_cache_addr          : std_logic := '0';
118
signal dirent_lifo_goto_cache, dirent_lifo_full, dirent_lifo_empty      : std_logic := '0';
119
 
120
signal folder_addr, folder_addr_tmp, folder_addr_final : unsigned(31 downto 0) := X"00000000";
121
signal sectors_per_cluster, spc_counter : std_logic_vector(7 downto 0) := X"00";
122
 
123
signal bp_lifo_rst, bp_lifo_we, bp_lifo_rd, bp_lifo_empty : std_logic := '0';
124
signal bp_lifo_block_data : std_logic_vector(31 downto 0) := (others => '0');
125
 
126
signal find_addr_lifo_rst, find_addr_lifo_we, find_addr_lifo_rd, find_addr_lifo_empty : std_logic := '0';
127
 
128
signal end_of_dirents : std_logic := '0';
129
signal sectors_per_cluster_zero_indexed, find_dirent_block_num, find_dirent_block_num_rd : unsigned(7 downto 0) := X"00";
130
signal current_cluster, current_cluster_buf, current_cluster_rd : unsigned(31 downto 0) := X"00000000";
131
signal current_cluster_fat_block_addr, current_cluster_tmp, next_cluster_lba : unsigned(31 downto 0) := X"00000000";
132
signal current_cluster_lifo_rst, current_cluster_lifo_we, current_cluster_lifo_rd : std_logic := '0';
133
signal current_cluster_lifo_empty : std_logic := '0';
134
signal current_cluster_rd_slv : std_logic_vector(31 downto 0);
135
 
136
signal find_dirent_block_lifo_rst, find_dirent_block_lifo_we, find_dirent_block_lifo_rd : std_logic := '0';
137
signal find_dirent_block_lifo_empty : std_logic := '0';
138
signal find_dirent_block_num_rd_slv : std_logic_vector(7 downto 0);
139
 
140
signal file_counter :unsigned(15 downto 0) := (others => '0');
141
signal debug : std_logic := '0';
142
 
143
type MAIN_ROUTINE is (  REPORT_ERROR,
144
                                                                WAIT_FOR_INIT_CMPLT,
145
                                                                IDLE_W_BLOCK_RD,
146
                                                                IDLE_NO_BLOCK_RD,
147
 
148
                                                                FIND_NEXT_DIRENT0,
149
                                                                FIND_NEXT_DIRENT1,
150
                                                                FIND_NEXT_DIRENT2,
151
                                                                FIND_NEXT_DIRENT3,
152
                                                                FIND_NEXT_DIRENT4,
153
                                                                FIND_NEXT_DIRENT5,
154
                                                                FIND_NEXT_DIRENT6,
155
 
156
                                                                PARSE_NAME_DIRENT0,
157
                                                                PARSE_NAME_DIRENT1,
158
                                                                PARSE_NAME_DIRENT2,
159
                                                                PARSE_NAME_DIRENT3,
160
                                                                PARSE_NAME_DIRENT4,
161
                                                                PARSE_NAME_DIRENT5,
162
                                                                PARSE_NAME_DIRENT6,
163
                                                                PARSE_NAME_DIRENT7,
164
                                                                PARSE_NAME_DIRENT8,
165
                                                                PARSE_NAME_DIRENT9,
166
                                                                PARSE_NAME_DIRENT10,
167
                                                                PARSE_NAME_DIRENT11,
168
                                                                PARSE_NAME_DIRENT12,
169
                                                                PARSE_NAME_DIRENT13,
170
                                                                PARSE_NAME_DIRENT14,
171
                                                                PARSE_NAME_DIRENT15,
172
                                                                PARSE_NAME_DIRENT16,
173
                                                                PARSE_NAME_DIRENT17,
174
 
175
                                                                HANDLE_FILE_DIRENT0,
176
 
177
                                                                HANDLE_END_OF_DIR0,
178
                                                                HANDLE_END_OF_DIR1,
179
                                                                HANDLE_END_OF_DIR2,
180
                                                                HANDLE_END_OF_DIR3,
181
 
182
                                                                HANDLE_FOLDER_DIRENT0,
183
                                                                HANDLE_FOLDER_DIRENT1,
184
                                                                HANDLE_FOLDER_DIRENT2,
185
                                                                HANDLE_FOLDER_DIRENT3,
186
                                                                HANDLE_FOLDER_DIRENT4,
187
                                                                HANDLE_FOLDER_DIRENT5,
188
                                                                HANDLE_FOLDER_DIRENT6,
189
                                                                HANDLE_FOLDER_DIRENT7,
190
                                                                HANDLE_FOLDER_DIRENT8,
191
                                                                HANDLE_FOLDER_DIRENT9,
192
 
193
                                                                HANDLE_INTERNAL_ADDR_INC0,
194
                                                                HANDLE_INTERNAL_ADDR_INC1,
195
                                                                HANDLE_INTERNAL_ADDR_INC2,
196
                                                                HANDLE_INTERNAL_ADDR_INC3,
197
                                                                HANDLE_INTERNAL_ADDR_INC4,
198
                                                                HANDLE_INTERNAL_ADDR_INC5,
199
                                                                HANDLE_INTERNAL_ADDR_INC6,
200
                                                                HANDLE_INTERNAL_ADDR_INC7,
201
 
202
                                                                FIND_NEXT_CLUSTER0,
203
                                                                FIND_NEXT_CLUSTER1,
204
                                                                FIND_NEXT_CLUSTER2,
205
                                                                FIND_NEXT_CLUSTER3,
206
                                                                FIND_NEXT_CLUSTER4,
207
                                                                FIND_NEXT_CLUSTER5,
208
                                                                FIND_NEXT_CLUSTER6,
209
                                                                FIND_NEXT_CLUSTER7,
210
                                                                FIND_NEXT_CLUSTER8,
211
                                                                FIND_NEXT_CLUSTER9,
212
 
213
                                                                HANDLE_END_OF_DIRENTS0,
214
                                                                HANDLE_END_OF_DIRENTS1);
215
 
216
signal rw_state, rw_next_state, rw_state_cached : MAIN_ROUTINE := WAIT_FOR_INIT_CMPLT;
217
 
218
signal block_rd_we : std_logic := '0';
219
signal block_wr_addr, block_rd_addr : unsigned(8 downto 0) := (others => '0');
220
 
221
type BLOCK_RD_ROUTINE is (      IDLE,
222
                                                                        WAIT_UNTIL_NOT_BUSY,
223
                                                                        WAIT_UNTIL_BLOCK_READ_ACKD,
224
                                                                        READ_BYTE0,
225
                                                                        READ_BYTE1,
226
                                                                        READ_BYTE2,
227
                                                                        READ_BYTE3,
228
                                                                        READ_BYTE4
229
                                                                        );
230
signal br_state, br_next_state : BLOCK_RD_ROUTINE;
231
 
232
signal state_debug_sig : unsigned(5 downto 0);
233
signal state_debug_sig2 : unsigned(1 downto 0);
234
 
235
begin
236
 
237
        sd_init_cmplt <= SD_INIT_CMPLT_IN;
238
        SD_BLOCK_RD_OUT <= sd_block_rd;
239
        SD_BLOCK_ADDR_OUT <= slv(sd_block_addr);
240
        sd_data <= SD_DATA_IN;
241
        sd_busy <= SD_BUSY_IN;
242
        SD_BYTE_RD_OUT <= rd_byte;
243
        rd_byte_ack <= SD_BYTE_RD_ACK_IN;
244
 
245
        fat_begin_addr <= unsigned(FAT_BEGIN_ADDR_IN);
246
        sectors_per_fat <= unsigned(SECTORS_PER_FAT_IN);
247
        cluster_begin_addr <= unsigned(CLUSTER_BEGIN_ADDR_IN);
248
        get_next_dirent <= GET_NEXT_DIRENT_IN;
249
        sectors_per_cluster <= SECTORS_PER_CLUSTER_IN;
250
        sectors_per_cluster_zero_indexed <= unsigned(SECTORS_PER_CLUSTER_IN) - 1;
251
 
252
        NEXT_DIRENT_DONE_OUT <= dirent_found;
253
        DIRENT_IS_FOLDER_OUT <= dirent_is_folder;
254
        END_OF_DIRENT_NAME_OUT <= dirent_lifo_empty;
255
        NO_MORE_DIRENTS_OUT <= end_of_dirents;
256
 
257
--      debug_state: process(CLK_IN)
258
--      begin
259
--              if rising_edge(CLK_IN) then
260
--                      case (br_state) is
261
--                              when IDLE =>
262
--                                      state_debug_sig <= to_unsigned(0, 6);
263
--                              when WAIT_UNTIL_NOT_BUSY =>
264
--                                      state_debug_sig <= to_unsigned(1, 6);
265
--                              when WAIT_UNTIL_BLOCK_READ_ACKD =>
266
--                                      state_debug_sig <= to_unsigned(2, 6);
267
--                              when READ_BYTE0 =>
268
--                                      state_debug_sig <= to_unsigned(3, 6);
269
--                              when READ_BYTE1 =>
270
--                                      state_debug_sig <= to_unsigned(4, 6);
271
--                              when READ_BYTE2 =>
272
--                                      state_debug_sig <= to_unsigned(5, 6);
273
--                              when READ_BYTE3 =>
274
--                                      state_debug_sig <= to_unsigned(6, 6);
275
--                              when READ_BYTE4 =>
276
--                                      state_debug_sig <= to_unsigned(7, 6);
277
--                      end case;
278
--              end if;
279
--      end process;
280
 
281
        debug_state: process(CLK_IN)
282
        begin
283
                if rising_edge(CLK_IN) then
284
                        case( rw_state ) is
285
 
286
                                when REPORT_ERROR =>
287
                                        state_debug_sig <= to_unsigned(0, 6);
288
                                when WAIT_FOR_INIT_CMPLT =>
289
                                        state_debug_sig <= to_unsigned(1, 6);
290
                                when IDLE_W_BLOCK_RD =>
291
                                        state_debug_sig <= to_unsigned(2, 6);
292
                                when IDLE_NO_BLOCK_RD =>
293
                                        state_debug_sig <= to_unsigned(3, 6);
294
                                when FIND_NEXT_DIRENT0 =>
295
                                        state_debug_sig <= to_unsigned(4, 6);
296
                                when FIND_NEXT_DIRENT1 =>
297
                                        state_debug_sig <= to_unsigned(5, 6);
298
                                when FIND_NEXT_DIRENT2 =>
299
                                        state_debug_sig <= to_unsigned(6, 6);
300
                                when FIND_NEXT_DIRENT3 =>
301
                                        state_debug_sig <= to_unsigned(7, 6);
302
                                when FIND_NEXT_DIRENT4 =>
303
                                        state_debug_sig <= to_unsigned(8, 6);
304
                                when FIND_NEXT_DIRENT5 =>
305
                                        state_debug_sig <= to_unsigned(9, 6);
306
                                when FIND_NEXT_DIRENT6 =>
307
                                        state_debug_sig <= to_unsigned(10, 6);
308
                                when PARSE_NAME_DIRENT0 =>
309
                                        state_debug_sig <= to_unsigned(11, 6);
310
                                when PARSE_NAME_DIRENT1 =>
311
                                        state_debug_sig <= to_unsigned(12, 6);
312
                                when PARSE_NAME_DIRENT2 =>
313
                                        state_debug_sig <= to_unsigned(13, 6);
314
                                when PARSE_NAME_DIRENT3 =>
315
                                        state_debug_sig <= to_unsigned(14, 6);
316
                                when PARSE_NAME_DIRENT4 =>
317
                                        state_debug_sig <= to_unsigned(15, 6);
318
                                when PARSE_NAME_DIRENT5 =>
319
                                        state_debug_sig <= to_unsigned(16, 6);
320
                                when PARSE_NAME_DIRENT6 =>
321
                                        state_debug_sig <= to_unsigned(17, 6);
322
                                when PARSE_NAME_DIRENT7 =>
323
                                        state_debug_sig <= to_unsigned(18, 6);
324
                                when PARSE_NAME_DIRENT8 =>
325
                                        state_debug_sig <= to_unsigned(19, 6);
326
                                when PARSE_NAME_DIRENT9 =>
327
                                        state_debug_sig <= to_unsigned(20, 6);
328
                                when PARSE_NAME_DIRENT10 =>
329
                                        state_debug_sig <= to_unsigned(21, 6);
330
                                when PARSE_NAME_DIRENT11 =>
331
                                        state_debug_sig <= to_unsigned(22, 6);
332
                                when PARSE_NAME_DIRENT12 =>
333
                                        state_debug_sig <= to_unsigned(23, 6);
334
                                when PARSE_NAME_DIRENT13 =>
335
                                        state_debug_sig <= to_unsigned(24, 6);
336
                                when PARSE_NAME_DIRENT14 =>
337
                                        state_debug_sig <= to_unsigned(25, 6);
338
                                when PARSE_NAME_DIRENT15 =>
339
                                        state_debug_sig <= to_unsigned(26, 6);
340
                                when PARSE_NAME_DIRENT16 =>
341
                                        state_debug_sig <= to_unsigned(27, 6);
342
                                when PARSE_NAME_DIRENT17 =>
343
                                        state_debug_sig <= to_unsigned(28, 6);
344
                                when HANDLE_FILE_DIRENT0 =>
345
                                        state_debug_sig <= to_unsigned(29, 6);
346
                                when HANDLE_END_OF_DIR0 =>
347
                                        state_debug_sig <= to_unsigned(30, 6);
348
                                when HANDLE_END_OF_DIR1 =>
349
                                        state_debug_sig <= to_unsigned(31, 6);
350
                                when HANDLE_END_OF_DIR2 =>
351
                                        state_debug_sig <= to_unsigned(32, 6);
352
                                when HANDLE_END_OF_DIR3 =>
353
                                        state_debug_sig <= to_unsigned(33, 6);
354
                                when HANDLE_FOLDER_DIRENT0 =>
355
                                        state_debug_sig <= to_unsigned(34, 6);
356
                                when HANDLE_FOLDER_DIRENT1 =>
357
                                        state_debug_sig <= to_unsigned(35, 6);
358
                                when HANDLE_FOLDER_DIRENT2 =>
359
                                        state_debug_sig <= to_unsigned(36, 6);
360
                                when HANDLE_FOLDER_DIRENT3 =>
361
                                        state_debug_sig <= to_unsigned(37, 6);
362
                                when HANDLE_FOLDER_DIRENT4 =>
363
                                        state_debug_sig <= to_unsigned(38, 6);
364
                                when HANDLE_FOLDER_DIRENT5 =>
365
                                        state_debug_sig <= to_unsigned(39, 6);
366
                                when HANDLE_FOLDER_DIRENT6 =>
367
                                        state_debug_sig <= to_unsigned(40, 6);
368
                                when HANDLE_FOLDER_DIRENT7 =>
369
                                        state_debug_sig <= to_unsigned(41, 6);
370
                                when HANDLE_FOLDER_DIRENT8 =>
371
                                        state_debug_sig <= to_unsigned(42, 6);
372
                                when HANDLE_FOLDER_DIRENT9 =>
373
                                        state_debug_sig <= to_unsigned(43, 6);
374
                                when HANDLE_INTERNAL_ADDR_INC0 =>
375
                                        state_debug_sig <= to_unsigned(44, 6);
376
                                when HANDLE_INTERNAL_ADDR_INC1 =>
377
                                        state_debug_sig <= to_unsigned(45, 6);
378
                                when HANDLE_INTERNAL_ADDR_INC2 =>
379
                                        state_debug_sig <= to_unsigned(46, 6);
380
                                when HANDLE_INTERNAL_ADDR_INC3 =>
381
                                        state_debug_sig <= to_unsigned(47, 6);
382
                                when HANDLE_INTERNAL_ADDR_INC4 =>
383
                                        state_debug_sig <= to_unsigned(48, 6);
384
                                when HANDLE_INTERNAL_ADDR_INC5 =>
385
                                        state_debug_sig <= to_unsigned(49, 6);
386
                                when HANDLE_INTERNAL_ADDR_INC6 =>
387
                                        state_debug_sig <= to_unsigned(50, 6);
388
                                when HANDLE_INTERNAL_ADDR_INC7 =>
389
                                        state_debug_sig <= to_unsigned(51, 6);
390
                                when FIND_NEXT_CLUSTER0 =>
391
                                        state_debug_sig <= to_unsigned(52, 6);
392
                                when FIND_NEXT_CLUSTER1 =>
393
                                        state_debug_sig <= to_unsigned(53, 6);
394
                                when FIND_NEXT_CLUSTER2 =>
395
                                        state_debug_sig <= to_unsigned(54, 6);
396
                                when FIND_NEXT_CLUSTER3 =>
397
                                        state_debug_sig <= to_unsigned(55, 6);
398
                                when FIND_NEXT_CLUSTER4 =>
399
                                        state_debug_sig <= to_unsigned(56, 6);
400
                                when FIND_NEXT_CLUSTER5 =>
401
                                        state_debug_sig <= to_unsigned(57, 6);
402
                                when FIND_NEXT_CLUSTER6 =>
403
                                        state_debug_sig <= to_unsigned(58, 6);
404
                                when FIND_NEXT_CLUSTER7 =>
405
                                        state_debug_sig <= to_unsigned(59, 6);
406
                                when FIND_NEXT_CLUSTER8 =>
407
                                        state_debug_sig <= to_unsigned(60, 6);
408
                                when FIND_NEXT_CLUSTER9 =>
409
                                        state_debug_sig <= to_unsigned(61, 6);
410
                                when HANDLE_END_OF_DIRENTS0 =>
411
                                        state_debug_sig <= to_unsigned(62, 6);
412
                                when HANDLE_END_OF_DIRENTS1 =>
413
                                        state_debug_sig <= to_unsigned(63, 6);
414
                        end case;
415
                end if;
416
        end process;
417
 
418
        debug_state2: process(CLK_IN)
419
        begin
420
                if rising_edge(CLK_IN) then
421
                        case( rw_state_cached ) is
422
 
423
                                when FIND_NEXT_DIRENT2 =>
424
                                        state_debug_sig2 <= to_unsigned(0, 2);
425
                                when PARSE_NAME_DIRENT15 =>
426
                                        state_debug_sig2 <= to_unsigned(1, 2);
427
                                when IDLE_NO_BLOCK_RD =>
428
                                        state_debug_sig2 <= to_unsigned(2, 2);
429
                                when others =>
430
                                        state_debug_sig2 <= to_unsigned(3, 2);
431
                        end case;
432
                end if;
433
        end process;
434
 
435
-------- FSM OUTPUT --------
436
 
437
        BLOCK_RD: process(CLK_IN)
438
   begin
439
                if rising_edge(CLK_IN) then
440
                        if rw_state = WAIT_FOR_INIT_CMPLT then
441
                                sd_block_addr <= cluster_begin_addr;
442
                        elsif rw_state = HANDLE_FOLDER_DIRENT9 then
443
                                sd_block_addr <= folder_addr_final;
444
                        elsif rw_state = HANDLE_END_OF_DIR0 then
445
                                sd_block_addr <= unsigned(bp_lifo_block_data);
446
                        elsif rw_state = HANDLE_END_OF_DIRENTS0 then
447
                                sd_block_addr <= cluster_begin_addr;
448
                        elsif rw_state = HANDLE_INTERNAL_ADDR_INC1 then
449
                                sd_block_addr <= sd_block_addr + 1;
450
                        elsif rw_state = FIND_NEXT_CLUSTER1 then
451
                                sd_block_addr <= current_cluster_fat_block_addr;
452
                        elsif rw_state = HANDLE_INTERNAL_ADDR_INC6 then
453
                                sd_block_addr <= next_cluster_lba;
454
                        end if;
455
                        if rw_state = FIND_NEXT_DIRENT0 then
456
                                perform_block_rd <= '1';
457
                        elsif rw_state = HANDLE_INTERNAL_ADDR_INC1 then
458
                                perform_block_rd <= '1';
459
                        elsif rw_state = FIND_NEXT_CLUSTER1 then
460
                                perform_block_rd <= '1';
461
                        elsif rw_state = HANDLE_INTERNAL_ADDR_INC6 then
462
                                perform_block_rd <= '1';
463
                        else
464
                                perform_block_rd <= '0';
465
                        end if;
466
                        if rw_state = FIND_NEXT_DIRENT2 then
467
                                block_rd_addr <= find_dirent_addr;
468
                        elsif rw_state = FIND_NEXT_DIRENT3 then
469
                                block_rd_addr <= find_dirent_addr(8 downto 5) & C_attrib_offset;
470
                        elsif rw_state = PARSE_NAME_DIRENT1 then
471
                                block_rd_addr <= find_dirent_addr(8 downto 5) & to_unsigned(30, 5);
472
                        elsif rw_state = PARSE_NAME_DIRENT2 then
473
                                block_rd_addr <= find_dirent_addr(8 downto 5) & to_unsigned(28,5);
474
                        elsif rw_state = PARSE_NAME_DIRENT3 then
475
                                block_rd_addr <= find_dirent_addr(8 downto 5) & to_unsigned(24,5);
476
                        elsif rw_state = PARSE_NAME_DIRENT4 then
477
                                block_rd_addr <= find_dirent_addr(8 downto 5) & to_unsigned(22,5);
478
                        elsif rw_state = PARSE_NAME_DIRENT5 then
479
                                block_rd_addr <= find_dirent_addr(8 downto 5) & to_unsigned(20,5);
480
                        elsif rw_state = PARSE_NAME_DIRENT6 then
481
                                block_rd_addr <= find_dirent_addr(8 downto 5) & to_unsigned(18,5);
482
                        elsif rw_state = PARSE_NAME_DIRENT7 then
483
                                block_rd_addr <= find_dirent_addr(8 downto 5) & to_unsigned(16,5);
484
                        elsif rw_state = PARSE_NAME_DIRENT8 then
485
                                block_rd_addr <= find_dirent_addr(8 downto 5) & to_unsigned(14,5);
486
                        elsif rw_state = PARSE_NAME_DIRENT9 then
487
                                block_rd_addr <= find_dirent_addr(8 downto 5) & to_unsigned(9, 5);
488
                        elsif rw_state = PARSE_NAME_DIRENT10 then
489
                                block_rd_addr <= find_dirent_addr(8 downto 5) & to_unsigned(7, 5);
490
                        elsif rw_state = PARSE_NAME_DIRENT11 then
491
                                block_rd_addr <= find_dirent_addr(8 downto 5) & to_unsigned(5, 5);
492
                        elsif rw_state = PARSE_NAME_DIRENT12 then
493
                                block_rd_addr <= find_dirent_addr(8 downto 5) & to_unsigned(3, 5);
494
                        elsif rw_state = PARSE_NAME_DIRENT13 then
495
                                block_rd_addr <= find_dirent_addr(8 downto 5) & to_unsigned(1, 5);
496
                        elsif rw_state = PARSE_NAME_DIRENT15 then
497
                                block_rd_addr <= find_dirent_addr(8 downto 5) & C_attrib_offset;
498
                        elsif rw_state = HANDLE_FOLDER_DIRENT0 then
499
                                block_rd_addr <= find_dirent_addr(8 downto 5) & C_lsb_word_lsb_offset;
500
                        elsif rw_state = HANDLE_FOLDER_DIRENT1 then
501
                                block_rd_addr <= find_dirent_addr(8 downto 5) & C_lsb_word_msb_offset;
502
                        elsif rw_state = HANDLE_FOLDER_DIRENT2 then
503
                                block_rd_addr <= find_dirent_addr(8 downto 5) & C_msb_word_lsb_offset;
504
                        elsif rw_state = HANDLE_FOLDER_DIRENT3 then
505
                                block_rd_addr <= find_dirent_addr(8 downto 5) & C_msb_word_msb_offset;
506
                        elsif rw_state = FIND_NEXT_CLUSTER3 then
507
                                block_rd_addr <= current_cluster_buf(6 downto 0) & "00";
508
                        elsif rw_state = FIND_NEXT_CLUSTER4 then
509
                                block_rd_addr <= current_cluster_buf(6 downto 0) & "01";
510
                        elsif rw_state = FIND_NEXT_CLUSTER5 then
511
                                block_rd_addr <= current_cluster_buf(6 downto 0) & "10";
512
                        elsif rw_state = FIND_NEXT_CLUSTER6 then
513
                                block_rd_addr <= current_cluster_buf(6 downto 0) & "11";
514
                        end if;
515
                        if rw_state = FIND_NEXT_CLUSTER2 then
516
                                current_cluster_buf <= current_cluster;
517
                        end if;
518
                        if rw_state = FIND_NEXT_DIRENT6 then
519
                                rw_state_cached <= FIND_NEXT_DIRENT2;
520
                        elsif rw_state = PARSE_NAME_DIRENT14 then
521
                                rw_state_cached <= PARSE_NAME_DIRENT15;
522
                        elsif rw_state = HANDLE_FILE_DIRENT0 then
523
                                rw_state_cached <= IDLE_NO_BLOCK_RD;
524
                        end if;
525
                        if rw_state = HANDLE_FILE_DIRENT0 then
526
                                file_counter <= file_counter + 1;
527
                        elsif rw_state = HANDLE_END_OF_DIRENTS1 and DEBUG_IN(0) = '1' then
528
                                file_counter <= (others => '0');
529
                        end if;
530
                        if rw_state = HANDLE_FOLDER_DIRENT9 then
531
                                find_dirent_addr <= (others => '0');
532
                        elsif rw_state = HANDLE_END_OF_DIR0 then
533
                                find_dirent_addr <= find_dirent_addr_rd;
534
                        elsif rw_state = HANDLE_END_OF_DIRENTS0 then
535
                                find_dirent_addr <= (others => '0');
536
                        elsif rw_state = HANDLE_INTERNAL_ADDR_INC0 then
537
                                find_dirent_addr <= find_dirent_addr + "000100000";
538
                        end if;
539
                        if rw_state = HANDLE_FOLDER_DIRENT0 then
540
                                find_dirent_addr_cache <= find_dirent_addr + "000100000";
541
                        end if;
542
                        if rw_state = HANDLE_INTERNAL_ADDR_INC1 then
543
                                if find_dirent_block_num = sectors_per_cluster_zero_indexed then
544
                                        find_dirent_block_num <= (others => '0');
545
                                else
546
                                        find_dirent_block_num <= find_dirent_block_num + 1;
547
                                end if;
548
                        elsif rw_state = HANDLE_FOLDER_DIRENT9 then
549
                                find_dirent_block_num <= (others => '0');
550
                        elsif rw_state = HANDLE_END_OF_DIR0 then
551
                                find_dirent_block_num <= find_dirent_block_num_rd;
552
                        end if;
553
                end if;
554
        end process;
555
 
556
        DIRENT_LIFO: process(CLK_IN)
557
   begin
558
                if rising_edge(CLK_IN) then
559
                        if rw_next_state = PARSE_NAME_DIRENT0 then
560
                                dirent_lifo_rst <= '1';
561
                        else
562
                                dirent_lifo_rst <= '0';
563
                        end if;
564
                        if rw_state = PARSE_NAME_DIRENT2 then
565
                                dirent_lifo_we <= '1';
566
                        elsif rw_state = HANDLE_INTERNAL_ADDR_INC0 then
567
                                dirent_lifo_we <= '0';
568
                        end if;
569
                end if;
570
        end process;
571
 
572
        dirent_name_lifo : lifo
573
                Generic Map (   G_LOG2_DEPTH    => 7,
574
                                                        G_DATA_SIZE             => block_rd_data'length )
575
                 Port Map ( CLK_IN                      => CLK_IN,
576
                                                RESET_IN                => dirent_lifo_rst,
577
                                                CACHE_ADDR_IN   => dirent_lifo_cache_addr,
578
                                                GOTO_CACHE_IN   => dirent_lifo_goto_cache,
579
                                                WR_DATA_IN              => block_rd_data,
580
                                                WR_EN_IN                => dirent_lifo_we,
581
                                                RD_DATA_OUT     => DIRENT_CHAR_OUT,
582
                                                RD_EN_IN                => RD_DIRENT_NAME_CHAR_IN,
583
                                                EMPTY_OUT               => dirent_lifo_empty,
584
                                                FULL_OUT                        => dirent_lifo_full);
585
 
586
        HANDLE_FOLDER_DIRENT: process(CLK_IN)
587
   begin
588
                if rising_edge(CLK_IN) then
589
                        if rw_next_state = HANDLE_FOLDER_DIRENT0 or rw_next_state = HANDLE_FILE_DIRENT0 then
590
                                dirent_found <= '1';
591
                        else
592
                                dirent_found <= '0';
593
                        end if;
594
                        if rw_next_state = HANDLE_FOLDER_DIRENT0 then
595
                                dirent_is_folder <= '1';
596
                        else
597
                                dirent_is_folder <= '0';
598
                        end if;
599
                        if rw_state = HANDLE_FOLDER_DIRENT2 then
600
                                folder_addr(7 downto 0) <= unsigned(block_rd_data);
601
                        elsif rw_state = HANDLE_FOLDER_DIRENT3 then
602
                                folder_addr(15 downto 8) <= unsigned(block_rd_data);
603
                        elsif rw_state = HANDLE_FOLDER_DIRENT4 then
604
                                folder_addr(23 downto 16) <= unsigned(block_rd_data);
605
                        elsif rw_state = HANDLE_FOLDER_DIRENT5 then
606
                                folder_addr(31 downto 24) <= unsigned(block_rd_data);
607
                        end if;
608
                        if rw_state = HANDLE_FOLDER_DIRENT6 then
609
                                folder_addr_tmp <= (folder_addr - 2);
610
                        elsif rw_state = HANDLE_FOLDER_DIRENT7 then
611
                                folder_addr_tmp(31 downto 1) <= folder_addr_tmp(30 downto 0);
612
                                folder_addr_tmp(0) <= '0';
613
                        end if;
614
                        if rw_state = HANDLE_FOLDER_DIRENT8 then
615
                                folder_addr_final <= folder_addr_tmp + cluster_begin_addr;
616
                        end if;
617
                        if rw_state = HANDLE_FOLDER_DIRENT7 or rw_state = HANDLE_INTERNAL_ADDR_INC4 then
618
                                spc_counter(7 downto 1) <= spc_counter(6 downto 0);
619
                                spc_counter(0) <= '0';
620
                        else
621
                                spc_counter <= X"02";
622
                        end if;
623
 
624
 
625
 
626
                end if;
627
        end process;
628
 
629
        HANDLE_BP_CACHING: process(CLK_IN)
630
   begin
631
                if rising_edge(CLK_IN) then
632
                        if rw_state = HANDLE_FOLDER_DIRENT0 then
633
                                bp_lifo_we <= '1';
634
                        else
635
                                bp_lifo_we <= '0';
636
                        end if;
637
                        if rw_next_state = HANDLE_END_OF_DIR0 then
638
                                bp_lifo_rd <= '1';
639
                        else
640
                                bp_lifo_rd <= '0';
641
                        end if;
642
                end if;
643
        end process;
644
 
645
        sd_block_pointer_lifo : lifo
646
                Generic Map (   G_LOG2_DEPTH    => 5,
647
                                                        G_DATA_SIZE             => sd_block_addr'length )
648
                 Port Map ( CLK_IN                      => CLK_IN,
649
                                                RESET_IN                => bp_lifo_rst,
650
                                                CACHE_ADDR_IN   => '0',
651
                                                GOTO_CACHE_IN   => '0',
652
                                                WR_DATA_IN              => slv(sd_block_addr),
653
                                                WR_EN_IN                => bp_lifo_we,
654
                                                RD_DATA_OUT     => bp_lifo_block_data,
655
                                                RD_EN_IN                => bp_lifo_rd,
656
                                                EMPTY_OUT               => bp_lifo_empty,
657
                                                FULL_OUT                        => open);
658
 
659
        find_addr_lifo_we <= bp_lifo_we;
660
        find_addr_lifo_rd <= bp_lifo_rd;
661
        find_dirent_addr_rd <= unsigned(find_dirent_addr_rd_slv);
662
 
663
        find_dirent_addr_lifo : lifo
664
                Generic Map (   G_LOG2_DEPTH    => 5,
665
                                                        G_DATA_SIZE             => find_dirent_addr'length      )
666
                 Port Map ( CLK_IN                      => CLK_IN,
667
                                                RESET_IN                => find_addr_lifo_rst,
668
                                                CACHE_ADDR_IN   => '0',
669
                                                GOTO_CACHE_IN   => '0',
670
                                                WR_DATA_IN              => slv(find_dirent_addr_cache),
671
                                                WR_EN_IN                => find_addr_lifo_we,
672
                                                RD_DATA_OUT     => find_dirent_addr_rd_slv,
673
                                                RD_EN_IN                => find_addr_lifo_rd,
674
                                                EMPTY_OUT               => find_addr_lifo_empty,
675
                                                FULL_OUT                        => open);
676
 
677
        HANDLE_END_FLAG: process(CLK_IN)
678
   begin
679
                if rising_edge(CLK_IN) then
680
                        if rw_state = HANDLE_END_OF_DIRENTS0 then
681
                                end_of_dirents <= '1';
682
                        elsif rw_state = FIND_NEXT_DIRENT0 then
683
                                end_of_dirents <= '0';
684
                        end if;
685
                end if;
686
        end process;
687
 
688
        GOTO_NEXT_CLUSTER: process(CLK_IN)
689
   begin
690
                if rising_edge(CLK_IN) then
691
                        if rw_state = FIND_NEXT_CLUSTER0 then
692
                                current_cluster_fat_block_addr <= fat_begin_addr + RESIZE(current_cluster(31 downto 7), 32);
693
                        end if;
694
                        if rw_state = FIND_NEXT_CLUSTER5 then
695
                                current_cluster(7 downto 0) <= unsigned(block_rd_data);
696
                        elsif rw_state = FIND_NEXT_CLUSTER6 then
697
                                current_cluster(15 downto 8) <= unsigned(block_rd_data);
698
                        elsif rw_state = FIND_NEXT_CLUSTER7 then
699
                                current_cluster(23 downto 16) <= unsigned(block_rd_data);
700
                        elsif rw_state = FIND_NEXT_CLUSTER8 then
701
                                current_cluster(31 downto 24) <= unsigned(block_rd_data); -- TODO Check if equal to 0FFFFFFF (end of cluster) ?
702
                        elsif rw_state = HANDLE_FOLDER_DIRENT6 then
703
                                current_cluster <= folder_addr;
704
                        elsif rw_state = WAIT_FOR_INIT_CMPLT or rw_state = HANDLE_END_OF_DIRENTS0 then
705
                                current_cluster <= X"00000002"; -- TODO Set to ROOT_DIR_FIRST_CLUSTER_IN ?
706
                        elsif rw_state = HANDLE_END_OF_DIR0 then
707
                                current_cluster <= current_cluster_rd;
708
                        end if;
709
                        if rw_state = HANDLE_INTERNAL_ADDR_INC3 then
710
                                current_cluster_tmp <= (current_cluster - 2);
711
                        elsif rw_state = HANDLE_INTERNAL_ADDR_INC4 then
712
                                current_cluster_tmp(31 downto 1) <= current_cluster_tmp(30 downto 0);
713
                                current_cluster_tmp(0) <= '0';
714
                        end if;
715
                        if rw_state = HANDLE_INTERNAL_ADDR_INC5 then
716
                                next_cluster_lba <= current_cluster_tmp + cluster_begin_addr;
717
                        end if;
718
      end if;
719
   end process;
720
 
721
        current_cluster_lifo_we <= bp_lifo_we;
722
        current_cluster_lifo_rd <= bp_lifo_rd;
723
        current_cluster_rd <= unsigned(current_cluster_rd_slv);
724
 
725
        current_cluster_lifo : lifo
726
                Generic Map (   G_LOG2_DEPTH    => 5,
727
                                                        G_DATA_SIZE             => current_cluster'length       )
728
                 Port Map ( CLK_IN                      => CLK_IN,
729
                                                RESET_IN                => current_cluster_lifo_rst,
730
                                                CACHE_ADDR_IN   => '0',
731
                                                GOTO_CACHE_IN   => '0',
732
                                                WR_DATA_IN              => slv(current_cluster),
733
                                                WR_EN_IN                => current_cluster_lifo_we,
734
                                                RD_DATA_OUT     => current_cluster_rd_slv,
735
                                                RD_EN_IN                => current_cluster_lifo_rd,
736
                                                EMPTY_OUT               => current_cluster_lifo_empty,
737
                                                FULL_OUT                        => open);
738
 
739
        find_dirent_block_lifo_we <= bp_lifo_we;
740
        find_dirent_block_lifo_rd <= bp_lifo_rd;
741
        find_dirent_block_num_rd <= unsigned(find_dirent_block_num_rd_slv);
742
 
743
        find_dirent_block_num_lifo : lifo
744
                Generic Map (   G_LOG2_DEPTH    => 5,
745
                                                        G_DATA_SIZE             => find_dirent_block_num'length )
746
                 Port Map ( CLK_IN                      => CLK_IN,
747
                                                RESET_IN                => find_dirent_block_lifo_rst,
748
                                                CACHE_ADDR_IN   => '0',
749
                                                GOTO_CACHE_IN   => '0',
750
                                                WR_DATA_IN              => slv(find_dirent_block_num),
751
                                                WR_EN_IN                => find_dirent_block_lifo_we,
752
                                                RD_DATA_OUT     => find_dirent_block_num_rd_slv,
753
                                                RD_EN_IN                => find_dirent_block_lifo_rd,
754
                                                EMPTY_OUT               => find_dirent_block_lifo_empty,
755
                                                FULL_OUT                        => open);
756
 
757
        LIFO_RST_PROC : process(CLK_IN)
758
   begin
759
                if rising_edge(CLK_IN) then
760
                        if rw_state = HANDLE_END_OF_DIRENTS0 then
761
                                find_dirent_block_lifo_rst <= '1';
762
                                current_cluster_lifo_rst <= '1';
763
                                find_addr_lifo_rst <= '1';
764
                                bp_lifo_rst <= '1';
765
                        else
766
                                find_dirent_block_lifo_rst <= '0';
767
                                current_cluster_lifo_rst <= '0';
768
                                find_addr_lifo_rst <= '0';
769
                                bp_lifo_rst <= '0';
770
                        end if;
771
                end if;
772
        end process;
773
 
774
----------- MAIN FSM ------------
775
 
776
   MAIN_ROUTINE_SYNC: process(CLK_IN)
777
   begin
778
                if rising_edge(CLK_IN) then
779
                        if RESET_IN = '0' then
780
                                rw_state <= rw_next_state;
781
                        else
782
                                rw_state <= IDLE_W_BLOCK_RD;
783
                        end if;
784
      end if;
785
   end process;
786
 
787
        MAIN_ROUTINE_DECODE: process (  sd_init_cmplt,
788
                                                                                                block_rd_cmplt,
789
                                                                                                block_rd_cmplt
790
                                                                                        )
791
   begin
792
      rw_next_state <= rw_state;  -- default is to stay in current state
793
      case (rw_state) is
794
                        when REPORT_ERROR =>
795
                                rw_next_state <= WAIT_FOR_INIT_CMPLT;
796
                        when WAIT_FOR_INIT_CMPLT =>
797
                                if sd_init_cmplt = '1' then
798
               rw_next_state <= IDLE_W_BLOCK_RD;
799
            end if;
800
 
801
                        when IDLE_W_BLOCK_RD =>
802
                                if get_next_dirent = '1' then
803
                                        rw_next_state <= FIND_NEXT_DIRENT0;
804
                                end if;
805
                        when IDLE_NO_BLOCK_RD =>
806
                                if get_next_dirent = '1' then
807
                                        rw_next_state <= FIND_NEXT_DIRENT2;
808
                                end if;
809
 
810
                        when FIND_NEXT_DIRENT0 =>
811
                                rw_next_state <= FIND_NEXT_DIRENT1;
812
                        when FIND_NEXT_DIRENT1 =>
813
                                if block_rd_cmplt = '1' then
814
                                        rw_next_state <= FIND_NEXT_DIRENT2;
815
                                end if;
816
                        when FIND_NEXT_DIRENT2 =>
817
                                rw_next_state <= FIND_NEXT_DIRENT3;
818
                        when FIND_NEXT_DIRENT3 =>
819
                                rw_next_state <= FIND_NEXT_DIRENT4;
820
                        when FIND_NEXT_DIRENT4 =>
821
                                if block_rd_data = C_unused_entry then
822
                                        rw_next_state <= FIND_NEXT_DIRENT6;
823
                                elsif block_rd_data = C_end_of_directory then
824
                                        rw_next_state <= HANDLE_END_OF_DIR0;
825
                                else
826
                                        rw_next_state <= FIND_NEXT_DIRENT5;
827
                                end if;
828
                        when FIND_NEXT_DIRENT5 =>
829
                                if block_rd_data /= C_file_name_type then
830
                                        rw_next_state <= FIND_NEXT_DIRENT6;
831
                                else
832
                                        rw_next_state <= PARSE_NAME_DIRENT0;
833
                                end if;
834
                        when FIND_NEXT_DIRENT6 =>
835
                                rw_next_state <= HANDLE_INTERNAL_ADDR_INC0;
836
 
837
                        when PARSE_NAME_DIRENT0 =>
838
                                rw_next_state <= PARSE_NAME_DIRENT1;
839
                        when PARSE_NAME_DIRENT1 =>
840
                                rw_next_state <= PARSE_NAME_DIRENT2;
841
                        when PARSE_NAME_DIRENT2 =>
842
                                rw_next_state <= PARSE_NAME_DIRENT3;
843
                        when PARSE_NAME_DIRENT3 =>
844
                                rw_next_state <= PARSE_NAME_DIRENT4;
845
                        when PARSE_NAME_DIRENT4 =>
846
                                rw_next_state <= PARSE_NAME_DIRENT5;
847
                        when PARSE_NAME_DIRENT5 =>
848
                                rw_next_state <= PARSE_NAME_DIRENT6;
849
                        when PARSE_NAME_DIRENT6 =>
850
                                rw_next_state <= PARSE_NAME_DIRENT7;
851
                        when PARSE_NAME_DIRENT7 =>
852
                                rw_next_state <= PARSE_NAME_DIRENT8;
853
                        when PARSE_NAME_DIRENT8 =>
854
                                rw_next_state <= PARSE_NAME_DIRENT9;
855
                        when PARSE_NAME_DIRENT9 =>
856
                                rw_next_state <= PARSE_NAME_DIRENT10;
857
                        when PARSE_NAME_DIRENT10 =>
858
                                rw_next_state <= PARSE_NAME_DIRENT11;
859
                        when PARSE_NAME_DIRENT11 =>
860
                                rw_next_state <= PARSE_NAME_DIRENT12;
861
                        when PARSE_NAME_DIRENT12 =>
862
                                rw_next_state <= PARSE_NAME_DIRENT13;
863
                        when PARSE_NAME_DIRENT13 =>
864
                                rw_next_state <= PARSE_NAME_DIRENT14;
865
                        when PARSE_NAME_DIRENT14 =>
866
                                rw_next_state <= HANDLE_INTERNAL_ADDR_INC0;
867
                        when PARSE_NAME_DIRENT15 =>
868
                                rw_next_state <= PARSE_NAME_DIRENT16;
869
                        when PARSE_NAME_DIRENT16 =>
870
                                rw_next_state <= PARSE_NAME_DIRENT17;
871
                        when PARSE_NAME_DIRENT17 =>
872
                                if block_rd_data = C_file_name_type then
873
                                        rw_next_state <= PARSE_NAME_DIRENT1;
874
                                elsif block_rd_data(7 downto 4) = C_folder_type(7 downto 4) then
875
                                        rw_next_state <= HANDLE_FOLDER_DIRENT0;
876
                                elsif block_rd_data(7 downto 4) = C_file_type(7 downto 4) then
877
                                        rw_next_state <= HANDLE_FILE_DIRENT0; -- TODO create 'else' case to prevent lockups
878
                                end if;
879
 
880
                        when HANDLE_FILE_DIRENT0 =>
881
                                rw_next_state <= HANDLE_INTERNAL_ADDR_INC0;
882
 
883
                        when HANDLE_END_OF_DIR0 =>
884
                                if bp_lifo_empty = '0' then
885
                                        rw_next_state <= HANDLE_END_OF_DIR1;
886
                                else
887
                                        rw_next_state <= HANDLE_END_OF_DIRENTS0;
888
                                end if;
889
                        when HANDLE_END_OF_DIR1 =>
890
                                rw_next_state <= HANDLE_END_OF_DIR2;
891
                        when HANDLE_END_OF_DIR2 =>
892
                                rw_next_state <= HANDLE_END_OF_DIR3;
893
                        when HANDLE_END_OF_DIR3 =>
894
                                        rw_next_state <= IDLE_W_BLOCK_RD;
895
 
896
                        when HANDLE_FOLDER_DIRENT0 =>
897
                                rw_next_state <= HANDLE_FOLDER_DIRENT1;
898
                        when HANDLE_FOLDER_DIRENT1 =>
899
                                rw_next_state <= HANDLE_FOLDER_DIRENT2;
900
                        when HANDLE_FOLDER_DIRENT2 =>
901
                                rw_next_state <= HANDLE_FOLDER_DIRENT3;
902
                        when HANDLE_FOLDER_DIRENT3 =>
903
                                rw_next_state <= HANDLE_FOLDER_DIRENT4;
904
                        when HANDLE_FOLDER_DIRENT4 =>
905
                                rw_next_state <= HANDLE_FOLDER_DIRENT5;
906
                        when HANDLE_FOLDER_DIRENT5 =>
907
                                rw_next_state <= HANDLE_FOLDER_DIRENT6;
908
                        when HANDLE_FOLDER_DIRENT6 =>
909
                                rw_next_state <= HANDLE_FOLDER_DIRENT7;
910
                        when HANDLE_FOLDER_DIRENT7 =>
911
                                if spc_counter = sectors_per_cluster then
912
                                        rw_next_state <= HANDLE_FOLDER_DIRENT8;
913
                                end if;
914
                        when HANDLE_FOLDER_DIRENT8 =>
915
                                rw_next_state <= HANDLE_FOLDER_DIRENT9;
916
                        when HANDLE_FOLDER_DIRENT9 =>
917
                                rw_next_state <= IDLE_W_BLOCK_RD;
918
 
919
                        when HANDLE_END_OF_DIRENTS0 =>
920
                                rw_next_state <= HANDLE_END_OF_DIRENTS1;
921
                        when HANDLE_END_OF_DIRENTS1 =>
922
                                if DEBUG_IN(0) = '1' then
923
                                        rw_next_state <= IDLE_W_BLOCK_RD;
924
                                end if;
925
 
926
                        when HANDLE_INTERNAL_ADDR_INC0 =>
927
                                if find_dirent_addr(8 downto 5) = "1111" then
928
                                        rw_next_state <= HANDLE_INTERNAL_ADDR_INC1;
929
                                else
930
                                        rw_next_state <= rw_state_cached;
931
                                end if;
932
                        when HANDLE_INTERNAL_ADDR_INC1 =>
933
                                if find_dirent_block_num = sectors_per_cluster_zero_indexed then
934
                                        rw_next_state <= FIND_NEXT_CLUSTER0;
935
                                else
936
                                        rw_next_state <= HANDLE_INTERNAL_ADDR_INC2;
937
                                end if;
938
                        when HANDLE_INTERNAL_ADDR_INC2 =>
939
                                if block_rd_cmplt = '1' then
940
                                        rw_next_state <= rw_state_cached;
941
                                end if;
942
                        when HANDLE_INTERNAL_ADDR_INC3 =>
943
                                rw_next_state <= HANDLE_INTERNAL_ADDR_INC4;
944
                        when HANDLE_INTERNAL_ADDR_INC4 =>
945
                                if spc_counter = sectors_per_cluster then
946
                                        rw_next_state <= HANDLE_INTERNAL_ADDR_INC5;
947
                                end if;
948
                        when HANDLE_INTERNAL_ADDR_INC5 =>
949
                                rw_next_state <= HANDLE_INTERNAL_ADDR_INC6;
950
                        when HANDLE_INTERNAL_ADDR_INC6 =>
951
                                rw_next_state <= HANDLE_INTERNAL_ADDR_INC7;
952
                        when HANDLE_INTERNAL_ADDR_INC7 =>
953
                                if block_rd_cmplt = '1' then
954
                                        rw_next_state <= rw_state_cached;
955
                                end if;
956
 
957
                        when FIND_NEXT_CLUSTER0 =>
958
                                rw_next_state <= FIND_NEXT_CLUSTER1;
959
                        when FIND_NEXT_CLUSTER1 =>
960
                                rw_next_state <= FIND_NEXT_CLUSTER2;
961
                        when FIND_NEXT_CLUSTER2 =>
962
                                if block_rd_cmplt = '1' then
963
                                        rw_next_state <= FIND_NEXT_CLUSTER3;
964
                                end if;
965
                        when FIND_NEXT_CLUSTER3 =>
966
                                rw_next_state <= FIND_NEXT_CLUSTER4;
967
                        when FIND_NEXT_CLUSTER4 =>
968
                                rw_next_state <= FIND_NEXT_CLUSTER5;
969
                        when FIND_NEXT_CLUSTER5 =>
970
                                rw_next_state <= FIND_NEXT_CLUSTER6;
971
                        when FIND_NEXT_CLUSTER6 =>
972
                                rw_next_state <= FIND_NEXT_CLUSTER7;
973
                        when FIND_NEXT_CLUSTER7 =>
974
                                rw_next_state <= FIND_NEXT_CLUSTER8;
975
                        when FIND_NEXT_CLUSTER8 =>
976
                                rw_next_state <= FIND_NEXT_CLUSTER9;
977
                        when FIND_NEXT_CLUSTER9 =>
978
                                rw_next_state <= HANDLE_INTERNAL_ADDR_INC3;
979
 
980
                end case;
981
        end process;
982
 
983
----------- BLOCK READ FSM ------------
984
 
985
   BLOCK_READ_SYNC: process(CLK_IN)
986
   begin
987
                if rising_edge(CLK_IN) then
988
                        br_state <= br_next_state;
989
      end if;
990
   end process;
991
 
992
        BLOCK_READ_FLAGS: process(CLK_IN)
993
   begin
994
                if rising_edge(CLK_IN) then
995
                        if br_state = READ_BYTE0 and rd_byte_ack = '1' then
996
                                block_rd_we <= '1';
997
                        else
998
                                block_rd_we <= '0';
999
                        end if;
1000
                        if br_state = READ_BYTE1 then
1001
                                rd_byte <= '1';
1002
                        elsif br_state = READ_BYTE2 and rd_byte_ack = '0' then
1003
                                rd_byte <= '0';
1004
                        end if;
1005
                        if br_state = IDLE then
1006
                                block_wr_addr <= (others => '0');
1007
                        elsif br_state = READ_BYTE1 then
1008
                                block_wr_addr <= block_wr_addr + 1;
1009
                        end if;
1010
                        if br_state = READ_BYTE4 then
1011
                                block_rd_cmplt <= '1';
1012
                        else
1013
                                block_rd_cmplt <= '0';
1014
                        end if;
1015
                        if br_state = WAIT_UNTIL_BLOCK_READ_ACKD then
1016
                                sd_block_rd <= '1';
1017
                        else
1018
                                sd_block_rd <= '0';
1019
                        end if;
1020
      end if;
1021
   end process;
1022
 
1023
        BLOCK_READ_DECODE: process (br_state, perform_block_rd, rd_byte_ack, block_wr_addr)
1024
   begin
1025
      br_next_state <= br_state;  -- default is to stay in current state
1026
      case (br_state) is
1027
                        when IDLE =>
1028
                                if perform_block_rd = '1' then
1029
                                        br_next_state <= WAIT_UNTIL_NOT_BUSY;
1030
                                end if;
1031
                        when WAIT_UNTIL_NOT_BUSY =>
1032
                                if sd_busy = '0' then
1033
                                        br_next_state <= WAIT_UNTIL_BLOCK_READ_ACKD;
1034
                                end if;
1035
                        when WAIT_UNTIL_BLOCK_READ_ACKD =>
1036
                                if sd_busy = '1' then
1037
                                        br_next_state <= READ_BYTE0;
1038
                                end if;
1039
                        when READ_BYTE0 =>
1040
                                if rd_byte_ack = '1' then
1041
                                        br_next_state <= READ_BYTE1;
1042
                                end if;
1043
                        when READ_BYTE1 =>
1044
                                br_next_state <= READ_BYTE2;
1045
                        when READ_BYTE2 =>
1046
                                if rd_byte_ack = '0' then
1047
                                        br_next_state <= READ_BYTE3;
1048
                                end if;
1049
                        when READ_BYTE3 =>
1050
                                if block_wr_addr = "000000000" then
1051
                                        br_next_state <= READ_BYTE4;
1052
                                else
1053
                                        br_next_state <= READ_BYTE0;
1054
                                end if;
1055
                        when READ_BYTE4 =>
1056
                                br_next_state <= IDLE;
1057
                end case;
1058
        end process;
1059
 
1060
        Block_Ram_Inst : TDP_RAM
1061
                Generic Map (   G_DATA_A_SIZE   => sd_data'length,
1062
                                                        G_ADDR_A_SIZE   => block_wr_addr'length,
1063
                                                        G_RELATION              => 0,
1064
                                                        G_INIT_FILE             => "") --log2(SIZE_A/SIZE_B)
1065
                Port Map (      CLK_A_IN        => CLK_IN,
1066
                                                WE_A_IN                 => block_rd_we,
1067
                                                ADDR_A_IN       => slv(block_wr_addr),
1068
                                                DATA_A_IN       => sd_data,
1069
                                                DATA_A_OUT      => open,
1070
                                                CLK_B_IN        => CLK_IN,
1071
                                                WE_B_IN                 => '0',
1072
                                                ADDR_B_IN       => slv(block_rd_addr),
1073
                                                DATA_B_IN       => X"00",
1074
                                                DATA_B_OUT      => block_rd_data);
1075
 
1076
        --DEBUG_OUT2(0) <= '1' when rw_state = PARSE_NAME_DIRENT17 else '0';
1077
 
1078
        DEBUG_OUT2(5 downto 0) <= slv(state_debug_sig);
1079
        DEBUG_OUT2(7) <= sd_busy;
1080
 
1081
 
1082
        DEBUG_OUT <= slv(file_counter(15 downto 0));
1083
 
1084
end Behavioral;
1085
 

powered by: WebSVN 2.1.0

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