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

Subversion Repositories sd_card_controller

[/] [sd_card_controller/] [trunk/] [rtl/] [verilog/] [sd_cmd_serial_host.v] - Blame information for rev 8

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 3 rozpruwacz
//////////////////////////////////////////////////////////////////////
2
////                                                              ////
3
//// WISHBONE SD Card Controller IP Core                          ////
4
////                                                              ////
5
//// sd_cmd_serial_host.v                                         ////
6
////                                                              ////
7
//// This file is part of the WISHBONE SD Card                    ////
8
//// Controller IP Core project                                   ////
9 8 rozpruwacz
//// http://opencores.org/project,sd_card_controller              ////
10 3 rozpruwacz
////                                                              ////
11
//// Description                                                  ////
12
//// Module resposible for sending and receiving commands         ////
13
//// through 1-bit sd card command interface                      ////
14
////                                                              ////
15
//// Author(s):                                                   ////
16
////     - Marek Czerski, ma.czerski@gmail.com                    ////
17
////                                                              ////
18
//////////////////////////////////////////////////////////////////////
19
////                                                              ////
20
//// Copyright (C) 2013 Authors                                   ////
21
////                                                              ////
22
//// Based on original work by                                    ////
23
////     Adam Edvardsson (adam.edvardsson@orsoc.se)               ////
24
////                                                              ////
25
////     Copyright (C) 2009 Authors                               ////
26
////                                                              ////
27
//// This source file may be used and distributed without         ////
28
//// restriction provided that this copyright statement is not    ////
29
//// removed from the file and that any derivative work contains  ////
30
//// the original copyright notice and the associated disclaimer. ////
31
////                                                              ////
32
//// This source file is free software; you can redistribute it   ////
33
//// and/or modify it under the terms of the GNU Lesser General   ////
34
//// Public License as published by the Free Software Foundation; ////
35
//// either version 2.1 of the License, or (at your option) any   ////
36
//// later version.                                               ////
37
////                                                              ////
38
//// This source is distributed in the hope that it will be       ////
39
//// useful, but WITHOUT ANY WARRANTY; without even the implied   ////
40
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR      ////
41
//// PURPOSE. See the GNU Lesser General Public License for more  ////
42
//// details.                                                     ////
43
////                                                              ////
44
//// You should have received a copy of the GNU Lesser General    ////
45
//// Public License along with this source; if not, download it   ////
46
//// from http://www.opencores.org/lgpl.shtml                     ////
47
////                                                              ////
48
//////////////////////////////////////////////////////////////////////
49
 
50
module sd_cmd_serial_host (
51
           sd_clk,
52
           rst,
53
           setting_i,
54
           cmd_i,
55
           start_i,
56
           response_o,
57
           crc_ok_o,
58
           index_ok_o,
59
           finish_o,
60
           cmd_dat_i,
61
           cmd_out_o,
62
           cmd_oe_o
63
       );
64
 
65
//---------------Input ports---------------
66
input sd_clk;
67
input rst;
68
input [1:0] setting_i;
69
input [39:0] cmd_i;
70
input start_i;
71
input cmd_dat_i;
72
//---------------Output ports---------------
73
output reg [119:0] response_o;
74
output reg finish_o;
75
output reg crc_ok_o;
76
output reg index_ok_o;
77
output reg cmd_oe_o;
78
output reg cmd_out_o;
79
 
80
//-------------Internal Constant-------------
81
parameter INIT_DELAY = 4;
82
parameter BITS_TO_SEND = 48;
83
parameter CMD_SIZE = 40;
84
parameter RESP_SIZE = 128;
85
 
86
//---------------Internal variable-----------
87
reg cmd_dat_reg;
88
integer resp_len;
89
reg with_response;
90
reg [CMD_SIZE-1:0] cmd_buff;
91
reg [RESP_SIZE-1:0] resp_buff;
92
integer resp_idx;
93
//CRC
94
reg crc_rst;
95
reg [6:0]crc_in;
96
wire [6:0] crc_val;
97
reg crc_enable;
98
reg crc_bit;
99
reg crc_ok;
100
//-Internal Counterns
101
integer counter;
102
//-State Machine
103
parameter STATE_SIZE = 10;
104
parameter
105
    INIT = 7'h00,
