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_cmd_serial_host.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
//-------------------------
4
module sd_cmd_serial_host ( SD_CLK_IN, RST_IN, SETTING_IN ,CMD_IN, REQ_IN, ACK_OUT, REQ_OUT,ACK_IN, CMD_OUT, STATUS, cmd_dat_i, cmd_out_o, cmd_oe_o, st_dat_t);
5
//---------------Input ports---------------
6
input SD_CLK_IN;
7
input  RST_IN;
8
input [15:0] SETTING_IN;
9
 
10
input [39:0] CMD_IN;
11
input   REQ_IN;
12
input ACK_IN;
13
input cmd_dat_i;
14
 
15
//---------------Output ports---------------
16
output [39:0] CMD_OUT;
17
output ACK_OUT;
18
output REQ_OUT;
19
output [7:0] STATUS;
20
output reg cmd_oe_o;
21
output reg cmd_out_o;
22
output reg [1:0] st_dat_t;
23
//---------------Input ports Data Type------  
24
wire SD_CLK_IN;
25
wire RST_IN;
26
wire [15:0] SETTING_IN;
27
wire [39:0] CMD_IN;
28
wire REQ_IN;
29
wire ACK_IN;
30
 
31
//---------------Output ports Data Type------  
32
reg  [39:0] CMD_OUT;
33
wire ACK_OUT  ;
34
reg  [7:0] STATUS;
35
reg  REQ_OUT;
36
 
37
//-------------Internal Constant-------------
38
 
39
`ifdef SIM
40
 `define INIT_DELAY 2
41
`else
42
  `define INIT_DELAY 64
43
 `endif
44
 
45
`define NCR 2
46
parameter SEND_SIZE = 48;
47
parameter SIZE = 10;
48
parameter CONTENT_SIZE = 40;
49
parameter
50
    INIT   =  10'b0000_0000_01,
51
    IDLE   =  10'b0000_0000_10,
52
    WRITE_WR        =  10'b0000_0001_00,
53
    DLY_WR       =  10'b0000_0010_00,
54
    READ_WR      =  10'b0000_0100_00,
55
          DLY_READ      =  10'b0000_1000_00,
56
          ACK_WR                     =  10'b0001_0000_00,
57
          WRITE_WO          =  10'b0010_0000_00,
58
          DLY_WO              =  10'b0100_0000_00,
59
          ACK_WO              =  10'b1000_0000_00;
60
parameter Read_Delay = 7;
61
parameter EIGHT_PAD = 8;
62
//---------------Internal variable----------- 
63
//-Internal settings/buffers
64
reg [6:0] Response_Size;
65
reg [2:0] Delay_Cycler;
66
reg [CONTENT_SIZE-1:0] In_Buff;
67
reg [39:0] Out_Buff;
68
//-Internal State input
69
reg Write_Read;
70
reg Write_Only;
71
 
72
//-CRC
73
reg [4:0] word_select_counter;
74
reg CRC_RST;
75
reg [6:0]CRC_IN;
76
wire [6:0] CRC_VAL;
77
reg CRC_Enable;
78
reg CRC_OUT;
79
reg CRC_Check_On;
80
reg Crc_Buffering;
81
reg CRC_Valid;
82
//-Internal Counterns
83
  //6 bit sent counter
84
reg [7:0]Cmd_Cnt; //8 bit recive counter
85
reg [2:0]Delay_Cnt; //3 bit Delay counter
86
//-State Variable
87
reg [SIZE-1:0] state;
88
reg [SIZE-1:0] next_state;
89
//Misc
90
`define Vector_Index  (CONTENT_SIZE-1-Cmd_Cnt)
91
`define Bit_Nr (SEND_SIZE-Cmd_Cnt)
92
 
93
//TRI-STATE
94
reg block_write;
95
reg block_read;
96
 
97
 
98
//
99
reg [1:0]word_select;
100
reg FSM_ACK;
101
reg DECODER_ACK;
102
 
