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

Subversion Repositories aoocs

[/] [aoocs/] [trunk/] [rtl/] [terasic_de2_70/] [bus_sd.v] - Blame information for rev 2

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 alfik
/*
2
 * Copyright 2010, Aleksander Osman, alfik@poczta.fm. All rights reserved.
3
 *
4
 * Redistribution and use in source and binary forms, with or without modification, are
5
 * permitted provided that the following conditions are met:
6
 *
7
 *  1. Redistributions of source code must retain the above copyright notice, this list of
8
 *     conditions and the following disclaimer.
9
 *
10
 *  2. Redistributions in binary form must reproduce the above copyright notice, this list
11
 *     of conditions and the following disclaimer in the documentation and/or other materials
12
 *     provided with the distribution.
13
 *
14
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
15
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
16
 * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR
17
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
19
 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
20
 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
21
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
22
 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
23
 */
24
 
25
/*! \file
26
 * \brief 1-bit SD bus driver for SD cards with WISHBONE master and slave interface.
27
 */
28
 
29
/*! \brief \copybrief bus_sd.v
30
*/
31
module bus_sd(
32
        //% \name Clock and reset
33
    //% @{
34
        input               clk_30,
35
        input               reset_n,
36
        //% @}
37
 
38
        //% \name WISHBONE master
39
    //% @{
40
        output reg          CYC_O,
41
        output reg [31:0]   DAT_O,
42
        output reg          STB_O,
43
        output reg          WE_O,
44
        output reg [31:2]   ADR_O,
45
        output [3:0]        SEL_O,
46
        input [31:0]        DAT_I,
47
        input               ACK_I,
48
        input               ERR_I,
49
        input               RTY_I,
50
        // TAG_TYPE: TGC_O
51
        output              SGL_O,
52
        output              BLK_O,
53
        output              RMW_O,
54
        // TAG_TYPE: TGA_O
55
        output [2:0]        CTI_O,
56
        output [1:0]        BTE_O,
57
        //% @}
58
 
59
        //% \name WISHBONE slave
60
    //% @{
61
        output [31:0]       slave_DAT_O,
62
        input [31:0]        slave_DAT_I,
63
        output reg          ACK_O,
64
        output              ERR_O,
65
        output              RTY_O,
66
        input               CYC_I,
67
        input [3:2]         ADR_I,
68
        input               STB_I,
69
        input               WE_I,
70
        input [3:0]         SEL_I,
71
        //% @}
72
 
73
        //% \name SD bus 1-bit hardware interface
74
    //% @{
75
        output reg          sd_clk_o = 1'b0,
76
        inout               sd_cmd_io,
77
        inout               sd_dat_io,
78
        //% @}
79
 
80
        //% \name Debug signals
81
    //% @{
82
        output [7:0]        debug_sd
83
        //% @}
84
);
85
 
86
/***********************************************************************************************************************
87
 *                                                     Wishbone interface
88
 **********************************************************************************************************************/
89
 