106
    IDLE = 7'h01,
107
    SETUP_CRC = 7'h02,
108
    WRITE = 7'h04,
109
    READ_WAIT = 7'h08,
110
    READ = 7'h10,
111
    FINISH_WR = 7'h20,
112
    FINISH_WO = 7'h40;
113
reg [STATE_SIZE-1:0] state;
114
reg [STATE_SIZE-1:0] next_state;
115
//Misc
116
`define cmd_idx  (CMD_SIZE-1-counter)
117
 
118
//sd cmd input pad register
119
always @(posedge sd_clk)
120
    cmd_dat_reg <= cmd_dat_i;
121
 
122
//------------------------------------------
123
sd_crc_7 CRC_7(
124
             crc_bit,
125
             crc_enable,
126
             sd_clk,
127
             crc_rst,
128
             crc_val);
129
 
130
//------------------------------------------
131
always @(state or counter or start_i or with_response or cmd_dat_reg or resp_len)
132
begin: FSM_COMBO
133
    case(state)
134
        INIT: begin
135
            if (counter >= INIT_DELAY) begin
136
                next_state <= IDLE;
137
            end
138
            else begin
139
                next_state <= INIT;
140
            end
141
        end
142
        IDLE: begin
143
            if (start_i) begin
144
                next_state <= SETUP_CRC;
145
            end
146
            else begin
147
                next_state <= IDLE;
148
            end
149
        end
150
        SETUP_CRC:
151
            next_state <= WRITE;
152
        WRITE:
153
            if (counter >= BITS_TO_SEND && with_response) begin
154
                next_state <= READ_WAIT;
155
            end
156
            else if (counter >= BITS_TO_SEND) begin
157
                next_state <= FINISH_WO;
158
            end
159
            else begin
160
                next_state <= WRITE;
161
            end
162
        READ_WAIT:
163
            if (!cmd_dat_reg) begin
164
                next_state <= READ;
165
            end
166
            else begin
167
                next_state <= READ_WAIT;
168
            end
169
        FINISH_WO:
170
            next_state <= IDLE;
171
        READ:
172
            if (counter >= resp_len+8) begin
173
                next_state <= FINISH_WR;
174
            end
175
            else begin
176
                next_state <= READ;
177
            end
178
        FINISH_WR:
179
            next_state <= IDLE;
180
        default:
181
            next_state <= INIT;
182
    endcase
183
end
184
 
185
always @(posedge sd_clk or posedge rst)
186
begin: COMMAND_DECODER
187
    if (rst) begin
188
        resp_len <= 0;
189
        with_response <= 0;
190
        cmd_buff <= 0;
191
    end
192
    else begin
193
        if (start_i == 1) begin
194
            resp_len <= setting_i[1] ? 127 : 39;
195
            with_response <= setting_i[0];
196
            cmd_buff <= cmd_i;
197
        end
198
    end
199
end
200
 
201
//----------------Seq logic------------
202
always @(posedge sd_clk or posedge rst)
203
begin: FSM_SEQ
204
    if (rst) begin
205
        state <= INIT;
206
    end
207
    else begin
208
        state <= next_state;
209
    end
210
end
211
 
212
//-------------OUTPUT_LOGIC-------
213
always @(posedge sd_clk or posedge rst)
214
begin: FSM_OUT
215
    if (rst) begin
216
        crc_enable <= 0;
217
        resp_idx <= 0;
218
        cmd_oe_o <= 1;
219
        cmd_out_o <= 1;
220
        resp_buff <= 0;
221
        finish_o <= 0;
222
        crc_rst <= 1;
223
        crc_bit <= 0;
224
        crc_in <= 0;
225
        response_o <= 0;
226
        index_ok_o <= 0;
227
        crc_ok_o <= 0;
228
        crc_ok <= 0;
229
        counter <= 0;
230
    end
231
    else begin
232
        case(state)
233
            INIT: begin
234
                counter <= counter+1;
235
                cmd_oe_o <= 1;
236
                cmd_out_o <= 1;
237
            end
238
            IDLE: begin
239
                cmd_oe_o <= 0;      //Put CMD to Z
240
                counter <= 0;
241
                crc_rst <= 1;
242
                crc_enable <= 0;
243
                response_o <= 0;
244
                resp_idx <= 0;
245
                crc_ok_o <= 0;
246
                index_ok_o <= 0;
247
                finish_o <= 0;
248
            end
249
            SETUP_CRC: begin
250
                crc_rst <= 0;
251
                crc_enable <= 1;
252
                crc_bit <= cmd_buff[`cmd_idx];
