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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [orpsocv2/] [boards/] [actel/] [ordb1a3pe1500/] [rtl/] [verilog/] [sdc_controller/] [sd_data_master.v] - Blame information for rev 544

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 544 julius
`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
 
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
      start_rx_fifo<=0;
326
      if ( bd_cnt == `READ_CYCLE)
327
        re_s_tx <= 0;
328
 
329
       `ifdef  RAM_MEM_WIDTH_32
330
         if (ack_i_s_tx) begin
331
 
332
                if( bd_cnt == 2'b0) begin
333
                   sys_adr  <= dat_in_tx;
334
                   bd_cnt <= bd_cnt+1;
335
                end
336
                else if ( bd_cnt == 2'b1) begin
337
                   cmd_arg  <= dat_in_tx;
338
                   re_s_tx <= 0;
339
                           start_tx_fifo<=1;
340
        end
341
           end
342
       `endif
343
 
344
      `ifdef  RAM_MEM_WIDTH_16
345
      if (ack_i_s_tx) begin
346
 
347
        if( bd_cnt == 0) begin
348
           sys_adr [15:0] <= dat_in_tx;
349
           bd_cnt <= bd_cnt+1;   end
350
        else if ( bd_cnt == 1)  begin
351
           sys_adr [31:16] <= dat_in_tx;
352
           bd_cnt <= bd_cnt+1;    end
353
        else if ( bd_cnt == 2) begin
354
          cmd_arg [15:0] <= dat_in_tx;
355
          re_s_tx <= 0;
356
          bd_cnt <= bd_cnt+1;    end
357
        else if ( bd_cnt == 3) begin
358
           cmd_arg [31:16] <= dat_in_tx;
359
           re_s_tx <= 0;
360
           bd_cnt <= bd_cnt+1;
361
                   start_tx_fifo<=1;
362
         end
363
       end
364
       `endif
365
     //Add Later Save last block addres for comparison with current (For multiple block cmd)
366
     //Add support for Pre-erased
367
      cmd_set <= CMD24;
368
      tx_cycle <=1;
369
 
370
   end
371
 
372
     SEND_CMD : begin
373
       rec_done<=0;
374
       if (rx_cycle)    begin
375
         re_s_rx <=0;
376
         d_read<=1;
377
       end
378
       else begin
379
         re_s_tx <=0;
380
         d_write<=1;
381
        end
382
       start_rx_fifo<=0; //Reset FIFO  
383
      // start_tx_fifo<=0;  //Reset FIFO 
384
       if (!cmd_busy) begin
385
         we_req <= 1;
386
 
387
       end  //When send complete change state and wait for reply
388
       if (we_ack) begin
389
           send_done<=1;
390
           we_req <= 1;
391
 
392
       end
393
    end
394
 
395
 
396
    RECIVE_CMD : begin
397
         //When waiting for reply fill TX fifo
398
 
399
         start_rx_fifo<=0; //Restart fifo
400
       //else
401
         //start_rx_fifo <=1;
402
 
403
         we_req <= 0;
404
 
405
         send_done<=0;
406
       if (!cmd_busy) begin //Means the sending is completed,
407
         d_read<=0;
408
         d_write<=0;
409
         if (!cmd_tsf_err) begin
410
           if (card_status[0]) begin
411
 
412
                if ( (card_status[4:1] == 4'b0100) || (card_status[4:1] == 4'b0110) || (card_status[4:1] == 4'b0101) ) begin
413
                                          if (rx_cycle)
414
                                         start_rx_fifo<=1; //start RX-fifo
415
                    rec_done<=1;
416
                end
417
                else begin
418
                    rec_failed<=1;
419
                    Dat_Int_Status[4] <=1;
420
                    start_tx_fifo<=0;
421
                end
422
 
423
 
424
 
425
               //Check card_status[5:1] for state 4 or 6... 
426
               //If wrong state change interupt status reg,so software can put card in
427
               // transfer state and restart/cancel Data transfer
428
          end
429
 
430
         end
431
         else begin
432
             rec_failed<=1;  //CRC-Error, CIC-Error or timeout 
433
                start_tx_fifo<=0;
434
                end
435
       end
436
    end
437
 
438
    DATA_TRANSFER: begin
439
       CIDAT<=1;
440
     if (tx_cycle) begin
441
      if (tx_empt) begin
442
         Dat_Int_Status[2] <=1;
443
         trans_failed<=1;
444
       end
445
     end
446
     else begin
447
       if (rx_full) begin
448
         Dat_Int_Status[2] <=1;
449
         trans_failed<=1;
450
      end
451
    end
452
      //Check for fifo underflow, 
453
      //2 DO: if deteced stop transfer, reset data host
454
      if (internal_transm_complete) begin //Transfer complete
455
         ack_transfer<=1;
456
 
457
         if ((!crc_ok) && (busy_n))  begin //Wrong CRC and Data line free.
458
            Dat_Int_Status[5] <=1;
459
            trans_failed<=1;
460
         end
461
         else if ((crc_ok) && (busy_n)) begin //Data Line free
462
           trans_done <=1;
463
 
464
                        if (tx_cycle) begin
465
                                a_cmp_tx<=1;
466
                                if (free_tx_bd ==`BD_EMPTY-1 )
467
                                        Dat_Int_Status[0]<=1;
468
                        end
469
                        else begin
470
                                a_cmp_rx<=1;
471
                                if (free_rx_bd ==`BD_EMPTY-1)
472
                                        Dat_Int_Status[0]<=1;
473
                        end
474
 
475
 
476
       end
477
 
478
  end
479
  end
480
  STOP: begin
481
    cmd_set <= CMD12;
482
    rec_done<=0;
483
    rec_failed<=0;
484
    send_done<=0;
485
    trans_failed<=0;
486
    trans_done<=0;
487
    d_read<=1;
488
    d_write<=1;
489
    start_rx_fifo <=0;
490
    start_tx_fifo <=0;
491
 
492
  end
493
   STOP_SEND: begin
494
      resend_try_cnt=resend_try_cnt+1;
495
      if (resend_try_cnt==`RESEND_MAX_CNT)
496
          Dat_Int_Status[1]<=1;
497
      if (!cmd_busy)
498
         we_req <= 1;
499
      if (we_ack)
500
           send_done<=1;
501
   end
502
 
503
   STOP_RECIVE_CMD: begin
504
     we_req <= 0;
505
    end
506
 
507
  endcase
508
  if (Dat_Int_Status_rst)
509
    Dat_Int_Status<=0;
510
 end
511
 
512
end
513
 
514
endmodule

powered by: WebSVN 2.1.0

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