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

Subversion Repositories ao68000

[/] [ao68000/] [trunk/] [tests/] [soc_for_linux_on_terasic_de2_70/] [verilog/] [sd.v] - Blame information for rev 12

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

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