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

Subversion Repositories aoocs

[/] [aoocs/] [trunk/] [tests/] [model_sd.v] - Blame information for rev 2

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 alfik
 
2
module model_sd(
3
        input reset_n,
4
 
5
        input sd_clk,
6
        inout sd_cmd_io,
7
        inout sd_dat_io
8
);
9
 
10
reg sd_cmd_o;
11
reg sd_dat_o;
12
reg sd_cmd_enable;
13
reg sd_data_enable;
14
 
15
assign sd_cmd_io = (sd_cmd_enable == 1'b1) ? sd_cmd_o : 1'bZ;
16
assign sd_dat_io = (sd_data_enable == 1'b1) ? sd_dat_o : 1'bZ;
17
 
18
reg [3:0] cmd_state;
19
reg [47:0] cmd_contents;
20
reg [135:0] cmd_reply;
21
reg [7:0] cmd_counter;
22
reg [6:0] crc7;
23
 
24
parameter [3:0]
25
        S_CMD_START_BIT = 4'd0,
26
        S_CMD_CONTENTS = 4'd1,
27
        S_CMD_CRC7_END_BIT = 4'd2,
28
        S_CMD_CHECK = 4'd3,
29
        S_CMD_WAIT = 4'd4,
30
        S_CMD_SEND_CONTENTS = 4'd5,
31
        S_CMD_SEND_CRC7 = 4'd6,
32
        S_CMD_SEND_END_BIT = 4'd7,
33
        S_CMD_SEND_FINISHED = 4'd8;
34
 
35
always @(posedge sd_clk or negedge reset_n) begin
36
        if(reset_n == 1'b0) begin
37
                cmd_state <= S_CMD_START_BIT;
38
                sd_cmd_enable <= 1'b0;
39
                sd_cmd_o <= 1'b1;
40
                cmd_contents <= 48'd0;
41
                cmd_counter <= 8'd0;
42
                crc7 <= 7'd0;
43
        end
44
        else if(cmd_state == S_CMD_START_BIT) begin
45
                if(sd_cmd_io == 1'b0) begin
46
                        cmd_contents <= { cmd_contents[46:0], sd_cmd_io };
47
                        crc7 <= { sd_cmd_io ^ crc7[0], crc7[6:5], sd_cmd_io ^ crc7[4] ^ crc7[0], crc7[3:1] };
48
                        cmd_state <= S_CMD_CONTENTS;
49
                        cmd_counter <= 8'd0;
50
                end
51
        end
52
        else if(cmd_state == S_CMD_CONTENTS) begin
53
                cmd_contents <= { cmd_contents[46:0], sd_cmd_io };
54
                crc7 <= { sd_cmd_io ^ crc7[0], crc7[6:5], sd_cmd_io ^ crc7[4] ^ crc7[0], crc7[3:1] };
55
 
56
                if(cmd_counter == 8'd38) begin
57
                        cmd_state <= S_CMD_CRC7_END_BIT;
58
                        cmd_counter <= 8'd0;
59
                end
60
                else cmd_counter <= cmd_counter + 8'd1;
61
        end
62
        else if(cmd_state == S_CMD_CRC7_END_BIT) begin
63
                cmd_contents <= { cmd_contents[46:0], sd_cmd_io };
64
 
65
                if(cmd_counter == 8'd7) begin
66
                        cmd_state <= S_CMD_CHECK;
67
                        cmd_counter <= 8'd0;
68
                end
69
                else cmd_counter <= cmd_counter + 8'd1;
70
        end
71
        else if(cmd_state == S_CMD_CHECK) begin
72
                crc7 <= 7'd0;
73
 
74
                if(
75
                        cmd_contents == { 1'b0, 1'b1, 6'd0, 32'd0, crc7[0],crc7[1],crc7[2],crc7[3],crc7[4],crc7[5],crc7[6], 1'b1 }
76
                ) begin
77
                        $display("CMD0");
78
                        cmd_state <= S_CMD_START_BIT;
79
                end
80
                else if(
81
                        cmd_contents == { 1'b0, 1'b1, 6'd8, 20'd0, 4'b0001, 8'b10101010, crc7[0],crc7[1],crc7[2],crc7[3],crc7[4],crc7[5],crc7[6], 1'b1 }
82
                ) begin
83
                        $display("CMD8");
84
                        cmd_reply[135:88] <= { 1'b0, 1'b0, 6'd8, 20'd0, 4'b0001, cmd_contents[15:8], 7'd0, 1'b1};
85
                        cmd_state <= S_CMD_WAIT;
86
                end
87
                else if(
88
                        cmd_contents == { 1'b0, 1'b1, 6'd55, 16'd0, 16'd0, crc7[0],crc7[1],crc7[2],crc7[3],crc7[4],crc7[5],crc7[6], 1'b1 }
89
                ) begin
90
                        $display("CMD55");
91
                        cmd_reply[135:88] <= { 1'b0, 1'b0, 6'd55, 32'b100000, 7'd0, 1'b1};
92
                        cmd_state <= S_CMD_WAIT;
93
                end
94
                else if(
95
                        cmd_contents == { 1'b0, 1'b1, 6'd41, 1'b0, 1'b1, 6'b0, 24'b0001_0000_0000_0000_0000_0000,
96
                                crc7[0],crc7[1],crc7[2],crc7[3],crc7[4],crc7[5],crc7[6], 1'b1 }
97
                ) begin
98
                        $display("CMD41");
99
                        cmd_reply[135:88] <= { 1'b0, 1'b0, 6'b111111, 32'b1100_0000_00000000_00000000_00000000, 7'b1111111, 1'b1};
100
                        cmd_state <= S_CMD_WAIT;
101
                end
102
                else if(
103
                        cmd_contents == { 1'b0, 1'b1, 6'd2, 32'd0, crc7[0],crc7[1],crc7[2],crc7[3],crc7[4],crc7[5],crc7[6], 1'b1 }
104
                ) begin
105
                        $display("CMD2");
106
                        cmd_reply[135:0] <= { 135'd0, 1'b1};
107
                        cmd_state <= S_CMD_WAIT;
108
                end
109
                else if(
110
                        cmd_contents == { 1'b0, 1'b1, 6'd3, 32'd0, crc7[0],crc7[1],crc7[2],crc7[3],crc7[4],crc7[5],crc7[6], 1'b1 }
111
                ) begin
112
                        $display("CMD3");
113
                        cmd_reply[135:88] <= { 1'b0, 1'b0, 6'd3, 16'hA0A0, 16'b0, 7'd0, 1'b1};
114
                        cmd_state <= S_CMD_WAIT;
115
                end
116
                else if(
117
                        cmd_contents == { 1'b0, 1'b1, 6'd7, 16'hA0A0, 16'd0, crc7[0],crc7[1],crc7[2],crc7[3],crc7[4],crc7[5],crc7[6], 1'b1 }
118
                ) begin
119
                        $display("CMD7: %08h", cmd_contents);
120
 
121
                        cmd_reply[135:88] <= { 1'b0, 1'b0, 6'd7, 32'b0, 7'd0, 1'b1};
122
                        cmd_state <= S_CMD_WAIT;
123
                end
124
                else if(
125
                        cmd_contents[47:40] == { 1'b0, 1'b1, 6'd17 } && cmd_contents[7:0] == { crc7[0],crc7[1],crc7[2],crc7[3],crc7[4],crc7[5],crc7[6], 1'b1 }
126
                ) begin
127
                        $display("CMD17: %08h", cmd_contents);
128
 
129
                        cmd_reply[135:88] <= { 1'b0, 1'b0, 6'd17, 32'b0, 7'd0, 1'b1};
130
                        cmd_state <= S_CMD_WAIT;
131
                end
132
                else if(
133
                        cmd_contents[47:40] == { 1'b0, 1'b1, 6'd24 } && cmd_contents[7:0] == { crc7[0],crc7[1],crc7[2],crc7[3],crc7[4],crc7[5],crc7[6], 1'b1 }
134
                ) begin
135
                        $display("CMD24: %08h", cmd_contents);
136
 
137
                        cmd_reply[135:88] <= { 1'b0, 1'b0, 6'd24, 32'b0, 7'd0, 1'b1};
138
                        cmd_state <= S_CMD_WAIT;
139
                end
140
                else begin
141
                        $display("Other cmd: %02d, contents: %08h", cmd_contents[45:40], cmd_contents);
142
                        cmd_state <= S_CMD_START_BIT;
143
                end
144
        end
145
        else if(cmd_state == S_CMD_WAIT) begin
146
                if(cmd_counter == 8'd15) begin
147
                        cmd_counter <= 8'd0;
148
                        sd_cmd_enable <= 1'b1;
149
                        sd_cmd_o <= 1'b1;
150
                        cmd_state <= S_CMD_SEND_CONTENTS;
151
                end
152
                else cmd_counter <= cmd_counter + 8'd1;
153
        end
154
        else if(cmd_state == S_CMD_SEND_CONTENTS) begin
155
                sd_cmd_o <= cmd_reply[135];
156
                cmd_reply <= { cmd_reply[134:0], 1'b0 };
157
                crc7 <= { cmd_reply[135] ^ crc7[0], crc7[6:5], cmd_reply[135] ^ crc7[4] ^ crc7[0], crc7[3:1] };
158
 
159
                if(cmd_counter == 8'd47 && cmd_contents[45:40] == 6'd41) begin
160
                        cmd_counter <= 8'd0;
161
                        cmd_state <= S_CMD_SEND_FINISHED;
162
                end
163
                else if(cmd_counter == 8'd39 && cmd_contents[45:40] != 6'd2 && cmd_contents[45:40] != 6'd41) begin
164
                        cmd_counter <= 8'd0;
165
                        cmd_state <= S_CMD_SEND_CRC7;
166
                end
167
                else if(cmd_counter == 8'd135 && cmd_contents[45:40] == 8'd2) begin
168
                        cmd_counter <= 8'd0;
169
                        cmd_state <= S_CMD_SEND_FINISHED;
170
                end
171
                else cmd_counter <= cmd_counter + 8'd1;
172
        end
173
        else if(cmd_state == S_CMD_SEND_CRC7) begin
174
                sd_cmd_o <= crc7[0];
175
                crc7 <= { 1'b0, crc7[6:1] };
176
 
177
                if(cmd_counter == 8'd6) begin
178
                        cmd_counter <= 8'd0;
179
                        cmd_state <= S_CMD_SEND_END_BIT;
180
                end
181
                else cmd_counter <= cmd_counter + 8'd1;
182
        end
183
        else if(cmd_state == S_CMD_SEND_END_BIT) begin
184
                sd_cmd_o <= 1'b1;
185
                cmd_state <= S_CMD_SEND_FINISHED;
186
        end
187
        else if(cmd_state == S_CMD_SEND_FINISHED) begin
188
                sd_cmd_o <= 1'b1;
189
                sd_cmd_enable <= 1'b0;
190
                crc7 <= 7'd0;
191
                cmd_state <= S_CMD_START_BIT;
192
        end
193
end
194
 
195
reg [2:0] data_state;
196
reg [11:0] data_counter;
197
reg [4095:0] data_contents;
198
reg [15:0] crc16;
199
 
200
parameter [2:0]
201
        S_DATA_IDLE = 3'd0,
202
        S_DATA_R1B_REPLY = 3'd1,
203
        S_DATA_R1B_REPLY_1 = 3'd2,
204
        S_DATA_READ = 3'd3,
205
        S_DATA_READ_1 = 3'd4,
206
        S_DATA_READ_2 = 3'd5,
207
        S_DATA_READ_3 = 3'd6;
208
 
209
 
210
always @(posedge sd_clk or negedge reset_n) begin
211
        if(reset_n == 1'b0) begin
212
                sd_data_enable <= 1'b0;
213
                sd_dat_o <= 1'b1;
214
                data_state <= S_DATA_IDLE;
215
                data_counter <= 12'd0;
216
                crc16 <= 16'd0;
217
        end
218
        else if(data_state == S_DATA_IDLE) begin
219
                if(cmd_contents[45:40] == 6'd7 && cmd_state == S_CMD_SEND_CRC7) begin
220
                        sd_data_enable <= 1'b1;
221
                        sd_dat_o <= 1'b1;
222
                        data_state <= S_DATA_R1B_REPLY;
223
                end
224
                else if(cmd_contents[45:40] == 6'd17 && cmd_state == S_CMD_SEND_CRC7) begin
225
                        sd_data_enable <= 1'b1;
226
                        sd_dat_o <= 1'b1;
227
                        data_contents <= { 1'b1, 31'b0, 1'b1, 4062'd0, 1'b1 };
228
                        data_state <= S_DATA_READ;
229
                end
230
        end
231
        else if(data_state == S_DATA_R1B_REPLY) begin
232
                if(data_counter == 12'd16) begin
233
                        sd_dat_o <= 1'b1;
234
                        data_counter <= 12'd0;
235
                        data_state <= S_DATA_R1B_REPLY_1;
236
                end
237
                else begin
238
                        sd_dat_o <= 1'b0;
239
                        data_counter <= data_counter + 12'd1;
240
                end
241
        end
242
        else if(data_state == S_DATA_R1B_REPLY_1) begin
243
                sd_data_enable <= 1'b0;
244
                data_state <= S_DATA_IDLE;
245
        end
246
 
247
 
248
        else if(data_state == S_DATA_READ) begin
249
                sd_dat_o <= 1'b0;
250
                crc16 <= { 1'b0 ^ crc16[0], crc16[15:12], 1'b0 ^ crc16[11] ^ crc16[0], crc16[10:5],
251
                        1'b0 ^ crc16[4] ^ crc16[0], crc16[3:1] };
252
 
253
                data_counter <= 12'd0;
254
                data_state <= S_DATA_READ_1;
255
        end
256
        else if(data_state == S_DATA_READ_1) begin
257
                sd_dat_o <= data_contents[4095];
258
                crc16 <= { data_contents[4095] ^ crc16[0], crc16[15:12], data_contents[4095] ^ crc16[11] ^ crc16[0], crc16[10:5],
259
                        data_contents[4095] ^ crc16[4] ^ crc16[0], crc16[3:1] };
260
                data_contents <= { data_contents[4094:0], 1'b0 };
261
 
262
                if(data_counter == 12'd4095) begin
263
                        data_counter <= 12'd0;
264
                        data_state <= S_DATA_READ_2;
265
                end
266
                else data_counter <= data_counter + 12'd1;
267
        end
268
 
269
        else if(data_state == S_DATA_READ_2) begin
270
                sd_dat_o <= crc16[0];
271
 
272
                if(data_counter == 12'd16) begin
273
                        data_counter <= 12'd0;
274
                        data_state <= S_DATA_READ_3;
275
                end
276
                else begin
277
                        crc16 <= { 1'b1, crc16[15:1] };
278
                        data_counter <= data_counter + 12'd1;
279
                end
280
        end
281
        else if(data_state == S_DATA_READ_3) begin
282
                sd_data_enable <= 1'b0;
283
                crc16 <= 16'd0;
284
                data_state <= S_DATA_IDLE;
285
        end
286
 
287
end
288
 
289
endmodule
290
 

powered by: WebSVN 2.1.0

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