253
            end
254
            WRITE: begin
255
                if (counter < BITS_TO_SEND-8) begin  // 1->40 CMD, (41 >= CNT && CNT <=47) CRC, 48 stop_bit
256
                    cmd_oe_o <= 1;
257
                    cmd_out_o <= cmd_buff[`cmd_idx];
258
                    if (counter < BITS_TO_SEND-9) begin //1 step ahead
259
                        crc_bit <= cmd_buff[`cmd_idx-1];
260
                    end else begin
261
                        crc_enable <= 0;
262
                    end
263
                end
264
                else if (counter < BITS_TO_SEND-1) begin
265
                    cmd_oe_o <= 1;
266
                    crc_enable <= 0;
267
                    cmd_out_o <= crc_val[BITS_TO_SEND-counter-2];
268
                end
269
                else if (counter == BITS_TO_SEND-1) begin
270
                    cmd_oe_o <= 1;
271
                    cmd_out_o <= 1'b1;
272
                end
273
                else begin
274
                    cmd_oe_o <= 0;
275
                    cmd_out_o <= 1'b1;
276
                end
277
                counter <= counter+1;
278
            end
279
            READ_WAIT: begin
280
                crc_enable <= 0;
281
                crc_rst <= 1;
282
                counter <= 1;
283
                cmd_oe_o <= 0;
284
                resp_buff[RESP_SIZE-1] <= cmd_dat_reg;
285
            end
286
            FINISH_WO: begin
287
                finish_o <= 1;
288
                crc_enable <= 0;
289
                crc_rst <= 1;
290
                counter <= 0;
291
                cmd_oe_o <= 0;
292
            end
293
            READ: begin
294
                crc_rst <= 0;
295
                crc_enable <= (resp_len != RESP_SIZE-1 || counter > 7);
296
                cmd_oe_o <= 0;
297
                if (counter <= resp_len) begin
298
                    if (counter < 8) //1+1+6 (S,T,Index)
299
                        resp_buff[RESP_SIZE-1-counter] <= cmd_dat_reg;
300
                    else begin
301
                        resp_idx <= resp_idx + 1;
302
                        resp_buff[RESP_SIZE-9-resp_idx] <= cmd_dat_reg;
303
                    end
304
                    crc_bit <= cmd_dat_reg;
305
                end
306
                else if (counter-resp_len <= 7) begin
307
                    crc_in[(resp_len+7)-(counter)] <= cmd_dat_reg;
308
                    crc_enable <= 0;
309
                end
310
                else begin
311
                    crc_enable <= 0;
312
                    if (crc_in == crc_val) crc_ok <= 1;
313
                    else crc_ok <= 0;
314
                end
315
                counter <= counter + 1;
316
            end
317
            FINISH_WR: begin
318
                if (cmd_buff[37:32] == resp_buff[125:120])
319
                    index_ok_o <= 1;
320
                else
321
                    index_ok_o <= 0;
322
                crc_ok_o <= crc_ok;
323
                finish_o <= 1;
324
                crc_enable <= 0;
325
                crc_rst <= 1;
326
                counter <= 0;
327
                cmd_oe_o <= 0;
328
                response_o <= resp_buff[119:0];
329
            end
330
        endcase
331
    end
332
end
333
 
334
endmodule
335
 
336
 

powered by: WebSVN 2.1.0

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