90
assign debug_sd = { (reset_n == 1'b0), (error_count == 16'd65535), 2'b0, control_state };
91
 
92
//---------------------------------------------------- wishbone master
93
assign SGL_O = 1'b1;
94
assign BLK_O = 1'b0;
95
assign RMW_O = 1'b0;
96
assign SEL_O = 4'b1111;
97
assign BTE_O = 2'b00;
98
assign CTI_O = 3'b000;
99
 
100
reg bus_error;
101
reg data_read;
102
reg data_write;
103
reg [31:0] data_part_contents;
104
 
105
//STB_O,CYC_O,WE_O,DAT_O,
106
always @(posedge clk_30 or negedge reset_n) begin
107
        if(reset_n == 1'b0) begin
108
            ADR_O <= 30'd0;
109
                STB_O <= 1'b0;
110
                CYC_O <= 1'b0;
111
                WE_O <= 1'b0;
112
                DAT_O <= 32'd0;
113
                bus_error <= 1'b0;
114
                data_read <= 1'b0;
115
                data_write <= 1'b0;
116
                data_part_contents <= 32'd0;
117
        end
118
        else if(data_state == S_DATA_READ_READY_PART && data_read == 1'b0) begin
119
                if(ACK_I == 1'b1) begin
120
                        STB_O <= 1'b0;
121
                        CYC_O <= 1'b0;
122
                        WE_O <= 1'b0;
123
 
124
                        data_read <= 1'b1;
125
                end
126
                else if(RTY_I == 1'b1) begin
127
                        STB_O <= 1'b0;
128
                        CYC_O <= 1'b0;
129
                        WE_O <= 1'b0;
130
                end
131
                else if(ERR_I == 1'b1) begin
132
                        STB_O <= 1'b0;
133
                        CYC_O <= 1'b0;
134
                        WE_O <= 1'b0;
135
 
136
                        data_read <= 1'b1;
137
                        bus_error <= 1'b1;
138
                end
139
                else begin
140
                    ADR_O <= wb_address_base + { 23'b0, part_counter };
141
                        STB_O <= 1'b1;
142
                        CYC_O <= 1'b1;
143
                        WE_O <= 1'b1;
144
                        DAT_O <= data_part;
145
                end
146
        end
147
        else if(data_state == S_DATA_WRITE_READY_PART && data_write == 1'b0) begin
148
                if(ACK_I == 1'b1) begin
149
                        STB_O <= 1'b0;
150
                        CYC_O <= 1'b0;
151
                        WE_O <= 1'b0;
152
                        data_part_contents <= DAT_I;
153
 
154
                        data_write <= 1'b1;
155
                end
156
                else if(RTY_I == 1'b1) begin
157
                        STB_O <= 1'b0;
158
                        CYC_O <= 1'b0;
159
                        WE_O <= 1'b0;
160
                end
161
                else if(ERR_I == 1'b1) begin
162
                        STB_O <= 1'b0;
163
                        CYC_O <= 1'b0;
164
                        WE_O <= 1'b0;
165
 
166
                        data_write <= 1'b1;
167
                        bus_error <= 1'b1;
168
                end
169
                else begin
170
                    ADR_O <= wb_address_base + { 23'b0, part_counter };
171
                        STB_O <= 1'b1;
172
                        CYC_O <= 1'b1;
173
                        WE_O <= 1'b0;
174
                end
175
        end
176
        else if(data_state != S_DATA_READ_READY_PART && data_state != S_DATA_WRITE_READY_PART) begin
177
                if(status == STATUS_ERROR) begin
178
                        bus_error <= 1'b0;
179
                end
180
 
181
                data_read <= 1'b0;
182
                data_write <= 1'b0;
183
        end
184
end
185
 
186
//---------------------------------------------------- wishbone slave
187
assign ERR_O = 1'b0;
188
assign RTY_O = 1'b0;
189
assign slave_DAT_O = {29'd0, status[2:0]};
190
 
191
// write only
192
reg [31:0] sd_address;
193
reg [31:0] sd_block_count;
194
reg [1:0] control;
195
reg [31:2] wb_address_base;
196
 
197
parameter [1:0]
198
        CONTROL_IDLE            = 2'd0,
199
        CONTROL_REINIT          = 2'd1,
200
        CONTROL_READ            = 2'd2,
201
        CONTROL_WRITE           = 2'd3;
202
 
203
always @(posedge clk_30 or negedge reset_n) begin
204
        if(reset_n == 1'b0) begin
205
                wb_address_base <= 30'd0;
206
                sd_address <= 32'd0;
207
                sd_block_count <= 32'd0;
208
                control <= 2'd0;
209
                ACK_O <= 1'b0;
210
        end
211
        else begin
212
                if(control_state == S_CTRL_PRE_IDLE) begin
213
                        sd_block_count <= sd_block_count - 32'd1;
214
                        sd_address <= sd_address + 32'd1;
215
                        wb_address_base <= wb_address_base + 30'd128;
216
 
217
                        if(sd_block_count == 32'd1) control <= CONTROL_IDLE;
218
                        ACK_O <= 1'b0;
219
                end
220
                else if(CYC_I == 1'b1 && STB_I == 1'b1 && WE_I == 1'b1) begin
221
                ACK_O <= 1'b1;
222
 
223
                if(ADR_I[3:2] == 2'b00) begin
224
                        wb_address_base[31:24] <= (SEL_I[3] == 1'b1) ? slave_DAT_I[31:24] : wb_address_base[31:24];
225
                        wb_address_base[23:16] <= (SEL_I[2] == 1'b1) ? slave_DAT_I[23:16] : wb_address_base[23:16];
226
                        wb_address_base[15:8] <= (SEL_I[1] == 1'b1) ? slave_DAT_I[15:8] : wb_address_base[15:8];
227
                        wb_address_base[7:2] <= (SEL_I[0] == 1'b1) ? slave_DAT_I[7:2] : wb_address_base[7:2];
228
                end
229
                else if(ADR_I[3:2] == 2'b01) begin
230
                        sd_address[31:24] <= (SEL_I[3] == 1'b1) ? slave_DAT_I[31:24] : sd_address[31:24];
231
                        sd_address[23:16] <= (SEL_I[2] == 1'b1) ? slave_DAT_I[23:16] : sd_address[23:16];
232
                        sd_address[15:8] <= (SEL_I[1] == 1'b1) ? slave_DAT_I[15:8] : sd_address[15:8];
233
                        sd_address[7:0] <= (SEL_I[0] == 1'b1) ? slave_DAT_I[7:0] : sd_address[7:0];
234
                end
235
                else if(ADR_I[3:2] == 2'b10) begin
236
                        sd_block_count[31:24] <= (SEL_I[3] == 1'b1) ? slave_DAT_I[31:24] : sd_block_count[31:24];
237
                        sd_block_count[23:16] <= (SEL_I[2] == 1'b1) ? slave_DAT_I[23:16] : sd_block_count[23:16];
238
                        sd_block_count[15:8] <= (SEL_I[1] == 1'b1) ? slave_DAT_I[15:8] : sd_block_count[15:8];
239
                        sd_block_count[7:0] <= (SEL_I[0] == 1'b1) ? slave_DAT_I[7:0] : sd_block_count[7:0];
240
                end
241
                else if(ADR_I[3:2] == 2'b11) begin
242
                        control[1:0] <= (SEL_I[0] == 1'b1) ? slave_DAT_I[1:0] : control[1:0];
243
                end
244
        end
245
        else if(CYC_I == 1'b1 && STB_I == 1'b1 && WE_I == 1'b0 && ADR_I[3:2] == 2'b00) begin
246
                ACK_O <= 1'b1;
247
        end
248
        else begin
249
                ACK_O <= 1'b0;
250
        end
251
        end
252
 
253
end
254
 
255
/***********************************************************************************************************************
256
 *                                                     Control state machine
257
 **********************************************************************************************************************/
258
 
259
reg [3:0] control_state;
260
reg [15:0] error_count;
261
reg [2:0] status;
262
reg [37:0] cmd_send_contents;
263
 
264
reg start_cmd;
265
reg start_read;
266
reg start_write;
267
 
268
`define CRC7_REVERSE crc7[0],crc7[1],crc7[2],crc7[3],crc7[4],crc7[5],crc7[6]
269
 
270
parameter [3:0]
271
        S_CTRL_INIT             = 4'd0,
272
        S_CTRL_CMD0             = 4'd1,
273
        S_CTRL_CMD8             = 4'd2,
274
        S_CTRL_CMD55            = 4'd3,
275
        S_CTRL_ACMD41           = 4'd4,
276
        S_CTRL_CMD2             = 4'd5,
277
        S_CTRL_CMD3             = 4'd6,
278
        S_CTRL_CMD7             = 4'd7,
279
        S_CTRL_PRE_IDLE         = 4'd8,
280
        S_CTRL_IDLE                     = 4'd9,
281
        S_CTRL_CMD17_READ       = 4'd10,
282
        S_CTRL_CMD24_WRITE      = 4'd11;
283
 
284
parameter [2:0]
285
        STATUS_INIT             = 3'd0,
286
        STATUS_INIT_ERROR       = 3'd1,
287
        STATUS_IDLE             = 3'd2,
288
        STATUS_READ                     = 3'd3,
289
        STATUS_WRITE            = 3'd4,
290
        STATUS_ERROR            = 3'd5;
291
 
292
always @(posedge clk_30 or negedge reset_n) begin
293
        if(reset_n == 1'b0) begin
294
                control_state <= S_CTRL_INIT;
295
                status <= STATUS_INIT;
296
                cmd_send_contents <= 38'd0;
297
                start_cmd <= 1'b0;
298
                start_read <= 1'b0;
299
                start_write <= 1'b0;
300
                error_count <= 16'd0;
301
        end
302
        else if(control_state == S_CTRL_INIT && error_count == 16'd65535) begin
303
                status <= STATUS_INIT_ERROR;
304
 
305
                if(control == CONTROL_REINIT) begin
306
                        error_count <= 16'd0;
307
                        control_state <= S_CTRL_INIT;
308
                end
309
        end
310
        else if(control_state == S_CTRL_INIT) begin
311
                status <= STATUS_INIT;
312
 
313
                if(cmd_state == S_CMD_IDLE && start_cmd == 1'b0) begin
314
                    start_cmd <= 1'b1;
315
                        //CMD0, no arguments
316
                        cmd_send_contents <= { 6'd0, 32'd0 };
317
                        control_state <= S_CTRL_CMD0;
318
                end
319
        end
320
        else if(control_state == S_CTRL_CMD0) begin
321
 
322
                if(cmd_state == S_CMD_REPLY_ERROR) begin
323
                        error_count <= error_count + 16'd1;
324
                        control_state <= S_CTRL_INIT;
325
                end
326
                else if(cmd_state == S_CMD_IDLE && start_cmd == 1'b0) begin
327
                        start_cmd <= 1'b1;
328
                        //CMD8, supply voltage, check pattern
329
                        cmd_send_contents <= { 6'd8, 20'd0, 4'b0001, 8'b10101010 };
330
                        control_state <= S_CTRL_CMD8;
331
                end
332
                else start_cmd <= 1'b0;
333
        end
334
        else if(control_state == S_CTRL_CMD8) begin
335
                if(start_cmd == 1'b1) begin
336
                        start_cmd <= 1'b0;
337
                end
338
                else if(cmd_state == S_CMD_REPLY_ERROR ||
339
                        (cmd_state == S_CMD_IDLE && cmd_reply != { 1'b0, 1'b0, 6'd8, 20'd0, 4'b0001, 8'b10101010, `CRC7_REVERSE, 1'b1 })
340
                ) begin
341
                        error_count <= error_count + 16'd1;
342
                        control_state <= S_CTRL_INIT;
343
                end
344
                else if(cmd_state == S_CMD_IDLE) begin
345
                        start_cmd <= 1'b1;
346
                        //CMD55, RCA
347
                        cmd_send_contents <= { 6'd55, 16'd0, 16'd0};
348
                        control_state <= S_CTRL_CMD55;
349
                end
350
        end
351
        else if(control_state == S_CTRL_CMD55) begin
352
                if(start_cmd == 1'b1) begin
353
                        start_cmd <= 1'b0;
354
                end
355
                else if(cmd_state == S_CMD_REPLY_ERROR ||
356
                        (cmd_state == S_CMD_IDLE &&
357
                                (cmd_reply[47:40] != { 1'b0, 1'b0, 6'd55 } || cmd_reply[39:27] != 13'b0 || cmd_reply[24:21] != 4'b0 ||
358
                                 cmd_reply[13] != 1'b1 || cmd_reply[11] != 1'b0 || cmd_reply[7:0] != { `CRC7_REVERSE, 1'b1 }
359
                                )
360
                        )
361
                ) begin
362
                        error_count <= error_count + 16'd1;
363
                        control_state <= S_CTRL_INIT;
364
                end
365
                else if(cmd_state == S_CMD_IDLE && start_cmd == 1'b0) begin
366
                        start_cmd <= 1'b1;
367
                        //ACMD41, 
368
                        cmd_send_contents <= {  6'd41,                                                          //command index
369
                                                                        1'b0,                                                           //reserved bit
370
                                                                        1'b1,                                                           //host capacity support HCS(OCR[30])
371
                                                                        6'b0,                                                           //reserved bits
372
                                                                        24'b0001_0000_0000_0000_0000_0000       //VDD voltage window OCR[23:0]
373
                        };
374
                        control_state <= S_CTRL_ACMD41;
375
                end
376
        end
377
        else if(control_state == S_CTRL_ACMD41) begin
378
                if(start_cmd == 1'b1) begin
379
                        start_cmd <= 1'b0;
380
                end
381
                else if(cmd_state == S_CMD_REPLY_ERROR ||
382
                        (cmd_state == S_CMD_IDLE && (cmd_reply[47:40] != { 1'b0, 1'b0, 6'b111111 } ||
383
                                cmd_reply[39:38] != 2'b11 || cmd_reply[7:0] != {7'b1111111, 1'b1 })
384
                        )
385
                ) begin
386
                        if(error_count == 16'd65535) begin
387
                                control_state <= S_CTRL_INIT;
388
                        end
389
                        else begin
390
                                error_count <= error_count + 16'd1;
391
                                start_cmd <= 1'b1;
392
                                //CMD55, RCA
393
                                cmd_send_contents <= { 6'd55, 16'd0, 16'd0};
394
                                control_state <= S_CTRL_CMD55;
395
                        end
396
                end
397
                else if(cmd_state == S_CMD_IDLE && start_cmd == 1'b0) begin
398
                        start_cmd <= 1'b1;
399
                        //CMD2, no arguments
400
                        cmd_send_contents <= { 6'd2, 32'd0 };
401
                        control_state <= S_CTRL_CMD2;
402
                end
403
        end
404
        else if(control_state == S_CTRL_CMD2) begin
405
                if(start_cmd == 1'b1) begin
406
                        start_cmd <= 1'b0;
407
                end
408
                else if(cmd_state == S_CMD_REPLY_ERROR ||
409
                        (cmd_state == S_CMD_IDLE && cmd_reply[0] != 1'b1)
410
                ) begin
411
                        error_count <= error_count + 16'd1;
412
                        control_state <= S_CTRL_INIT;
413
                end
414
                else if(cmd_state == S_CMD_IDLE && start_cmd == 1'b0) begin
415
                        start_cmd <= 1'b1;
416
                        //CMD3, no arguments
417
                        cmd_send_contents <= { 6'd3, 32'd0 };
418
                        control_state <= S_CTRL_CMD3;
419
                end
420
        end
421
        else if(control_state == S_CTRL_CMD3) begin
422
                if(start_cmd == 1'b1) begin
423
                        start_cmd <= 1'b0;
424
                end
425
                else if(cmd_state == S_CMD_REPLY_ERROR ||
426
                        (cmd_state == S_CMD_IDLE &&
427
                                (cmd_reply[47:40] != { 1'b0, 1'b0, 6'd3 } ||
428
                                 /*23:8= 23,22,19,12:0 from card status*/
429
                                 cmd_reply[23:21] != 3'b0 || cmd_reply[13] != 1'b0 || cmd_reply[11] != 1'b0 ||
430
                                 cmd_reply[7:0] != { `CRC7_REVERSE, 1'b1 }
431
                                )
432
                        )
433
                ) begin
434
                        error_count <= error_count + 16'd1;
435
                        control_state <= S_CTRL_INIT;
436
                end
437
                else if(cmd_state == S_CMD_IDLE && start_cmd == 1'b0) begin
438
 
439
                        start_cmd <= 1'b1;
440
                        //CMD7, no arguments
441
                        cmd_send_contents <= {  6'd7,                           //command index
442
                                                                        cmd_reply[39:24],       //RCA
443
                                                                        16'd0                           //stuff bits
444
                        };
445
                        control_state <= S_CTRL_CMD7;
446
                end
447
        end
448
        else if(control_state == S_CTRL_CMD7) begin
449
                if(start_cmd == 1'b1) begin
450
                        start_cmd <= 1'b0;
451
                end
452
                else if(cmd_state == S_CMD_REPLY_ERROR ||
453
                        (cmd_state == S_CMD_IDLE &&
454
                                (cmd_reply[47:40] != { 1'b0, 1'b0, 6'd7 } || cmd_reply[39:27] != 13'b0 || cmd_reply[24:21] != 4'b0 ||
455
                                 cmd_reply[13] != 1'b0 || cmd_reply[11] != 1'b0 || cmd_reply[7:0] != { `CRC7_REVERSE, 1'b1 }
456
                                )
457
                        )
458
                ) begin
459
                        error_count <= error_count + 16'd1;
460
                        control_state <= S_CTRL_INIT;
461
                end
462
                else if(cmd_state == S_CMD_IDLE && start_cmd == 1'b0) begin
463
                        start_cmd <= 1'b0;
464
 
465
                        error_count <= 16'd0;
466
                        control_state <= S_CTRL_IDLE;
467
                end
468
        end
469
        else if(control_state == S_CTRL_PRE_IDLE) begin
470
                control_state <= S_CTRL_IDLE;
471
 
472
                if(bus_error == 1'b1) error_count <= 16'd65535;
473
        end
474
        else if(control_state == S_CTRL_IDLE && error_count != 16'd0) begin
475
                status <= STATUS_ERROR;
476
 
477
                if(control == CONTROL_IDLE) begin
478
                        control_state <= S_CTRL_IDLE;
479
                        error_count <= 16'd0;
480
                end
481
                else if(control == CONTROL_REINIT) begin
482
                        control_state <= S_CTRL_INIT;
483
                        error_count <= 16'd0;
484
                end
485
        end
486
        else if(control_state == S_CTRL_IDLE) begin
487
                if(control == CONTROL_READ && sd_block_count != 32'd0) begin
488
                        status <= STATUS_READ;
489
                        start_cmd <= 1'b1;
490
                        start_read <= 1'b1;
491
                        //CMD17, sector address
492
                        cmd_send_contents <= {  6'd17,                          //command index
493
                                                                        sd_address[31:0] //sector address
494
                        };
495
                        control_state <= S_CTRL_CMD17_READ;
496
                end
497
                else if(control == CONTROL_WRITE && sd_block_count != 32'd0) begin
498
                        status <= STATUS_WRITE;
499
                        start_cmd <= 1'b1;
500
                        start_write <= 1'b1;
501
                        //CMD24, sector address
502
                        cmd_send_contents <= {  6'd24,                          //command index
503
                                                                        sd_address[31:0]         //sector address
504
                        };
505
                        control_state <= S_CTRL_CMD24_WRITE;
506
                end
507
                else begin
508
                        status <= STATUS_IDLE;
509
                end
510
        end
511
        else if(control_state == S_CTRL_CMD17_READ) begin
512
                if(start_cmd == 1'b1) begin
513
                        start_cmd <= 1'b0;
514
                end
515
                else if(cmd_state == S_CMD_REPLY_ERROR ||
516
                        (cmd_state == S_CMD_IDLE &&
517
                                (cmd_reply[47:40] != { 1'b0, 1'b0, 6'd17 } || cmd_reply[39:27] != 13'b0 || cmd_reply[24:21] != 4'b0 ||
518
                                 cmd_reply[13] != 1'b0 || cmd_reply[11] != 1'b0 || cmd_reply[7:0] != { `CRC7_REVERSE, 1'b1 }
519
                                )
520
                        )
521
                ) begin
522
                        error_count <= error_count + 16'd1;
523
                        control_state <= S_CTRL_IDLE;
524
                end
525
                else if(cmd_state == S_CMD_IDLE && start_cmd == 1'b0 && start_read == 1'b1) begin
526
                        start_read <= 1'b0;
527
                end
528
                else if(cmd_state == S_CMD_IDLE && start_cmd == 1'b0 && start_read == 1'b0 && data_state == S_DATA_READ_ERROR) begin
529
                        error_count <= error_count + 16'd1;
530
                        control_state <= S_CTRL_IDLE;
531
                end
532
                else if(cmd_state == S_CMD_IDLE && start_cmd == 1'b0 && start_read == 1'b0 && data_state == S_DATA_IDLE) begin
533
                        error_count <= 16'd0;
534
                        control_state <= S_CTRL_PRE_IDLE;
535
                end
536
        end
537
        else if(control_state == S_CTRL_CMD24_WRITE) begin
538
                if(start_cmd == 1'b1) begin
539
                        start_cmd <= 1'b0;
540
                end
541
                else if(cmd_state == S_CMD_REPLY_ERROR ||
542
                        (cmd_state == S_CMD_IDLE &&
543
                                (cmd_reply[47:40] != { 1'b0, 1'b0, 6'd24 } || cmd_reply[39:27] != 13'b0 || cmd_reply[24:21] != 4'b0 ||
544
                                 cmd_reply[13] != 1'b0 || cmd_reply[11] != 1'b0 || cmd_reply[7:0] != { `CRC7_REVERSE, 1'b1 }
545
                                )
546
                        )
547
                ) begin
548
                        error_count <= error_count + 16'd1;
549
                        control_state <= S_CTRL_IDLE;
550
                end
551
                else if(cmd_state == S_CMD_IDLE && start_cmd == 1'b0 && start_write == 1'b1) begin
552
                        start_write <= 1'b0;
553
                end
554
                else if(cmd_state == S_CMD_IDLE && start_cmd == 1'b0 && start_write == 1'b0 && data_state == S_DATA_WRITE_ERROR) begin
555
                        error_count <= error_count + 16'd1;
556
                        control_state <= S_CTRL_IDLE;
557
                end
558
                else if(cmd_state == S_CMD_IDLE && start_cmd == 1'b0 && start_write == 1'b0 && data_state == S_DATA_IDLE) begin
559
                        error_count <= 16'd0;
560
                        control_state <= S_CTRL_PRE_IDLE;
561
                end
562
        end
563
end
564
 
565
/***********************************************************************************************************************
566
 *                                                     SD interface
567
 **********************************************************************************************************************/
568
 
569
reg sd_cmd_o = 1'b1;
570
reg sd_dat_o = 1'b1;
571
 
572
assign sd_cmd_io = (sd_cmd_enable == 1'b1) ? sd_cmd_o : 1'bZ;
573
assign sd_dat_io = (sd_data_enable == 1'b1) ? sd_dat_o : 1'bZ;
574
 
575
//CID register not interpreted: CRC7 not checked, always accepted
576
 
577
//---------------------------------------------------- SD data
578
 
579
reg sd_data_enable;
580
reg [3:0] data_state;
581
reg [23:0] data_counter;
582
reg [6:0] part_counter;
583
reg [15:0] crc16;
584
reg [31:0] data_part;
585
reg clk_data_ena;
586
reg clk_master_ena;
587
 
588
parameter [3:0]
589
        S_DATA_IDLE                                                             = 4'd0,
590
        S_DATA_READ_START_BIT                                           = 4'd1,
591
        S_DATA_READ_CONTENTS                                            = 4'd2,
592
        S_DATA_READ_READY_PART                                          = 4'd3,
593
        S_DATA_READ_READY_PART_CONTINUE                         = 4'd4,
594
        S_DATA_READ_CRC16_END_BIT                                       = 4'd5,
595
        S_DATA_READ_ERROR                                                       = 4'd6,
596
        S_DATA_WRITE_START_BIT                                          = 4'd7,
597
        S_DATA_WRITE_READY_PART                                         = 4'd8,
598
        S_DATA_WRITE_CONTENTS                                           = 4'd9,
599
        S_DATA_WRITE_CRC16_END_BIT                                      = 4'd10,
600
        S_DATA_WRITE_CRC_STATUS_START                           = 4'd11,
601
        S_DATA_WRITE_CRC_STATUS_CONTENTS_END_BIT        = 4'd12,
602
        S_DATA_WRITE_BUSY_START                                         = 4'd13,
603
        S_DATA_WRITE_BUSY_WAIT                                          = 4'd14,
604
        S_DATA_WRITE_ERROR                                                      = 4'd15;
605
 
606
 
607
always @(posedge clk_30 or negedge reset_n) begin
608
        if(reset_n == 1'b0) begin
609
                sd_data_enable  <= 1'b0;
610
                data_state              <= S_DATA_IDLE;
611
                data_counter    <= 24'd0;
612
                part_counter    <= 7'd0;
613
                crc16                   <= 16'd0;
614
                data_part               <= 32'd0;
615
                clk_data_ena    <= 1'b0;
616
                clk_master_ena  <= 1'b1;
617
                sd_dat_o                <= 1'b1;
618
        end
619
        else if(data_state == S_DATA_IDLE) begin
620
                //do not wait for read command and reply
621
                if(start_read == 1'b1) begin
622
                        data_state <= S_DATA_READ_START_BIT;
623
                end
624
                //wait for write command and reply
625
                else if(start_write == 1'b1 && start_cmd == 1'b0 && cmd_state == S_CMD_IDLE) begin
626
                        data_state <= S_DATA_WRITE_START_BIT;
627
                end
628
        end
629
        else if(clk_counter == 2'd0) begin
630
 
631
                //wait for response and data simultaneously (data read)
632
                if(data_state == S_DATA_READ_START_BIT) begin
633
                        clk_data_ena <= 1'b1;
634
 
635
                        if(sd_dat_io == 1'b0) begin
636
                                crc16 <= { sd_dat_io ^ crc16[0], crc16[15:12], sd_dat_io ^ crc16[11] ^ crc16[0], crc16[10:5],
637
                                        sd_dat_io ^ crc16[4] ^ crc16[0], crc16[3:1] };
638
 
639
                                data_state <= S_DATA_READ_CONTENTS;
640
                                data_counter <= 24'd0;
641
                        end
642
                        else if(data_counter == 24'd65535) begin
643
                                data_state <= S_DATA_READ_ERROR;
644
                                data_counter <= 24'd0;
645
                        end
646
                        else data_counter <= data_counter + 24'd1;
647
                end
648
                else if(data_state == S_DATA_READ_CONTENTS) begin
649
                        crc16 <= { sd_dat_io ^ crc16[0], crc16[15:12], sd_dat_io ^ crc16[11] ^ crc16[0],
650
                                crc16[10:5], sd_dat_io ^ crc16[4] ^ crc16[0], crc16[3:1] };
651
                        data_part <= { data_part[30:0], sd_dat_io };
652
 
653
                        if(data_counter == 24'd30) begin
654
                                clk_master_ena <= 1'b0;
655
                                data_counter <= data_counter + 24'd1;
656
                        end
657
                        else if(data_counter == 24'd31) begin
658
                                data_state <= S_DATA_READ_READY_PART;
659
                                data_counter <= 24'd0;
660
                        end
661
                        else data_counter <= data_counter + 24'd1;
662
                end
663
                else if(data_state == S_DATA_READ_READY_PART) begin
664
                        if(data_read == 1'b1) begin
665
                                clk_master_ena <= 1'b1;
666
                                data_state <= S_DATA_READ_READY_PART_CONTINUE;
667
                        end
668
                end
669
                else if(data_state == S_DATA_READ_READY_PART_CONTINUE) begin
670
                        if(part_counter == 7'd127) begin
671
                                data_state <= S_DATA_READ_CRC16_END_BIT;
672
                                part_counter <= 7'd0;
673
                        end
674
                        else begin
675
                                data_state <= S_DATA_READ_CONTENTS;
676
                                part_counter <= part_counter + 7'd1;
677
                        end
678
                end
679
                else if(data_state == S_DATA_READ_CRC16_END_BIT) begin
680
                        data_part <= { sd_dat_io, data_part[31:1] };
681
 
682
                        if(data_counter == 24'd16) begin
683
                                if(data_part[31:16] != crc16[15:0] || sd_dat_io != 1'b1) begin
684
                                        data_state <= S_DATA_READ_ERROR;
685
                                        data_counter <= 24'd0;
686
                                end
687
                                else begin
688
                                        clk_data_ena <= 1'b0;
689
                                        data_state <= S_DATA_IDLE;
690
                                        data_counter <= 24'd0;
691
                                        crc16 <= 16'd0;
692
                                end
693
                        end
694
                        else data_counter <= data_counter + 24'd1;
695
                end
696
                else if(data_state == S_DATA_READ_ERROR) begin
697
                        clk_data_ena <= 1'b0;
698
                        data_state <= S_DATA_IDLE;
699
                        data_counter <= 24'd0;
700
                        crc16 <= 16'd0;
701
                end
702
 
703
                //send data on data line, wait for crc status, wait while busy on data line (data write)
704
                else if(data_state == S_DATA_WRITE_START_BIT) begin
705
                        sd_dat_o <= 1'b0;
706
                        crc16 <= { 1'b0 ^ crc16[0], crc16[15:12], 1'b0 ^ crc16[11] ^ crc16[0], crc16[10:5],
707
                                1'b0 ^ crc16[4] ^ crc16[0], crc16[3:1] };
708
 
709
                        sd_data_enable <= 1'b1;
710
                        clk_data_ena <= 1'b1;
711
                        data_counter <= 24'd0;
712
                        data_state <= S_DATA_WRITE_READY_PART;
713
                end
714
                else if(data_state == S_DATA_WRITE_READY_PART) begin
715
 
716
                        if(data_write == 1'b1) begin
717
                            clk_data_ena <= 1'b1;
718
                                data_state <= S_DATA_WRITE_CONTENTS;
719
                                data_part <= data_part_contents;
720
                        end
721
                        else begin
722
                            clk_data_ena <= 1'b0;
723
                        end
724
                end
725
                else if(data_state == S_DATA_WRITE_CONTENTS) begin
726
                        sd_dat_o <= data_part[31];
727
                        crc16 <= { data_part[31] ^ crc16[0], crc16[15:12], data_part[31] ^ crc16[11] ^ crc16[0], crc16[10:5],
728
                                data_part[31] ^ crc16[4] ^ crc16[0], crc16[3:1] };
729
                        data_part <= { data_part[30:0], 1'b0 };
730
 
731
                        if(data_counter == 24'd31) begin
732
                                data_counter <= 24'd0;
733
 
734
                                if(part_counter == 7'd127) begin
735
                                        part_counter <= 7'd0;
736
                                        data_state <= S_DATA_WRITE_CRC16_END_BIT;
737
                                end
738
                                else begin
739
                                    clk_data_ena <= 1'b0;
740
                                        part_counter <= part_counter + 7'd1;
741
                                        data_state <= S_DATA_WRITE_READY_PART;
742
                                end
743
                        end
744
                        else data_counter <= data_counter + 24'd1;
745
                end
746
 
747
                else if(data_state == S_DATA_WRITE_CRC16_END_BIT) begin
748
                        sd_dat_o <= crc16[0];
749
 
750
                        if(data_counter == 24'd16) begin
751
                            data_counter <= 24'd0;
752
                            crc16 <= 16'd0;
753
                                data_state <= S_DATA_WRITE_CRC_STATUS_START;
754
                        end
755
                        else begin
756
                                crc16 <= { 1'b1, crc16[15:1] };
757
                                data_counter <= data_counter + 24'd1;
758
                        end
759
 
760
                end
761
                else if(data_state == S_DATA_WRITE_CRC_STATUS_START) begin
762
                        sd_data_enable <= 1'b0;
763
 
764
                        if(sd_dat_io == 1'b0) begin
765
                                data_state <= S_DATA_WRITE_CRC_STATUS_CONTENTS_END_BIT;
766
                                data_counter <= 24'b0;
767
                        end
768
                        else if(data_counter == 24'd65535) begin
769
                                data_state <= S_DATA_WRITE_ERROR;
770
                                data_counter <= 24'b0;
771
                        end
772
                        else data_counter <= data_counter + 24'd1;
773
                end
774
 
775
                else if(data_state == S_DATA_WRITE_CRC_STATUS_CONTENTS_END_BIT) begin
776
                        data_part <= { data_part[30:0], sd_dat_io };
777
 
778
                        if(data_counter == 24'd3) begin
779
                                data_state <= S_DATA_WRITE_BUSY_START;
780
                                data_counter <= 24'b0;
781
                        end
782
                        else data_counter <= data_counter + 24'd1;
783
                end
784
                else if(data_state == S_DATA_WRITE_BUSY_START) begin
785
 
786
                        if(sd_dat_io == 1'b0) begin
787
                                data_state <= S_DATA_WRITE_BUSY_WAIT;
788
                                data_counter <= 24'b0;
789
                        end
790
                        else if(data_counter == 24'd65535) begin
791
                                data_state <= S_DATA_WRITE_ERROR;
792
                                data_counter <= 24'b0;
793
                        end
794
                        else data_counter <= data_counter + 24'd1;
795
                end
796
                else if(data_state == S_DATA_WRITE_BUSY_WAIT) begin
797
                        if(sd_dat_io == 1'b1 && data_part[3:0] != 4'b0101) begin
798
                                data_state <= S_DATA_WRITE_ERROR;
799
                                data_counter <= 24'd0;
800
                        end
801
                        else if(sd_dat_io == 1'b1) begin
802
                                clk_data_ena <= 1'b0;
803
                                data_state <= S_DATA_IDLE;
804
                                data_counter <= 24'd0;
805
                        end
806
                        else if(data_counter == 24'hFFFFFF) begin
807
                                data_state <= S_DATA_WRITE_ERROR;
808
                                data_counter <= 24'd0;
809
                        end
810
                        else data_counter <= data_counter + 24'd1;
811
                end
812
                else if(data_state == S_DATA_WRITE_ERROR) begin
813
                        clk_data_ena <= 1'b0;
814
                        data_state <= S_DATA_IDLE;
815
                        data_counter <= 24'd0;
816
                end
817
        end
818
end
819
 
820
//---------------------------------------------------- SD command
821
 
822
reg             sd_cmd_enable;
823
reg [37:0]       cmd_send;
824
reg [47:0]       cmd_reply;
825
reg [3:0]        cmd_state;
826
reg [7:0]        cmd_counter;
827
reg [6:0]        crc7;
828
reg             clk_cmd_ena;
829
 
830
parameter [3:0]
831
        S_CMD_IDLE                                      = 4'd0,
832
        S_CMD_SEND_START_ONES           = 4'd1,
833
        S_CMD_SEND_START_BIT            = 4'd2,
834
        S_CMD_SEND_START_HOST           = 4'd3,
835
        S_CMD_SEND_CONTENTS             = 4'd4,
836
        S_CMD_SEND_CRC7                         = 4'd5,
837
        S_CMD_SEND_END_BIT                      = 4'd6,
838
        S_CMD_SEND_END_ONES             = 4'd7,
839
        S_CMD_REPLY_START_BIT           = 4'd8,
840
        S_CMD_REPLY_CONTENTS            = 4'd9,
841
        S_CMD_REPLY_CRC7_END_BIT        = 4'd10,
842
        S_CMD_REPLY_FINISH_ONES         = 4'd11,
843
        S_CMD_REPLY_ERROR                       = 4'd12;
844
 
845
 
846
always @(posedge clk_30 or negedge reset_n) begin
847
        if(reset_n == 1'b0) begin
848
                sd_cmd_enable   <= 1'b0;
849
                cmd_send                <= 38'd0;
850
                cmd_reply               <= 48'd0;
851
                cmd_state               <= S_CMD_IDLE;
852
                cmd_counter     <= 8'd0;
853
                crc7                    <= 7'd0;
854
                clk_cmd_ena     <= 1'b0;
855
                sd_cmd_o                <= 1'b1;
856
        end
857
        else if(cmd_state == S_CMD_IDLE) begin
858
                if(start_cmd == 1'b1) begin
859
                        cmd_state <= S_CMD_SEND_START_ONES;
860
                end
861
        end
862
        else if(clk_counter == 2'd0 && clk_master_ena == 1'b1) begin
863
 
864
                //send command
865
                if(cmd_state == S_CMD_SEND_START_ONES) begin
866
                        sd_cmd_enable <= 1'b1;
867
                        sd_cmd_o <= 1'b1;
868
                        clk_cmd_ena <= 1'b1;
869
                        crc7 <= 7'd0;
870
 
871
                        if(cmd_counter == 8'd7) begin
872
                                cmd_state <= S_CMD_SEND_START_BIT;
873
                                cmd_counter <= 8'd0;
874
                        end
875
                        else cmd_counter <= cmd_counter + 8'd1;
876
                end
877
                else if(cmd_state == S_CMD_SEND_START_BIT) begin
878
                        sd_cmd_o <= 1'b0;
879
                        crc7 <= { 1'b0 ^ crc7[0], crc7[6:5], 1'b0 ^ crc7[4] ^ crc7[0], crc7[3:1] };
880
 
881
                        cmd_state <= S_CMD_SEND_START_HOST;
882
                end
883
                else if(cmd_state == S_CMD_SEND_START_HOST) begin
884
                        sd_cmd_o <= 1'b1;
885
                        crc7 <= { 1'b1 ^ crc7[0], crc7[6:5], 1'b1 ^ crc7[4] ^ crc7[0], crc7[3:1] };
886
 
887
                        cmd_send <= cmd_send_contents;
888
                        cmd_state <= S_CMD_SEND_CONTENTS;
889
                end
890
                else if(cmd_state == S_CMD_SEND_CONTENTS) begin
891
                        sd_cmd_o <= cmd_send[37];
892
                        crc7 <= { cmd_send[37] ^ crc7[0], crc7[6:5], cmd_send[37] ^ crc7[4] ^ crc7[0], crc7[3:1] };
893
                        cmd_send <= { cmd_send[36:0], 1'b0 };
894
 
895
                        if(cmd_counter == 8'd37) begin
896
                                cmd_state <= S_CMD_SEND_CRC7;
897
                                cmd_counter <= 8'd0;
898
                        end
899
                        else cmd_counter <= cmd_counter + 8'd1;
900
                end
901
                else if(cmd_state == S_CMD_SEND_CRC7) begin
902
                        sd_cmd_o <= crc7[0];
903
                        crc7 <= { 1'b0, crc7[6:1] };
904
 
905
                        if(cmd_counter == 8'd6) begin
906
                                cmd_state <= S_CMD_SEND_END_BIT;
907
                                cmd_counter <= 8'd0;
908
                        end
909
                        else cmd_counter <= cmd_counter + 8'd1;
910
                end
911
                else if(cmd_state == S_CMD_SEND_END_BIT) begin
912
                        sd_cmd_o <= 1'b1;
913
 
914
                        // if CMD0: send ones
915
                        if(control_state == S_CTRL_CMD0) begin
916
                                cmd_state <= S_CMD_SEND_END_ONES;
917
                        end
918
                        else begin
919
                                crc7 <= 7'd0;
920
                                cmd_state <= S_CMD_REPLY_START_BIT;
921
                        end
922
                end
923
                else if(cmd_state == S_CMD_SEND_END_ONES) begin
924
                        sd_cmd_enable <= 1'b0;
925
                        sd_cmd_o <= 1'b1;
926
 
927
                        if(cmd_counter == 8'd7) begin
928
                                clk_cmd_ena <= 1'b0;
929
                                cmd_state <= S_CMD_IDLE;
930
                                cmd_counter <= 8'd0;
931
                        end
932
                        else cmd_counter <= cmd_counter + 8'd1;
933
                end
934
 
935
                //wait for response: 48-bits with CRC7
936
                //wait for response: 48-bits without CRC7
937
                //wait for response: 136-bits (CMD2/R2)
938
                //wait for response and busy on data line simultaneously: (CMD7/R1b)
939
                else if(cmd_state == S_CMD_REPLY_START_BIT) begin
940
                        sd_cmd_enable <= 1'b0;
941
 
942
                        if(sd_cmd_io == 1'b0) begin
943
                                crc7 <= { sd_cmd_io ^ crc7[0], crc7[6:5], sd_cmd_io ^ crc7[4] ^ crc7[0], crc7[3:1] };
944
                                cmd_reply <= { cmd_reply[46:0], sd_cmd_io };
945
 
946
                                cmd_state <= S_CMD_REPLY_CONTENTS;
947
                                cmd_counter <= 8'd0;
948
                        end
949
                        else if(cmd_counter == 8'd255) begin
950
                                crc7 <= 7'd0;
951
                                cmd_state <= S_CMD_REPLY_ERROR;
952
                                cmd_counter <= 8'd0;
953
                        end
954
                        else cmd_counter <= cmd_counter + 8'd1;
955
                end
956
                else if(cmd_state == S_CMD_REPLY_CONTENTS) begin
957
                        crc7 <= { sd_cmd_io ^ crc7[0], crc7[6:5], sd_cmd_io ^ crc7[4] ^ crc7[0], crc7[3:1] };
958
                        cmd_reply <= { cmd_reply[46:0], sd_cmd_io };
959
 
960
                        if(     (control_state != S_CTRL_CMD2 && cmd_counter == 8'd38) ||
961
                                (control_state == S_CTRL_CMD2 && cmd_counter == 8'd126)
962
                        ) begin
963
                                cmd_state <= S_CMD_REPLY_CRC7_END_BIT;
964
                                cmd_counter <= 8'd0;
965
                        end
966
                        else cmd_counter <= cmd_counter + 8'd1;
967
                end
968
                else if(cmd_state == S_CMD_REPLY_CRC7_END_BIT) begin
969
                        cmd_reply <= { cmd_reply[46:0], sd_cmd_io };
970
 
971
                        if(cmd_counter == 8'd7) begin
972
                                cmd_state <= S_CMD_REPLY_FINISH_ONES;
973
                                cmd_counter <= 8'd0;
974
                        end
975
                        else cmd_counter <= cmd_counter + 8'd1;
976
                end
977
                //at least 2 clock cycles required for data write
978
                else if(cmd_state == S_CMD_REPLY_FINISH_ONES) begin
979
                        //check is sd_dat_io busy for CMD7
980
                        if(cmd_counter >= 8'd7 && (control_state != S_CTRL_CMD7 || sd_dat_io == 1'b1)) begin
981
                                clk_cmd_ena <= 1'b0;
982
                                cmd_state <= S_CMD_IDLE;
983
                                cmd_counter <= 8'd0;
984
                        end
985
                        else if(cmd_counter == 8'd255) begin
986
                                cmd_state <= S_CMD_REPLY_ERROR;
987
                                cmd_counter <= 8'd0;
988
                        end
989
                        else cmd_counter <= cmd_counter + 8'd1;
990
                end
991
                else if(cmd_state == S_CMD_REPLY_ERROR) begin
992
                        clk_cmd_ena <= 1'b0;
993
                        cmd_state <= S_CMD_IDLE;
994
                        cmd_counter <= 8'd0;
995
                end
996
        end
997
end
998
 
999
//---------------------------------------------------- SD clock
1000
 
1001
reg [1:0] clk_counter;
1002
 
1003
always @(posedge clk_30 or negedge reset_n) begin
1004
        if(reset_n == 1'b0) begin
1005
                sd_clk_o <= 1'b0;
1006
                clk_counter <= 2'd0;
1007
        end
1008
        else if(clk_counter == 2'd0) begin
1009
                if(clk_master_ena == 1'b1 && (clk_cmd_ena == 1'b1 || clk_data_ena == 1'b1)) begin
1010
                        clk_counter <= clk_counter + 2'd1;
1011
                end
1012
        end
1013
        else if(clk_counter == 2'd1) begin
1014
                sd_clk_o <= 1'b1;
1015
                clk_counter <= clk_counter + 2'd1;
1016
        end
1017
        else if(clk_counter == 2'd2) begin
1018
            clk_counter <= clk_counter + 2'd1;
1019
        end
1020
        else if(clk_counter == 2'd3) begin
1021
                sd_clk_o <= 1'b0;
1022
                clk_counter <= clk_counter + 2'd1;
1023
        end
1024
end
1025
 
1026
endmodule
1027
 

powered by: WebSVN 2.1.0

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