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

Subversion Repositories sd_card_controller

[/] [sd_card_controller/] [trunk/] [rtl/] [verilog/] [sdc_controller.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
//// sdc_controller.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
//// Top level entity.                                            ////
13 8 rozpruwacz
//// This core is based on the "sd card controller" project from  ////
14 3 rozpruwacz
//// http://opencores.org/project,sdcard_mass_storage_controller  ////
15 8 rozpruwacz
//// but has been largely rewritten. A lot of effort has been     ////
16
//// made to make the core more generic and easily usable         ////
17
//// with OSs like Linux.                                         ////
18 3 rozpruwacz
//// - data transfer commands are not fixed                       ////
19
//// - data transfer block size is configurable                   ////
20
//// - multiple block transfer support                            ////
21
//// - R2 responses (136 bit) support                             ////
22
////                                                              ////
23
//// Author(s):                                                   ////
24
////     - Marek Czerski, ma.czerski@gmail.com                    ////
25
////                                                              ////
26
//////////////////////////////////////////////////////////////////////
27
////                                                              ////
28
//// Copyright (C) 2013 Authors                                   ////
29
////                                                              ////
30
//// Based on original work by                                    ////
31
////     Adam Edvardsson (adam.edvardsson@orsoc.se)               ////
32
////                                                              ////
33
////     Copyright (C) 2009 Authors                               ////
34
////                                                              ////
35
//// This source file may be used and distributed without         ////
36
//// restriction provided that this copyright statement is not    ////
37
//// removed from the file and that any derivative work contains  ////
38
//// the original copyright notice and the associated disclaimer. ////
39
////                                                              ////
40
//// This source file is free software; you can redistribute it   ////
41
//// and/or modify it under the terms of the GNU Lesser General   ////
42
//// Public License as published by the Free Software Foundation; ////
43
//// either version 2.1 of the License, or (at your option) any   ////
44
//// later version.                                               ////
45
////                                                              ////
46
//// This source is distributed in the hope that it will be       ////
47
//// useful, but WITHOUT ANY WARRANTY; without even the implied   ////
48
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR      ////
49
//// PURPOSE. See the GNU Lesser General Public License for more  ////
50
//// details.                                                     ////
51
////                                                              ////
52
//// You should have received a copy of the GNU Lesser General    ////
53
//// Public License along with this source; if not, download it   ////
54
//// from http://www.opencores.org/lgpl.shtml                     ////
55
////                                                              ////
56
//////////////////////////////////////////////////////////////////////
57
`include "sd_defines.h"
58
 
59
module sdc_controller(
60
           // WISHBONE common
61
           wb_clk_i,
62
           wb_rst_i,
63
           // WISHBONE slave
64
           wb_dat_i,
65
           wb_dat_o,
66
           wb_adr_i,
67
           wb_sel_i,
68
           wb_we_i,
69
           wb_cyc_i,
70
           wb_stb_i,
71
           wb_ack_o,
72
           // WISHBONE master
73
           m_wb_dat_o,
74
           m_wb_dat_i,
75
           m_wb_adr_o,
76
           m_wb_sel_o,
77
           m_wb_we_o,
78
           m_wb_cyc_o,
79
           m_wb_stb_o,
80
           m_wb_ack_i,
81
           m_wb_cti_o,
82
           m_wb_bte_o,
83
           //SD BUS
84
           sd_cmd_dat_i,
85
           sd_cmd_out_o,
86
           sd_cmd_oe_o,
87
           //card_detect,
88
           sd_dat_dat_i,
89
           sd_dat_out_o,
90
           sd_dat_oe_o,
91
           sd_clk_o_pad,
92
           sd_clk_i_pad,
93
           int_cmd,
94
           int_data
95
       );
96
 
97
input wb_clk_i;
98
input wb_rst_i;
99
input [31:0] wb_dat_i;
100
output [31:0] wb_dat_o;
101
//input card_detect;
102
input [7:0] wb_adr_i;
103
input [3:0] wb_sel_i;
104
input wb_we_i;
105
input wb_cyc_i;
106
input wb_stb_i;
107
output wb_ack_o;
108
output [31:0] m_wb_adr_o;
109
output [3:0] m_wb_sel_o;
110
output m_wb_we_o;
111
input [31:0] m_wb_dat_i;
112
output [31:0] m_wb_dat_o;
113
output m_wb_cyc_o;
114
output m_wb_stb_o;
115
input m_wb_ack_i;
116
output [2:0] m_wb_cti_o;
117
output [1:0] m_wb_bte_o;
118
input wire [3:0] sd_dat_dat_i;
119
output wire [3:0] sd_dat_out_o;
120
output wire sd_dat_oe_o;
121
input wire sd_cmd_dat_i;
122
output wire sd_cmd_out_o;
123
output wire sd_cmd_oe_o;
124
output sd_clk_o_pad;
125
input wire sd_clk_i_pad;
126
output int_cmd, int_data;
127
 
128
//SD clock
129
wire sd_clk_o; //Sd_clk used in the system
130
 
131
wire go_idle;
132
wire cmd_start_wb_clk;
133
wire cmd_start_sd_clk;
134
wire cmd_start;
135
wire [1:0] cmd_setting;
136
wire cmd_start_tx;
137
wire [39:0] cmd;
138
wire [119:0] cmd_response;
139
wire cmd_crc_ok;
140
wire cmd_index_ok;
141
wire cmd_finish;
142
 
143
wire d_write;
144
wire d_read;
145
wire [31:0] data_in_rx_fifo;
146
wire [31:0] data_out_tx_fifo;
147
wire start_tx_fifo;
148
wire start_rx_fifo;
149
wire tx_fifo_empty;
150
wire tx_fifo_full;
151
wire rx_fifo_full;
152
wire sd_data_busy;
153
wire data_busy;
154
wire data_crc_ok;
155
wire rd_fifo;
156
wire we_fifo;
157
 
158
wire data_start_rx;
159
wire data_start_tx;
160
wire cmd_int_rst_wb_clk;
161
wire cmd_int_rst_sd_clk;
162
wire cmd_int_rst;
163
wire data_int_rst_wb_clk;
164
wire data_int_rst_sd_clk;
165
wire data_int_rst;
166
 
167
//wb accessible registers
168
wire [31:0] argument_reg_wb_clk;
169
wire [`CMD_REG_SIZE-1:0] command_reg_wb_clk;
170
wire [15:0] timeout_reg_wb_clk;
171
wire [0:0] software_reset_reg_wb_clk;
172
wire [31:0] response_0_reg_wb_clk;
173
wire [31:0] response_1_reg_wb_clk;
174
wire [31:0] response_2_reg_wb_clk;
175
wire [31:0] response_3_reg_wb_clk;
176
wire [`BLKSIZE_W-1:0] block_size_reg_wb_clk;
177
wire [15:0] controll_setting_reg_wb_clk;
178
wire [`INT_CMD_SIZE-1:0] cmd_int_status_reg_wb_clk;
179
wire [`INT_DATA_SIZE-1:0] data_int_status_reg_wb_clk;
180
wire [`INT_CMD_SIZE-1:0] cmd_int_enable_reg_wb_clk;
181
wire [`INT_DATA_SIZE-1:0] data_int_enable_reg_wb_clk;
182
wire [`BLKCNT_W-1:0] block_count_reg_wb_clk;
183
wire [31:0] dma_addr_reg_wb_clk;
184
wire [7:0] clock_divider_reg_wb_clk;
185
 