103
reg q;
104
reg Req_internal_in;
105
reg q1;
106
reg Ack_internal_in;
107
//------------------------------------------   
108
sd_crc_7 CRC_7(
109
CRC_OUT,
110
CRC_Enable,
111
SD_CLK_IN,
112
CRC_RST,
113
CRC_VAL);
114
//------------------------------------------  
115
always @ (state or Delay_Cnt or Write_Read or Cmd_Cnt or Write_Only or Ack_internal_in or  cmd_dat_i or Response_Size or Delay_Cycler)
116
begin : FSM_COMBO
117
 next_state  = 0;
118
case(state)
119
INIT: begin
120
  if (Cmd_Cnt >= `INIT_DELAY )begin
121
     next_state = IDLE;
122
  end
123
 
124
  else begin
125
 
126
      next_state = INIT;
127
  end
128
 
129
end
130
 
131
 
132
IDLE: begin
133
         if (Write_Read ) begin
134
        next_state = WRITE_WR;
135
      end
136
      else if (Write_Only  ) begin
137
        next_state = WRITE_WO;
138
      end
139
      else begin
140
         next_state = IDLE;
141
      end
142
end
143
WRITE_WR:
144
      if (Cmd_Cnt >=SEND_SIZE-1) begin
145
        next_state = DLY_WR;
146
      end
147
      else begin
148
        next_state = WRITE_WR;
149
      end
150
WRITE_WO:
151
      if (Cmd_Cnt >= SEND_SIZE-1) begin
152
        next_state = DLY_WO;
153
      end
154
      else begin
155
        next_state = WRITE_WO;
156
      end
157
DLY_WR :
158
      if ( (Delay_Cnt >= `NCR) && ( !cmd_dat_i)) begin
159
        next_state = READ_WR;
160
      end
161
      else begin
162
        next_state = DLY_WR;
163
      end
164
DLY_WO :
165
       if (Delay_Cnt >= Delay_Cycler) begin
166
        next_state = ACK_WO;
167
      end
168
      else begin
169
        next_state = DLY_WO;
170
      end
171
READ_WR :
172
      if (Cmd_Cnt >= (Response_Size+EIGHT_PAD)) begin
173
        next_state = DLY_READ;
174
      end
175
      else begin
176
        next_state = READ_WR;
177
      end
178
 
179
ACK_WO :
180
      next_state = IDLE;
181
 
182
DLY_READ :
183
     if (Ack_internal_in ) begin
184
        next_state = ACK_WR;
185
      end
186
      else begin
187
        next_state = DLY_READ;
188
      end
189
 
190
ACK_WR  :
191
        next_state = IDLE;
192
 
193
 
194
default : next_state  = INIT;
195
 
196
 endcase
197
end
198
  //----
199
 
200
always @ (posedge SD_CLK_IN or posedge RST_IN)
201
begin : REQ_SYNC
202
        if  (RST_IN ) begin
203
                Req_internal_in <=1'b0;
204
                q <=1'b0;
205
        end
206
        else begin
207
                q<=REQ_IN;
208
                Req_internal_in<=q;
209
        end
210
 
211
 
212
end
213
 
214
always @ (posedge SD_CLK_IN or posedge RST_IN)
215
begin :ACK_SYNC
216
        if  (RST_IN ) begin
217
                Ack_internal_in <=1'b0;
218
                q1 <=1'b0;
219
        end
220
        else begin
221
                q1<=ACK_IN;
222
                Ack_internal_in<=q1;
223
        end
224
 
225
 
226
end
227
 
228
 
229
 
230
 
231
 
232
 
233
 
234
always @ (posedge SD_CLK_IN or posedge RST_IN )
235
  begin:COMMAND_DECODER
236
  if (RST_IN ) begin
237
                  Delay_Cycler <=3'b0;
238
                  Response_Size <=7'b0;
239
                  DECODER_ACK <= 1;
240
                  Write_Read<=1'b0;
241
            Write_Only<=1'b0;
242
            CRC_Check_On <=0;
243
            In_Buff <=0;
