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

Subversion Repositories sdcard_mass_storage_controller

[/] [sdcard_mass_storage_controller/] [trunk/] [rtl/] [sdc_dma/] [verilog/] [sd_data_master.v] - Blame information for rev 134

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 134 tac2
`include "sd_defines.v"
2
 
3
module sd_data_master (
4
  input clk,
5
  input rst,
6
  //Tx Bd
7
 
8
  input [`RAM_MEM_WIDTH-1:0] dat_in_tx,
9
  input [`BD_WIDTH-1:0] free_tx_bd,
10
  input ack_i_s_tx,
11
  output reg re_s_tx,
12
  output reg a_cmp_tx,
13
  //Rx Bd
14
 
15
  input [`RAM_MEM_WIDTH-1:0] dat_in_rx,
16
  input [`BD_WIDTH-1:0] free_rx_bd,
17
  input ack_i_s_rx,
18
  output reg re_s_rx,
19
  output reg a_cmp_rx,
20
  //Input from SD-Host Reg
21
  input  cmd_busy, //STATUS_REG[0] and mux  
22
  //Output to SD-Host Reg
23
  output reg we_req,
24
  input we_ack,
25
  output reg d_write,
26
  output reg d_read,
27
  output reg [31:0] cmd_arg,
28
  output reg [15:0] cmd_set,
29
  input cmd_tsf_err,
30
  input [4:0] card_status,
31
  //To fifo filler
32
  output reg start_tx_fifo,
33
  output reg start_rx_fifo,
34
  output reg [31:0] sys_adr,
35
  input tx_empt,
36
  input tx_full,
37
  input rx_full,
38
 
39
  //SD-DATA_Host
40
  input busy_n     ,
41
  input transm_complete ,
42
  input crc_ok,
43
  output reg ack_transfer,
44
  //status output
45
  output reg  [7:0] Dat_Int_Status ,
46
  input Dat_Int_Status_rst,
47
  output reg  CIDAT,
48
  input [1:0] transfer_type
49
 
50
 
51
  );
52
`define RESEND_MAX_CNT 3
53
`ifdef RAM_MEM_WIDTH_32
54
      `define READ_CYCLE 2
55
       reg [1:0]bd_cnt  ;
56
       `define BD_EMPTY (`BD_SIZE  /2)
57
`else `ifdef  RAM_MEM_WIDTH_16
58
      `define READ_CYCLE 4
59
       reg [2:0] bd_cnt;
60
       `define BD_EMPTY (`BD_SIZE  /4)
61
   `endif
62
`endif
63
 
64
reg send_done;
65
reg rec_done;
66
reg rec_failed;
67
reg tx_cycle;
68
reg rx_cycle;
69
reg [2:0] resend_try_cnt;
70
 
71
parameter CMD24 = 16'h181A ; // 011000 0001 1010
72
parameter CMD17 = 16'h111A; //  010001 0001 1010
73
parameter CMD12 = 16'hC1A ; //  001100 0001 1010
74
parameter ACMD13 = 16'hD1A ; // 001101 0001 1010  //SD STATUS
75
parameter ACMD51 = 16'h331A ; //110011 0001 1010 //SCR Register
76
 
77
parameter SIZE = 9;
78
reg [SIZE-1:0] state;
79
reg [SIZE-1:0] next_state;
80
parameter IDLE             =  9'b000000001;
81
parameter GET_TX_BD        =  9'b000000010;
82
parameter GET_RX_BD        =  9'b000000100;
83
parameter SEND_CMD         =  9'b000001000;
84
parameter RECIVE_CMD       =  9'b000010000;
85
parameter DATA_TRANSFER    =  9'b000100000;
86
parameter STOP             =  9'b001000000;
87
parameter STOP_SEND        =  9'b010000000;
88
parameter STOP_RECIVE_CMD  =  9'b100000000;
89
 
90
reg trans_done;
91
reg trans_failed;
92
reg internal_transm_complete;
93
reg transm_complete_q;
94
 
95
always @ (posedge clk or posedge rst )
96
begin
97
        if  (rst) begin
98
                internal_transm_complete <=1'b0;
99
                transm_complete_q<=0;
100
        end
101
        else begin
102
                transm_complete_q<=transm_complete;
103
                internal_transm_complete<=transm_complete_q;
104
        end
105
 
106
 
107
end
108
 
109
 
110
 
111
 
112
always @ (state or resend_try_cnt or tx_full or free_tx_bd or free_rx_bd or bd_cnt or send_done or rec_done or rec_failed or trans_done or trans_failed)
113
begin : FSM_COMBO
114
 next_state  = 0;
115
case(state)
116
 
117
  IDLE: begin
118
   if (free_tx_bd !=`BD_EMPTY)begin