186
wire [31:0] argument_reg_sd_clk;
187
wire [`CMD_REG_SIZE-1:0] command_reg_sd_clk;
188
wire [15:0] timeout_reg_sd_clk;
189
wire [0:0] software_reset_reg_sd_clk;
190
wire [31:0] response_0_reg_sd_clk;
191
wire [31:0] response_1_reg_sd_clk;
192
wire [31:0] response_2_reg_sd_clk;
193
wire [31:0] response_3_reg_sd_clk;
194
wire [`BLKSIZE_W-1:0] block_size_reg_sd_clk;
195
wire [15:0] controll_setting_reg_sd_clk;
196
wire [`INT_CMD_SIZE-1:0] cmd_int_status_reg_sd_clk;
197
wire [2:0] data_int_status_reg_sd_clk;
198
wire [`INT_CMD_SIZE-1:0] cmd_int_enable_reg_sd_clk;
199
wire [2:0] data_int_enable_reg_sd_clk;
200
wire [`BLKCNT_W-1:0] block_count_reg_sd_clk;
201
wire [31:0] dma_addr_reg_sd_clk;
202
wire [7:0] clock_divider_reg_sd_clk;
203
 
204
sd_clock_divider clock_divider0(
205
                     .CLK (sd_clk_i_pad),
206
                     .DIVIDER (clock_divider_reg_sd_clk),
207
                     .RST  (wb_rst_i),
208
                     .SD_CLK  (sd_clk_o)
209
                 );
210
 
211
assign sd_clk_o_pad  = sd_clk_o ;
212
 
213
sd_cmd_master sd_cmd_master0(
214
           .sd_clk       (sd_clk_o),
215
           .rst          (wb_rst_i | software_reset_reg_sd_clk[0]),
216
           .start_i      (cmd_start_sd_clk),
217
           .int_status_rst_i(cmd_int_rst_sd_clk),
218
           .setting_o    (cmd_setting),
219
           .start_xfr_o  (cmd_start_tx),
220
           .go_idle_o    (go_idle),
221
           .cmd_o        (cmd),
222
           .response_i   (cmd_response),
223
           .crc_ok_i     (cmd_crc_ok),
224
           .index_ok_i   (cmd_index_ok),
225
           .busy_i       (sd_data_busy),
226
           .finish_i     (cmd_finish),
227
           //input card_detect,
228
           .argument_i   (argument_reg_sd_clk),
229
           .command_i    (command_reg_sd_clk),
230
           .timeout_i    (timeout_reg_sd_clk),
231
           .int_status_o (cmd_int_status_reg_sd_clk),
232
           .response_0_o (response_0_reg_sd_clk),
233
           .response_1_o (response_1_reg_sd_clk),
234
           .response_2_o (response_2_reg_sd_clk),
235
           .response_3_o (response_3_reg_sd_clk)
236
       );
237
 
238
sd_cmd_serial_host cmd_serial_host0(
239
                       .sd_clk     (sd_clk_o),
240
                       .rst        (wb_rst_i | software_reset_reg_sd_clk[0] | go_idle),
241
                       .setting_i  (cmd_setting),
242
                       .cmd_i      (cmd),
243
                       .start_i    (cmd_start_tx),
244
                       .finish_o   (cmd_finish),
245
                       .response_o (cmd_response),
246
                       .crc_ok_o   (cmd_crc_ok),
247
                       .index_ok_o (cmd_index_ok),
248
                       .cmd_dat_i  (sd_cmd_dat_i),
249
                       .cmd_out_o  (sd_cmd_out_o),
250
                       .cmd_oe_o   (sd_cmd_oe_o)
251
                   );
252
 
253
sd_data_master sd_data_master0(
254
           .sd_clk           (sd_clk_o),
255
           .rst              (wb_rst_i | software_reset_reg_sd_clk[0]),
256
           .start_tx_i       (data_start_tx),
257
           .start_rx_i       (data_start_rx),
258
           .d_write_o        (d_write),
259
           .d_read_o         (d_read),
260
           .start_tx_fifo_o  (start_tx_fifo),
261
           .start_rx_fifo_o  (start_rx_fifo),
262
           .tx_fifo_empty_i  (tx_fifo_empty),
263
           .tx_fifo_full_i   (tx_fifo_full),
264
           .rx_fifo_full_i   (rx_fifo_full),
265
           .xfr_complete_i   (!data_busy),
266
           .crc_ok_i         (data_crc_ok),
267
           .int_status_o     (data_int_status_reg_sd_clk),
268
           .int_status_rst_i (data_int_rst_sd_clk)
269
       );
270
 
271
sd_data_serial_host sd_data_serial_host0(
272
                        .sd_clk         (sd_clk_o),
273
                        .rst            (wb_rst_i | software_reset_reg_sd_clk[0]),
274
                        .data_in        (data_out_tx_fifo),
275
                        .rd             (rd_fifo),
276
                        .data_out       (data_in_rx_fifo),
277
                        .we             (we_fifo),
278
                        .DAT_oe_o       (sd_dat_oe_o),
279
                        .DAT_dat_o      (sd_dat_out_o),
280
                        .DAT_dat_i      (sd_dat_dat_i),
281
                        .blksize        (block_size_reg_sd_clk),
282
                        .bus_4bit       (controll_setting_reg_sd_clk[0]),
283
                        .blkcnt         (block_count_reg_sd_clk),
284
                        .start          ({d_read, d_write}),
285
                        .sd_data_busy   (sd_data_busy),
286
                        .busy           (data_busy),
287
                        .crc_ok         (data_crc_ok)
288
                    );
289
 
290
sd_fifo_filler sd_fifo_filler0(
291
            .wb_clk    (wb_clk_i),
292
            .rst       (wb_rst_i | software_reset_reg_sd_clk[0]),
293
            .wbm_adr_o (m_wb_adr_o),
294
            .wbm_we_o  (m_wb_we_o),
295
            .wbm_dat_o (m_wb_dat_o),
296
            .wbm_dat_i (m_wb_dat_i),
297
            .wbm_cyc_o (m_wb_cyc_o),
298
            .wbm_stb_o (m_wb_stb_o),
299
            .wbm_ack_i (m_wb_ack_i),
300
            .en_rx_i   (start_rx_fifo),
301
            .en_tx_i   (start_tx_fifo),
302
            .adr_i     (dma_addr_reg_sd_clk),
303
            .sd_clk    (sd_clk_o),
304
            .dat_i     (data_in_rx_fifo),
305
            .dat_o     (data_out_tx_fifo),
306
            .wr_i      (we_fifo),
307
            .rd_i      (rd_fifo),
308
            .sd_empty_o   (tx_fifo_empty),
309
            .sd_full_o   (rx_fifo_full),
310
            .wb_empty_o   (),
311
            .wb_full_o    (tx_fifo_full)
312
        );
313
 
314
sd_data_xfer_trig sd_data_xfer_trig0 (
315
           .sd_clk                (sd_clk_o),
316
           .rst                   (wb_rst_i | software_reset_reg_sd_clk[0]),
317
           .cmd_with_data_start_i (cmd_start_sd_clk & (command_reg_sd_clk[`CMD_WITH_DATA] != 2'b00)),
