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

Subversion Repositories ao486

[/] [ao486/] [trunk/] [rtl/] [soc/] [driver_sd/] [card_init.v] - Blame information for rev 8

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 8 alfik
/*
2
 * This file is subject to the terms and conditions of the BSD License. See
3
 * the file "LICENSE" in the main directory of this archive for more details.
4
 *
5
 * Copyright (C) 2014 Aleksander Osman
6
 */
7
 
8
module card_init(
9
    input               clk,
10
    input               rst_n,
11
 
12
    //
13
    input               operation_init,
14
    output              operation_finished_ok,
15
    output              operation_finished_with_error,
16
 
17
    //
18
    output              cmd_ready,
19
    output      [5:0]   cmd_index,
20
    output      [31:0]  cmd_arg,
21
    output      [7:0]   cmd_resp_length,
22
    output              cmd_resp_has_crc7,
23
 
24
    input               reply_ready,
25
    input       [135:0] reply_contents,
26
    input               reply_error,
27
 
28
    //
29
    input               current_dat0
30
);
31
 
32
//------------------------------------------------------------------------------
33
 
34
reg [23:0] initial_delay;
35
always @(posedge clk or negedge rst_n) begin
36
    if(rst_n == 1'b0)                   initial_delay <= 24'd0;
37
    else if(initial_delay[23] == 1'b0)  initial_delay <= initial_delay + 24'd1;
38
end
39
 
40
assign operation_finished_with_error =
41
    (reply_error && (state == S_CMD0 || state == S_CMD8 || state == S_CMD55_FOR_41 || state == S_ACMD41 || state == S_CMD2 || state == S_CMD3 || state == S_CMD7 || state == S_CMD55_FOR_6 || state == S_ACMD6)) ||
42
    (state == S_CMD0         && reply_ready && ~(valid_cmd0))  ||
43
    (state == S_CMD8         && reply_ready && ~(valid_cmd8))  ||
44
    (state == S_CMD55_FOR_41 && reply_ready && ~(valid_cmd55)) ||
45
    (state == S_ACMD41       && reply_ready && ~(valid_acmd41) && ~(valid_acmd41_but_busy)) ||
46
    (state == S_CMD2         && reply_ready && ~(valid_cmd2)) ||
47
    (state == S_CMD3         && reply_ready && ~(valid_cmd3)) ||
48
    (state == S_CMD7         && reply_ready && ~(valid_cmd7) && ~(valid_cmd7_but_busy)) ||
49
    (state == S_CMD55_FOR_6  && reply_ready && ~(valid_cmd55)) ||
50
    (state == S_ACMD6        && reply_ready && ~(valid_acmd6));
51
 
52
assign operation_finished_ok = state == S_ACMD6 && reply_ready && valid_acmd6;
53
 
54
//------------------------------------------------------------------------------
55
 
56
wire prepare_cmd0           = state == S_IDLE && initial_delay[23] && operation_init;
57
wire valid_cmd0             = 1'b1; //always valid
58
 
59
wire prepare_cmd8           = state == S_CMD0 && reply_ready && valid_cmd0;
60
wire valid_cmd8             = reply_contents[45:40] == 6'd8 && reply_contents[19:16] == 4'b0001 && reply_contents[15:8] == 8'b11010010; //command index; accepted volage 2.7-3.6 V; check pattern echo
61
 
62
wire prepare_cmd55_for_41   = (state == S_CMD8 && reply_ready && valid_cmd8) || repeat_acmd41;
63
wire valid_cmd55            = reply_contents[45:40] == 6'd55 && reply_contents[39:27] == 13'd0 && reply_contents[24:21] == 4'b0; //command index; R1[31:19] no errors; R1[16:13] no errors
64
 
65
wire prepare_acmd41         = state == S_CMD55_FOR_41 && reply_ready && valid_cmd55;
66
wire valid_acmd41           = reply_contents[39:38] == 2'b11;                            //initialization complete and SDHC or SDXC;
67
wire valid_acmd41_but_busy  = reply_contents[39] == 1'b0 && acmd41_busy_cnt < 20'hFFFFF; //initialization not complete
68
wire repeat_acmd41          = state == S_ACMD41 && reply_ready && valid_acmd41_but_busy;
69
 
70
wire prepare_cmd2           = state == S_ACMD41 && reply_ready && valid_acmd41;
71
wire valid_cmd2             = 1'b1; //always valid
72
 
73
wire prepare_cmd3           = state == S_CMD2 && reply_ready && valid_cmd2;
74
wire valid_cmd3             = reply_contents[45:40] == 6'd3 && reply_contents[23:21] == 3'b0; //command index; R1[23,22,19] no errors
75
wire [15:0] cmd3_new_rca    = reply_contents[39:24];
76
 
77
wire prepare_cmd7           = state == S_CMD3 && reply_ready && valid_cmd3;
78
wire valid_cmd7_common      = reply_contents[45:40] == 6'd7 && reply_contents[39:27] == 13'd0 && reply_contents[24:21] == 4'b0; //command index; R1[31:19] no errors; R1[16:13] no errors
79
wire valid_cmd7             = valid_cmd7_common && current_dat0;
80
wire valid_cmd7_but_busy    = valid_cmd7_common && ~(current_dat0);
81
 
82
wire prepare_cmd55_for_6    = (state == S_CMD7 && reply_ready && valid_cmd7) || (state == S_WAIT_DAT0 && current_dat0);
83
 
84
wire prepare_acmd6          = state == S_CMD55_FOR_6 && reply_ready && valid_cmd55;
85
wire valid_acmd6            = reply_contents[45:40] == 6'd6 && reply_contents[39:27] == 13'd0 && reply_contents[24:21] == 4'b0; //command index; R1[31:19] no errors; R1[16:13] no errors
86
 
87
//------------------------------------------------------------------------------
88
 
89
reg [19:0] acmd41_busy_cnt;
90
always @(posedge clk or negedge rst_n) begin
91
    if(rst_n == 1'b0)       acmd41_busy_cnt <= 20'd0;
92
    else if(prepare_cmd0)   acmd41_busy_cnt <= 20'd0;
93
    else if(repeat_acmd41)  acmd41_busy_cnt <= acmd41_busy_cnt + 20'd1;
94
end
95
 
96
reg [15:0] rca;
97
always @(posedge clk or negedge rst_n) begin
98
    if(rst_n == 1'b0)       rca <= 16'd0;
99
    else if(prepare_cmd7)   rca <= cmd3_new_rca;
100
end
101
 
102
//------------------------------------------------------------------------------
103
 
104
localparam [3:0] S_IDLE         = 4'd0;
105
localparam [3:0] S_CMD0         = 4'd1;
106
localparam [3:0] S_CMD8         = 4'd2;
107
localparam [3:0] S_CMD55_FOR_41 = 4'd3;
108
localparam [3:0] S_ACMD41       = 4'd4;
109
localparam [3:0] S_CMD2         = 4'd5;
110
localparam [3:0] S_CMD3         = 4'd6;
111
localparam [3:0] S_CMD7         = 4'd7;
112
localparam [3:0] S_WAIT_DAT0    = 4'd8;
113
localparam [3:0] S_CMD55_FOR_6  = 4'd9;
114
localparam [3:0] S_ACMD6        = 4'd10;
115
 
116
reg [3:0] state;
117
always @(posedge clk or negedge rst_n) begin
118
    if(rst_n == 1'b0)                                               state <= S_IDLE;
119
 
120
    else if(operation_finished_with_error)                          state <= S_IDLE;
121
 
122
    else if(prepare_cmd0)                                           state <= S_CMD0;
123
    else if(prepare_cmd8)                                           state <= S_CMD8;
124
    else if(prepare_cmd55_for_41)                                   state <= S_CMD55_FOR_41;
125
    else if(prepare_acmd41)                                         state <= S_ACMD41;
126
    else if(repeat_acmd41)                                          state <= S_CMD55_FOR_41;
127
    else if(prepare_cmd2)                                           state <= S_CMD2;
128
    else if(prepare_cmd3)                                           state <= S_CMD3;
129
    else if(prepare_cmd7)                                           state <= S_CMD7;
130
    else if(state == S_CMD7 && reply_ready && valid_cmd7_but_busy)  state <= S_WAIT_DAT0;
131
    else if(prepare_cmd55_for_6)                                    state <= S_CMD55_FOR_6;
132
    else if(prepare_acmd6)                                          state <= S_ACMD6;
133
 
134
    else if(operation_finished_ok)                                  state <= S_IDLE;
135
end
136
 
137
//------------------------------------------------------------------------------
138
 
139
assign cmd_ready = prepare_cmd0 || prepare_cmd8 || prepare_cmd55_for_41 || prepare_acmd41 || prepare_cmd2 || prepare_cmd3 || prepare_cmd7 || prepare_cmd55_for_6 || prepare_acmd6;
140
 
141
assign cmd_index =
142
    (prepare_cmd0)?         6'd0 :
143
    (prepare_cmd8)?         6'd8 :
144
    (prepare_cmd55_for_41)? 6'd55 :
145
    (prepare_acmd41)?       6'd41 :
146
    (prepare_cmd2)?         6'd2 :
147
    (prepare_cmd3)?         6'd3 :
148
    (prepare_cmd7)?         6'd7 :
149
    (prepare_cmd55_for_6)?  6'd55 :
150
    (prepare_acmd6)?        6'd6 :
151
                            6'd0;
152
 
153
assign cmd_arg =
154
    (prepare_cmd0)?         32'd0 :             //stuff bits
155
 
156
    (prepare_cmd8)?         { 20'b0,            //reserved
157
                              4'b0001,          //VHS voltage supplied 2.7-3.6 V
158
                              8'b11010010 } :   //check pattern;
159
 
160
    (prepare_cmd55_for_41)? { 16'd0,            //RCA
161
                              16'd0 } :         //stuff bits
162
 
163
    (prepare_acmd41)?       { 1'b0,                   //busy
164
                              1'b1,                   //Host Capacity Support (1=SDHC or SDXC)
165
                              1'b0,                   //reserved FB(0)
166
                              1'b0,                   //SDXC Power Control (0=power saving)
167
                              3'b0,                   //reserved
168
                              1'b0,                   //switching to 1.8V request
169
                              16'b0011000000000000,   //voltage window field OCR[23:08]: 3.2-3.3 and 3.3-3.4
170
                              8'b0 } :                //reseved;
171
 
172
    (prepare_cmd2)?         32'd0 :             //stuff bits
173
 
174
    (prepare_cmd3)?         32'd0 :             //stuff bits
175
 
176
    (prepare_cmd7)?         { cmd3_new_rca,     //RCA
177
                              16'd0 } :         //stuff bits
178
 
179
    (prepare_cmd55_for_6)?  { rca,              //RCA
180
                              16'd0 } :         //stuff bits
181
 
182
    (prepare_acmd6)?        { 30'd0,            //stuff bits
183
                              2'b10 } :         //4 bit bus
184
 
185
                            32'd0;
186
 
187
assign cmd_resp_length =
188
    (prepare_cmd0)?         8'd0 :
189
    (prepare_cmd8)?         8'd48 :  //R7
190
    (prepare_cmd55_for_41)? 8'd48 :  //R1
191
    (prepare_acmd41)?       8'd48 :  //R3 OCR
192
    (prepare_cmd2)?         8'd136 : //R2
193
    (prepare_cmd3)?         8'd48 :  //R6
194
    (prepare_cmd7)?         8'd48 :  //R1b
195
    (prepare_cmd55_for_6)?  8'd48 :  //R1
196
    (prepare_acmd6)?        8'd48 :  //R1
197
                            8'd0;
198
 
199
assign cmd_resp_has_crc7 =
200
    (prepare_cmd0)?         1'b0 :
201
    (prepare_cmd8)?         1'b1 :
202
    (prepare_cmd55_for_41)? 1'b1 :
203
    (prepare_acmd41)?       1'b0 :
204
    (prepare_cmd2)?         1'b1 :
205
    (prepare_cmd3)?         1'b1 :
206
    (prepare_cmd7)?         1'b1 :
207
    (prepare_cmd55_for_6)?  1'b1 :
208
    (prepare_acmd6)?        1'b1 :
209
                            1'b1;
210
 
211
//------------------------------------------------------------------------------
212
// synthesis translate_off
213
wire _unused_ok = &{ 1'b0, reply_contents[135:46], reply_contents[20], reply_contents[7:0], 1'b0 };
214
// synthesis translate_on
215
//------------------------------------------------------------------------------
216
 
217
endmodule

powered by: WebSVN 2.1.0

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