119
      next_state = GET_TX_BD;
120
   end
121
   else if (free_rx_bd !=`BD_EMPTY) begin
122
      next_state = GET_RX_BD;
123
   end
124
   else begin
125
      next_state = IDLE;
126
   end
127
  end
128
  GET_TX_BD: begin
129
    if ( ( bd_cnt> `READ_CYCLE-1) && (tx_full==1) )begin
130
     next_state = SEND_CMD;
131
    end
132
    else begin
133
     next_state = GET_TX_BD;
134
    end
135
  end
136
 
137
  GET_RX_BD: begin
138
    if (bd_cnt >= (`READ_CYCLE-1))begin
139
     next_state = SEND_CMD;
140
    end
141
    else begin
142
     next_state = GET_RX_BD;
143
    end
144
  end
145
 
146
  SEND_CMD: begin
147
   if (send_done)begin
148
     next_state = RECIVE_CMD;
149
    end
150
    else begin
151
     next_state = SEND_CMD;
152
    end
153
  end
154
 
155
 
156
 RECIVE_CMD: begin
157
    if (rec_done)
158
      next_state = DATA_TRANSFER;
159
    else if (rec_failed)
160
      next_state =  SEND_CMD;
161
    else
162
      next_state = RECIVE_CMD;
163
   end
164
 
165
  DATA_TRANSFER: begin
166
    if (trans_done)
167
      next_state = IDLE;
168
   else if (trans_failed)
169
      next_state = STOP;
170
   else
171
      next_state = DATA_TRANSFER;
172
   end
173
 
174
  STOP: begin
175
     next_state = STOP_SEND;
176
   end
177
 
178
   STOP_SEND: begin
179
    if (send_done)begin
180
     next_state =IDLE;
181
    end
182
    else begin
183
     next_state = STOP_SEND;
184
    end
185
   end
186
 
187
   STOP_RECIVE_CMD : begin
188
    if (rec_done)
189
      next_state = SEND_CMD;
190
    else if (rec_failed)
191
      next_state =  STOP;
192
    else if (resend_try_cnt>=`RESEND_MAX_CNT)
193
      next_state = IDLE;
194
    else
195
      next_state = STOP_RECIVE_CMD;
196
   end
197
 
198
 
199
 
200
 default : next_state  = IDLE;
201
 endcase
202
 
203
end
204
 
205
//----------------Seq logic------------
206
always @ (posedge clk or posedge rst   )
207
begin : FSM_SEQ
208
  if (rst ) begin
209
    state <= #1 IDLE;
210
 end
211
 else begin
212
    state <= #1 next_state;
213
 end
214
end
215
 
216
 
217
 
218
//Output logic-----------------
219
 
220
 
221
always @ (posedge clk or posedge rst   )
222
begin
223
 if (rst) begin
224
      send_done<=0;
225
      bd_cnt<=0;
226
      sys_adr<=0;
227
      cmd_arg<=0;
228
      rec_done<=0;
229
      start_tx_fifo<=0;
230
      start_rx_fifo<=0;
231
      send_done<=0;
232
      rec_failed<=0;
233
      d_write <=0;
234
      d_read <=0;
235
      trans_failed<=0;
236
      trans_done<=0;
237
      tx_cycle <=0;
238
      rx_cycle <=0;
239
      ack_transfer<=0;
240
      a_cmp_tx<=0;
241
      a_cmp_rx<=0;
242
      CIDAT<=0;
243
      Dat_Int_Status<=0;
244
      we_req<=0;
245
      re_s_tx<=0;
246
      re_s_rx<=0;
247
      cmd_set<=0;
248
      resend_try_cnt=0;
249
 end
250
 else begin
251
  case(state)
252
     IDLE: begin
253
      send_done<=0;
254
      bd_cnt<=0;
255
      sys_adr<=0;
256
      cmd_arg<=0;
257
      rec_done<=0;
258
      rec_failed<=0;
259
      start_tx_fifo<=0;
260
      start_rx_fifo<=0;
261
      send_done<=0;
262
      d_write <=0;
263
      d_read <=0;
264
      trans_failed<=0;
265
      trans_done<=0;
266
      tx_cycle <=0;
267
      rx_cycle <=0;
268
      ack_transfer<=0;
269
      a_cmp_tx<=0;
270
      a_cmp_rx<=0;
271
      resend_try_cnt=0;
272
     end
273
 
274
     GET_RX_BD: begin
275
        //0,1,2,3...
276
      re_s_rx <= 1;
277
     `ifdef  RAM_MEM_WIDTH_32
278
        if (ack_i_s_rx) begin
279
                if( bd_cnt == 2'b0) begin
280
                   sys_adr  <= dat_in_rx;
281
                   bd_cnt <= bd_cnt+1;
282
                end
283
                else if ( bd_cnt == 2'b1) begin
284
                   cmd_arg  <= dat_in_rx;
285
                   re_s_rx <= 0;
286
                end
287
           end
288
      `endif
289
 
290
 
291
      `ifdef  RAM_MEM_WIDTH_16
292
        if (ack_i_s_rx) begin
293
                if( bd_cnt == 2'b00) begin
294
                   sys_adr [15:0] <= dat_in_rx;
295
                end
296
                else if ( bd_cnt == 2'b01)  begin
297
                   sys_adr [31:16] <= dat_in_rx;
298
                end
299
                else if ( bd_cnt == 2) begin
300
                  cmd_arg [15:0] <= dat_in_rx;
301
                  re_s_rx <= 0;
302
                end
303
                else if ( bd_cnt == 3) begin
304
                   cmd_arg [31:16] <= dat_in_rx;
305
                   re_s_rx <= 0;
306
                 end
307
                 bd_cnt <= bd_cnt+1;
308
                end
309
       `endif
310
     //Add Later Save last block addres for comparison with current (For multiple block cmd)
311
     //Add support for Pre-erased
312
      if (transfer_type==2'b00)
313
                   cmd_set <= CMD17;
314
                else if (transfer_type==2'b01)
315
                   cmd_set <= ACMD13;
316
                else
317
           cmd_set <= ACMD51;
318
 
319
      rx_cycle<=1;
320
     end
321
 
322
     GET_TX_BD:  begin
323
        //0,1,2,3...
324
      re_s_tx <= 1;
325
      if ( bd_cnt == `READ_CYCLE)
326
        re_s_tx <= 0;
327
 
328
       `ifdef  RAM_MEM_WIDTH_32
329
         if (ack_i_s_tx) begin
330
 
331
                if( bd_cnt == 2'b0) begin
332
                   sys_adr  <= dat_in_tx;
333
                   bd_cnt <= bd_cnt+1;
334
                end
335
                else if ( bd_cnt == 2'b1) begin
336
                   cmd_arg  <= dat_in_tx;
337
                   re_s_tx <= 0;
338
                           start_tx_fifo<=1;
339
        end
340
           end
341
       `endif
342
 
343
      `ifdef  RAM_MEM_WIDTH_16
344
      if (ack_i_s_tx) begin
345
 
346
        if( bd_cnt == 0) begin
347
           sys_adr [15:0] <= dat_in_tx;
348
           bd_cnt <= bd_cnt+1;   end
349
        else if ( bd_cnt == 1)  begin
350
           sys_adr [31:16] <= dat_in_tx;
351
           bd_cnt <= bd_cnt+1;    end
352
        else if ( bd_cnt == 2) begin
353
          cmd_arg [15:0] <= dat_in_tx;
354
          re_s_tx <= 0;
355
          bd_cnt <= bd_cnt+1;    end
356
        else if ( bd_cnt == 3) begin
357
           cmd_arg [31:16] <= dat_in_tx;
358
           re_s_tx <= 0;
359
           bd_cnt <= bd_cnt+1;
360
                   start_tx_fifo<=1;
361
         end
362
       end
363
       `endif
364
     //Add Later Save last block addres for comparison with current (For multiple block cmd)
365
     //Add support for Pre-erased
366
      cmd_set <= CMD24;
367
      tx_cycle <=1;
368
 
369
   end
370
 
371
     SEND_CMD : begin
372
       rec_done<=0;
373
       if (rx_cycle)    begin
374
         re_s_rx <=0;
375
         d_read<=1;
376
       end
377
       else begin
378
         re_s_tx <=0;
379
         d_write<=1;
380
        end
381
       start_rx_fifo<=0; //Reset FIFO  
382
      // start_tx_fifo<=0;  //Reset FIFO 
383
       if (!cmd_busy) begin
384
         we_req <= 1;
385
 
386
       end  //When send complete change state and wait for reply
387
       if (we_ack) begin
388
           send_done<=1;
389
           we_req <= 1;
390
 
391
       end
392
    end
393
 
394
 
395
    RECIVE_CMD : begin
396
         //When waiting for reply fill TX fifo
397
        if (rx_cycle)
398
         start_rx_fifo<=1; //start_fifo prebuffering
399
       //else
400
         //start_rx_fifo <=1;
401
 
402
         we_req <= 0;
403
 
404
         send_done<=0;
405
       if (!cmd_busy) begin //Means the sending is completed,
406
         d_read<=0;
407
         d_write<=0;
408
         if (!cmd_tsf_err) begin
409
           if (card_status[0]) begin
410
 
411
                if ( (card_status[4:1] == 4'b0100) || (card_status[4:1] == 4'b0110) || (card_status[4:1] == 4'b0101) )
412
                    rec_done<=1;
413
                else begin
414
                    rec_failed<=1;
415
                    Dat_Int_Status[4] <=1;
416
                       start_tx_fifo<=0;
417
                end
418
 
419
 
420
 
421
               //Check card_status[5:1] for state 4 or 6... 
422
               //If wrong state change interupt status reg,so software can put card in
423
               // transfer state and restart/cancel Data transfer
424
          end
425
 
426
         end
427
         else begin
428
             rec_failed<=1;  //CRC-Error, CIC-Error or timeout 
429
                start_tx_fifo<=0;
430
                end
431
       end
432
    end
433
 
434
    DATA_TRANSFER: begin
435
       CIDAT<=1;
436
     if (tx_cycle) begin
437
      if (tx_empt) begin
438
         Dat_Int_Status[2] <=1;
439
         trans_failed<=1;
440
       end
441
     end
442
     else begin
443
       if (rx_full) begin
444
         Dat_Int_Status[2] <=1;
445
         trans_failed<=1;
446
      end
447
    end
448
      //Check for fifo underflow, 
449
      //2 DO: if deteced stop transfer, reset data host
450
      if (internal_transm_complete) begin //Transfer complete
451
         ack_transfer<=1;
452
 
453
         if ((!crc_ok) && (busy_n))  begin //Wrong CRC and Data line free.
454
            Dat_Int_Status[5] <=1;
455
            trans_failed<=1;
456
         end
457
         else if ((crc_ok) && (busy_n)) begin //Data Line free
458
           trans_done <=1;
459
 
460
                        if (tx_cycle) begin
461
                                a_cmp_tx<=1;
462
                                if (free_tx_bd ==`BD_EMPTY-1 )
463
                                        Dat_Int_Status[0]<=1;
464
                        end
465
                        else begin
466
                                a_cmp_rx<=1;
467
                                if (free_rx_bd ==`BD_EMPTY-1)
468
                                        Dat_Int_Status[0]<=1;
469
                        end
470
 
471
 
472
       end
473
 
474
  end
475
  end
476
  STOP: begin
477
    cmd_set <= CMD12;
478
    rec_done<=0;
479
    rec_failed<=0;
480
    send_done<=0;
481
    trans_failed<=0;
482
    trans_done<=0;
483
    d_read<=1;
484
    d_write<=1;
485
    start_rx_fifo <=0;
486
    start_tx_fifo <=0;
487
 
488
  end
489
   STOP_SEND: begin
490
      resend_try_cnt=resend_try_cnt+1;
491
      if (resend_try_cnt==`RESEND_MAX_CNT)
492
          Dat_Int_Status[1]<=1;
493
      if (!cmd_busy)
494
         we_req <= 1;
495
      if (we_ack)
496
           send_done<=1;
497
   end
498
 
499
   STOP_RECIVE_CMD: begin
500
     we_req <= 0;
501
    end
502
 
503
  endcase
504
  if (Dat_Int_Status_rst)
505
    Dat_Int_Status<=0;
506
 end
507
 
508
end
509
 
510
endmodule

powered by: WebSVN 2.1.0

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