318
           .r_w_i                 (command_reg_sd_clk[`CMD_WITH_DATA] == 2'b01),
319
           .cmd_int_status_i      (cmd_int_status_reg_sd_clk),
320
           .start_tx_o            (data_start_tx),
321
           .start_rx_o            (data_start_rx)
322
       );
323
 
324
sd_controller_wb sd_controller_wb0(
325
                     .wb_clk_i                       (wb_clk_i),
326
                     .wb_rst_i                       (wb_rst_i),
327
                     .wb_dat_i                       (wb_dat_i),
328
                     .wb_dat_o                       (wb_dat_o),
329
                     .wb_adr_i                       (wb_adr_i),
330
                     .wb_sel_i                       (wb_sel_i),
331
                     .wb_we_i                        (wb_we_i),
332
                     .wb_stb_i                       (wb_stb_i),
333
                     .wb_cyc_i                       (wb_cyc_i),
334
                     .wb_ack_o                       (wb_ack_o),
335
                     .cmd_start                      (cmd_start),
336
                     .data_int_rst                   (data_int_rst),
337
                     .cmd_int_rst                    (cmd_int_rst),
338
                     .argument_reg                   (argument_reg_wb_clk),
339
                     .command_reg                    (command_reg_wb_clk),
340
                     .response_0_reg                 (response_0_reg_wb_clk),
341
                     .response_1_reg                 (response_1_reg_wb_clk),
342
                     .response_2_reg                 (response_2_reg_wb_clk),
343
                     .response_3_reg                 (response_3_reg_wb_clk),
344
                     .software_reset_reg             (software_reset_reg_wb_clk),
345
                     .timeout_reg                    (timeout_reg_wb_clk),
346
                     .block_size_reg                 (block_size_reg_wb_clk),
347
                     .controll_setting_reg           (controll_setting_reg_wb_clk),
348
                     .cmd_int_status_reg             (cmd_int_status_reg_wb_clk),
349
                     .cmd_int_enable_reg             (cmd_int_enable_reg_wb_clk),
350
                     .clock_divider_reg              (clock_divider_reg_wb_clk),
351
                     .block_count_reg                (block_count_reg_wb_clk),
352
                     .dma_addr_reg                   (dma_addr_reg_wb_clk),
353
                     .data_int_status_reg            (data_int_status_reg_wb_clk),
354
                     .data_int_enable_reg            (data_int_enable_reg_wb_clk)
355
                 );
356
 
357
//clock domain crossing regiters
358
//assign cmd_start_sd_clk = cmd_start_wb_clk;
359
//assign data_int_rst_sd_clk = data_int_rst_wb_clk;
360
//assign cmd_int_rst_sd_clk = cmd_int_rst_wb_clk;
361
//assign argument_reg_sd_clk = argument_reg_wb_clk;
362
//assign command_reg_sd_clk = command_reg_wb_clk;
363
//assign response_0_reg_wb_clk = response_0_reg_sd_clk;
364
//assign response_1_reg_wb_clk = response_1_reg_sd_clk;
365
//assign response_2_reg_wb_clk = response_2_reg_sd_clk;
366
//assign response_3_reg_wb_clk = response_3_reg_sd_clk;
367
//assign software_reset_reg_sd_clk = software_reset_reg_wb_clk;
368
//assign timeout_reg_sd_clk = timeout_reg_wb_clk;
369
//assign block_size_reg_sd_clk = block_size_reg_wb_clk;
370
//assign controll_setting_reg_sd_clk = controll_setting_reg_wb_clk;
371
//assign cmd_int_status_reg_wb_clk = cmd_int_status_reg_sd_clk;
372
//assign cmd_int_enable_reg_sd_clk = cmd_int_enable_reg_wb_clk;
373
//assign clock_divider_reg_sd_clk = clock_divider_reg_wb_clk;
374
//assign block_count_reg_sd_clk = block_count_reg_wb_clk;
375
//assign dma_addr_reg_sd_clk = dma_addr_reg_wb_clk;
376
//assign data_int_status_reg_wb_clk = data_int_status_reg_sd_clk;
377
//assign data_int_enable_reg_sd_clk = data_int_enable_reg_wb_clk;
378
 
379
edge_detect cmd_start_edge(.rst(wb_rst_i), .clk(wb_clk_i), .sig(cmd_start), .rise(cmd_start_wb_clk), .fall());
380
edge_detect data_int_rst_edge(.rst(wb_rst_i), .clk(wb_clk_i), .sig(data_int_rst), .rise(data_int_rst_wb_clk), .fall());
381
edge_detect cmd_int_rst_edge(.rst(wb_rst_i), .clk(wb_clk_i), .sig(cmd_int_rst), .rise(cmd_int_rst_wb_clk), .fall());
382
monostable_domain_cross cmd_start_cross(wb_rst_i, wb_clk_i, cmd_start_wb_clk, sd_clk_o, cmd_start_sd_clk);
383
monostable_domain_cross data_int_rst_cross(wb_rst_i, wb_clk_i, data_int_rst_wb_clk, sd_clk_o, data_int_rst_sd_clk);
384
monostable_domain_cross cmd_int_rst_cross(wb_rst_i, wb_clk_i, cmd_int_rst_wb_clk, sd_clk_o, cmd_int_rst_sd_clk);
385
bistable_domain_cross #(32) argument_reg_cross(wb_rst_i, wb_clk_i, argument_reg_wb_clk, sd_clk_o, argument_reg_sd_clk);
386
bistable_domain_cross #(`CMD_REG_SIZE) command_reg_cross(wb_rst_i, wb_clk_i, command_reg_wb_clk, sd_clk_o, command_reg_sd_clk);
387
bistable_domain_cross #(32) response_0_reg_cross(wb_rst_i, sd_clk_o, response_0_reg_sd_clk, wb_clk_i, response_0_reg_wb_clk);
388
bistable_domain_cross #(32) response_1_reg_cross(wb_rst_i, sd_clk_o, response_1_reg_sd_clk, wb_clk_i, response_1_reg_wb_clk);
389
bistable_domain_cross #(32) response_2_reg_cross(wb_rst_i, sd_clk_o, response_2_reg_sd_clk, wb_clk_i, response_2_reg_wb_clk);
390
bistable_domain_cross #(32) response_3_reg_cross(wb_rst_i, sd_clk_o, response_3_reg_sd_clk, wb_clk_i, response_3_reg_wb_clk);
391
bistable_domain_cross software_reset_reg_cross(wb_rst_i, wb_clk_i, software_reset_reg_wb_clk, sd_clk_o, software_reset_reg_sd_clk);
392
bistable_domain_cross #(16) timeout_reg_cross(wb_rst_i, wb_clk_i, timeout_reg_wb_clk, sd_clk_o, timeout_reg_sd_clk);
393
bistable_domain_cross #(`BLKSIZE_W) block_size_reg_cross(wb_rst_i, wb_clk_i, block_size_reg_wb_clk, sd_clk_o, block_size_reg_sd_clk);
394
bistable_domain_cross #(16) controll_setting_reg_cross(wb_rst_i, wb_clk_i, controll_setting_reg_wb_clk, sd_clk_o, controll_setting_reg_sd_clk);
395
bistable_domain_cross #(`INT_CMD_SIZE) cmd_int_status_reg_cross(wb_rst_i, sd_clk_o, cmd_int_status_reg_sd_clk, wb_clk_i, cmd_int_status_reg_wb_clk);
396
bistable_domain_cross #(`INT_CMD_SIZE) cmd_int_enable_reg_cross(wb_rst_i, wb_clk_i, cmd_int_enable_reg_wb_clk, sd_clk_o, cmd_int_enable_reg_sd_clk);
397
bistable_domain_cross #(8) clock_divider_reg_cross(wb_rst_i, wb_clk_i, clock_divider_reg_wb_clk, sd_clk_i_pad, clock_divider_reg_sd_clk);
398
bistable_domain_cross #(`BLKCNT_W) block_count_reg_cross(wb_rst_i, wb_clk_i, block_count_reg_wb_clk, sd_clk_o, block_count_reg_sd_clk);
399
bistable_domain_cross #(32) dma_addr_reg_cross(wb_rst_i, wb_clk_i, dma_addr_reg_wb_clk, sd_clk_o, dma_addr_reg_sd_clk);
400
bistable_domain_cross #(`INT_DATA_SIZE) data_int_status_reg_cross(wb_rst_i, sd_clk_o, data_int_status_reg_sd_clk, wb_clk_i, data_int_status_reg_wb_clk);
401
bistable_domain_cross #(`INT_DATA_SIZE) data_int_enable_reg_cross(wb_rst_i, wb_clk_i, data_int_enable_reg_wb_clk, sd_clk_o, data_int_enable_reg_sd_clk);
402
 
403
assign m_wb_cti_o = 3'b000;
404
assign m_wb_bte_o = 2'b00;
405
 
406
assign int_cmd =  |(cmd_int_status_reg_wb_clk & cmd_int_enable_reg_wb_clk);
407
assign int_data =  |(data_int_status_reg_wb_clk & data_int_enable_reg_wb_clk);
408
 
409
assign m_wb_sel_o = 4'b1111;
410
 
411
endmodule

powered by: WebSVN 2.1.0

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