244
            block_write<=0;
245
            block_read <=0;
246
            word_select<=0;
247
   end
248
   else begin
249
                        if (Req_internal_in == 1) begin
250
                                Response_Size[6:0] <=  SETTING_IN [6:0];
251
                                CRC_Check_On <= SETTING_IN [7];
252
                                Delay_Cycler[2:0] <= SETTING_IN [10:8];
253
                                block_write <= SETTING_IN [11];
254
                                block_read <= SETTING_IN [12];
255
                                word_select <=SETTING_IN [14:13];
256
                                In_Buff <= CMD_IN;
257
                                DECODER_ACK<=0;
258
                                if (SETTING_IN [6:0]>0) begin
259
                                   Write_Read<=1'b1;
260
                                   Write_Only<=1'b0;
261
                                end
262
                                else begin
263
                                        Write_Read<=1'b0;
264
                                  Write_Only<=1'b1;
265
                                end
266
                        end
267
                        else begin
268
                                Write_Read<=1'b0;
269
                                Write_Only<=1'b0;
270
                                DECODER_ACK <= 1;
271
                        end
272
    end
273
 end
274
//End block COMMAND_DECODER  
275
 
276
//-------Function for Combo logic-----------------
277
 
278
 
279
 
280
assign ACK_OUT = FSM_ACK & DECODER_ACK;
281
 
282
//----------------Seq logic------------
283
always @ (posedge SD_CLK_IN or posedge RST_IN   )
284
begin : FSM_SEQ
285
  if (RST_IN ) begin
286
    state <= #1 INIT;
287
 end
288
 
289
 else begin
290
    state <= #1 next_state;
291
 end
292
end
293
 
294
//-------------OUTPUT_LOGIC-------
295
always @ (posedge SD_CLK_IN or posedge RST_IN   )
296
begin : FSM_OUT
297
 if (RST_IN ) begin
298
            CRC_Enable=0;
299
            word_select_counter<=0;
300
            Delay_Cnt =0;
301
                cmd_oe_o=1;
302
            cmd_out_o = 1;
303
                 Out_Buff =0;
304
                FSM_ACK=1;
305
                REQ_OUT =0;
306
                  CRC_RST =1;
307
                  CRC_OUT =0;
308
                  CRC_IN =0;
309
                  CMD_OUT =0;
310
                Crc_Buffering =0;
311
                STATUS = 0;
312
                CRC_Valid=0;
313
                Cmd_Cnt=0;
314
                st_dat_t<=0;
315
 
316
 
317
 end
318
 else begin
319
  case(state)
320
        INIT : begin
321
                Cmd_Cnt=Cmd_Cnt+1;
322
                cmd_oe_o=1;
323
                cmd_out_o = 1;
324
        end
325
 
326
        IDLE : begin
327
                cmd_oe_o=0;      //Put CMD to Z  
328
                Delay_Cnt =0;
329
                Cmd_Cnt =0;
330
                CRC_RST =1;
331
                CRC_Enable=0;
332
                CMD_OUT=0;
333
                st_dat_t<=0;
334
                word_select_counter<=0;
335
        end
336
 
337
        WRITE_WR:   begin
338
           FSM_ACK=0;
339
       CRC_RST =0;
340
           CRC_Enable=1;
341
 
342
 
343
 
344
     if (Cmd_Cnt==0) begin
345
       STATUS = 16'b0000_0000_0000_0001;
346
       REQ_OUT=1;
347
     end
348
     else if (Ack_internal_in) begin
349
       REQ_OUT=0;
350
     end
351
 
352
        //Wait one cycle before sending, for setting up the CRC unit.
353
     if (Crc_Buffering==1)  begin
354
        cmd_oe_o =1;
355
        if (`Bit_Nr > 8 ) begin  // 1->40 CMD, (41 >= CNT && CNT <=47) CRC, 48 stop_bit
356
                                   cmd_out_o = In_Buff[`Vector_Index];
357
                                   if (`Bit_Nr > 9 ) begin //1 step ahead
358
                               CRC_OUT = In_Buff[`Vector_Index-1];
359
                             end else begin
360
                               CRC_Enable=0;
361
                                   end
362
                          end
363
                          else if ( (`Bit_Nr <=8) && (`Bit_Nr >=2) ) begin
364
                                  CRC_Enable=0;
365
                                  cmd_out_o = CRC_VAL[(`Bit_Nr)-2];
366
 
367
                          if (block_read & block_write)
368
                            st_dat_t<=2'b11;
369
                          else  if  (block_read)
370
                            st_dat_t<=2'b10;
371
                          end
372
                          else begin
373
                                  cmd_out_o =1'b1;
374
                          end
375
                          Cmd_Cnt = Cmd_Cnt+1 ;
376
                end
377
          else begin //Pre load CRC
378
                    Crc_Buffering=1;
379
                  CRC_OUT = In_Buff[`Vector_Index];
380
          end
381
        end
382
 
383
        WRITE_WO:  begin
384
           FSM_ACK=0;
385
     CRC_RST =0;
386
           CRC_Enable=1;
387
 
388
 
389
     if (Cmd_Cnt==0) begin
390
       STATUS[3:0] = 16'b0000_0000_0000_0010;
391
       REQ_OUT=1;
392
     end
393
     else if (Ack_internal_in) begin
394
       REQ_OUT=0;
395
     end
396
 
397
 
398
 
399
        //Wait one cycle before sending, for setting up the CRC unit.
400
     if (Crc_Buffering==1)  begin
401
        cmd_oe_o =1;
402
        if (`Bit_Nr > 8 ) begin  // 1->40 CMD, (41 >= CNT && CNT <=47) CRC, 48 stop_bit
403
                             cmd_out_o = In_Buff[`Vector_Index];
404
                             if (`Bit_Nr > 9 ) begin //1 step ahead
405
                                CRC_OUT = In_Buff[`Vector_Index-1];
406
                             end
407
           else begin
408
                                CRC_Enable=0;
409
                             end
410
                    end
411
                    else if( (`Bit_Nr <=8) && (`Bit_Nr >=2) ) begin
412
                             CRC_Enable=0;
413
                       cmd_out_o = CRC_VAL[(`Bit_Nr)-2];
414
                       if  (block_read)
415
                            st_dat_t<=2'b10;
416
                    end
417
                   else begin
418
                            cmd_out_o =1'b1;
419
                    end
420
                          Cmd_Cnt = Cmd_Cnt+1;
421
                end
422
                else begin //Pre load CRC
423
                   Crc_Buffering=1;
424
                 CRC_OUT = In_Buff[`Vector_Index];
425
          end
426
        end
427
 
428
        DLY_WR :  begin
429
           if (Delay_Cnt==0) begin
430
         STATUS[3:0] = 4'b0011;
431
         REQ_OUT=1;
432
      end
433
      else if (Ack_internal_in) begin
434
       REQ_OUT=0;
435
     end
436
                  CRC_Enable=0;
437
                  CRC_RST =1;
438
                  Cmd_Cnt = 1;
439
                  cmd_oe_o=0;
440
                  if (Delay_Cnt<3'b111)
441
                    Delay_Cnt =Delay_Cnt+1;
442
                  Crc_Buffering=0;
443
    end
444
 
445
    DLY_WO :  begin
446
      if (Delay_Cnt==0) begin
447
         STATUS[3:0] = 4'b0100;
448
         STATUS[5] = 0;
449
         STATUS[6] = 1;
450
         REQ_OUT=1;
451
      end
452
      else if (Ack_internal_in) begin
453
       REQ_OUT=0;
454
     end
455
                  CRC_Enable=0;
456
                  CRC_RST =1;
457
                  Cmd_Cnt = 0;
458
                  cmd_oe_o=0;
459
            Delay_Cnt =Delay_Cnt+1;
460
            Crc_Buffering=0;
461
    end
462
 
463
    READ_WR :  begin
464
      Delay_Cnt =0;
465
      CRC_RST =0;
466
            CRC_Enable=1;
467
      cmd_oe_o =0;
468
 
469
           if (Cmd_Cnt==1) begin
470
       STATUS[3:0] = 16'b0000_0000_0000_0101;
471
       REQ_OUT=1;
472
       Out_Buff[39]=0; //startbit (0)
473
     end
474
     else if (Ack_internal_in) begin
475
       REQ_OUT=0;
476
     end
477
 
478
 
479
 
480
      if (Cmd_Cnt < (Response_Size))begin
481
 
482
        if (Cmd_Cnt<8 ) //1+1+6 (S,T,Index)          
483
          Out_Buff[39-Cmd_Cnt] = cmd_dat_i;
484
        else begin
485
 
486
          if (word_select == 2'b00) begin
487
            if(Cmd_Cnt<40) begin
488
                          word_select_counter<= word_select_counter+1;
489
                          Out_Buff[31-word_select_counter] = cmd_dat_i;
490
                         end
491
                      end
492
          else if (word_select == 2'b01) begin
493
            if ( (Cmd_Cnt>=40) && (Cmd_Cnt<72) )begin
494
                          word_select_counter<= word_select_counter+1;
495
                          Out_Buff[31-word_select_counter] = cmd_dat_i;
496
                         end
497
 
498
                      end
499
          else if  (word_select == 2'b10) begin
500
           if ( (Cmd_Cnt>=72) && (Cmd_Cnt<104) )begin
501
                          word_select_counter<= word_select_counter+1;
502
                          Out_Buff[31-word_select_counter] = cmd_dat_i;
503
                         end
504
                      end
505
          else if  (word_select == 2'b11) begin
506
           if ( (Cmd_Cnt>=104) && (Cmd_Cnt<128) )begin
507
                          word_select_counter<= word_select_counter+1;
508
                          Out_Buff[31-word_select_counter] = cmd_dat_i;
509
                         end
510
                      end
511
 
512
 
513
                    end
514
                    CRC_OUT = cmd_dat_i;
515
 
516
      end
517
      else if ( Cmd_Cnt - Response_Size <=6 ) begin
518
                          CRC_IN [(Response_Size+6)-(Cmd_Cnt)] = cmd_dat_i;
519
                          CRC_Enable=0;
520
      end
521
      else begin
522
                           if ((CRC_IN != CRC_VAL) && ( CRC_Check_On == 1)) begin
523
                                   CRC_Valid=0;
524
                                   CRC_Enable=0;
525
                        end
526
                        else begin
527
                        CRC_Valid=1;
528
                        CRC_Enable=0;
529
                        end
530
                        if (block_read & block_write)
531
                            st_dat_t<=2'b11;
532
                        else if (block_write)
533
                          st_dat_t<=2'b01;
534
 
535
      end
536
       Cmd_Cnt = Cmd_Cnt+1;
537
   end
538
 
539
   DLY_READ:  begin
540
 
541
     if (Delay_Cnt==0) begin
542
       STATUS[3:0] = 4'b0110;
543
       STATUS[5] = CRC_Valid;
544
       STATUS[6] = 1;
545
       REQ_OUT=1;
546
     end
547
     else if (Ack_internal_in) begin
548
       REQ_OUT=0;
549
     end
550
 
551
                  CRC_Enable=0;
552
                  CRC_RST =1;
553
                  Cmd_Cnt = 0;
554
                  cmd_oe_o=0;
555
 
556
      CMD_OUT[39:0]=Out_Buff;
557
                  Delay_Cnt =Delay_Cnt+1;
558
    end
559
 
560
        ACK_WO:  begin
561
                  FSM_ACK=1;
562
    end
563
 
564
        ACK_WR:  begin
565
                  FSM_ACK=1;
566
                  REQ_OUT =0;
567
 
568
    end
569
 
570
   endcase
571
  end
572
end
573
 
574
 
575
endmodule
576
 
577
 

powered by: WebSVN 2.1.0

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