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_fifo/] [verilog/] [sd_controller_fifo_actel.v] - Blame information for rev 107

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 95 tac2
module sd_controller_fifo_wba
2
(
3
  wb_clk_i, wb_rst_i, wb_dat_i, wb_dat_o,
4
  wb_adr_i, wb_sel_i, wb_we_i, wb_cyc_i, wb_stb_i, wb_ack_o,
5
  sd_cmd_dat_i,sd_cmd_out_o,  sd_cmd_oe_o,
6
  sd_dat_dat_i, sd_dat_out_o , sd_dat_oe_o, sd_clk_o_pad
7
);
8
input           wb_clk_i;
9
input           wb_rst_i;
10
input   [7:0]  wb_dat_i;
11
output  [7:0]  wb_dat_o;
12
input   [2:0]  wb_adr_i;
13
input    [3:0]  wb_sel_i;
14
input           wb_we_i;
15
input           wb_cyc_i;
16
input           wb_stb_i;
17
output reg          wb_ack_o;
18
input wire [3:0] sd_dat_dat_i;
19
output wire [3:0] sd_dat_out_o;
20
output wire sd_dat_oe_o;
21
input wire sd_cmd_dat_i;
22
output wire sd_cmd_out_o;
23
output wire sd_cmd_oe_o;
24
output sd_clk_o_pad;
25
wire sd_clk_i;
26
reg [7:0] controll_reg;
27
reg [7:0] status_reg;
28
reg [7:0] command_timeout_reg;
29
  assign sd_clk_i = wb_clk_i;
30
assign sd_clk_o=sd_clk_i;
31
reg [1:0] wb_fifo_adr_i_writer;
32
reg [1:0] wb_fifo_adr_i_reader;
33
wire [1:0] wb_fifo_adr_i;
34
reg add_token_read;
35
wire [7:0] wb_fifo_dat_i;
36
wire [7:0] wb_fifo_dat_o;
37
reg [7:0]  wb_dat_i_storage;
38
reg [7:0] wb_dat_o_i;
39
reg time_enable;
40
assign sd_clk_o_pad  = sd_clk_i ;
41
assign wb_fifo_adr_i = add_token_read ? wb_fifo_adr_i_reader : wb_fifo_adr_i_writer;
42
assign wb_fifo_dat_i =wb_dat_i_storage;
43
assign wb_dat_o = wb_adr_i[0] ? wb_fifo_dat_o :   wb_dat_o_i ;
44
wire [1:4]fifo_full ;
45
wire [1:4]fifo_empty;
46
reg wb_fifo_we_i;
47
reg wb_fifo_re_i;
48
wire [1:0] sd_adr_o;
49
wire [7:0] sd_dat_o;
50
wire [7:0] sd_dat_i;
51
sd_fifo sd_fifo_0
52
(
53
   .wb_adr_i  (wb_fifo_adr_i ),
54
   .wb_dat_i  (wb_fifo_dat_i),
55
   .wb_dat_o  (wb_fifo_dat_o ),
56
   .wb_we_i   (wb_fifo_we_i),
57
   .wb_re_i   (wb_fifo_re_i),
58
   .wb_clk  (wb_clk_i),
59
   .sd_adr_i (sd_adr_o ),
60
   .sd_dat_i (sd_dat_o),
61
   .sd_dat_o (sd_dat_i ),
62
   .sd_we_i (sd_we_o),
63
   .sd_re_i (sd_re_o),
64
   .sd_clk (sd_clk_o),
65
   .fifo_full ( fifo_full ),
66
   .fifo_empty (fifo_empty    ),
67
   .rst (wb_rst_i)
68
  ) ;
69
wire [1:0] sd_adr_o_cmd;
70
wire [7:0] sd_dat_i_cmd;
71
wire [7:0] sd_dat_o_cmd;
72
wire [1:0] sd_adr_o_dat;
73
wire [7:0] sd_dat_i_dat;
74
wire [7:0] sd_dat_o_dat;
75
wire [1:0] st_dat_t;
76
sd_cmd_phy sdc_cmd_phy_0
77
(
78
  .sd_clk (sd_clk_o),
79
  .rst (wb_rst_i ),
80
  .cmd_dat_i ( sd_cmd_dat_i  ),
81
  .cmd_dat_o (sd_cmd_out_o   ),
82
  .cmd_oe_o (sd_cmd_oe_o   ),
83
  .sd_adr_o (sd_adr_o_cmd),
84
  .sd_dat_i (sd_dat_i_cmd),
85
  .sd_dat_o (sd_dat_o_cmd),
86
  .sd_we_o (sd_we_o_cmd),
87
  .sd_re_o (sd_re_o_cmd),
88
  .fifo_full ( fifo_full[1:2] ),
89
  .fifo_empty ( fifo_empty [1:2]),
90
  .start_dat_t (st_dat_t),
91
  .fifo_acces_token (fifo_acces_token)
92
  );
93
  sd_data_phy sd_data_phy_0 (
94
  .sd_clk (sd_clk_o),
95
  .rst (wb_rst_i | controll_reg[0]),
96
  .DAT_oe_o ( sd_dat_oe_o  ),
97
  .DAT_dat_o (sd_dat_out_o),
98
  .DAT_dat_i  (sd_dat_dat_i ),
99
  .sd_adr_o (sd_adr_o_dat   ),
100
  .sd_dat_i (sd_dat_i_dat  ),
101
  .sd_dat_o (sd_dat_o_dat  ),
102
  .sd_we_o  (sd_we_o_dat),
103
  .sd_re_o (sd_re_o_dat),
104
  .fifo_full ( fifo_full[3:4] ),
105
  .fifo_empty ( fifo_empty [3:4]),
106
  .start_dat (st_dat_t),
107
  .fifo_acces (~fifo_acces_token)
108
  );
109
  assign sd_adr_o =  fifo_acces_token ? sd_adr_o_cmd : sd_adr_o_dat;
110
  assign sd_dat_o =  fifo_acces_token ? sd_dat_o_cmd : sd_dat_o_dat;
111
  assign sd_we_o  = fifo_acces_token ? sd_we_o_cmd : sd_we_o_dat;
112
  assign sd_re_o  =  fifo_acces_token ? sd_re_o_cmd : sd_re_o_dat;
113
 assign sd_dat_i_dat = sd_dat_i;
114
 assign sd_dat_i_cmd = sd_dat_i;
115
  always @(posedge wb_clk_i or posedge wb_rst_i)
116
        begin
117
        if (wb_rst_i)
118
            status_reg<=0;
119
          else begin
120
      status_reg[0] <= fifo_full[1];
121
      status_reg[1] <= fifo_empty[2];
122
      status_reg[2] <=  fifo_full[3];
123
      status_reg[3] <=  fifo_empty[4];
124
    end
125
  end
126
  reg delayed_ack;
127
  always @(posedge wb_clk_i or posedge wb_rst_i)
128
        begin
129
          if (wb_rst_i)
130
            wb_ack_o <=0;
131
           else
132
             wb_ack_o <=wb_stb_i & wb_cyc_i &  ~wb_ack_o & delayed_ack;
133
        end
134
  always @(posedge wb_clk_i or posedge wb_rst_i)
135
        begin
136
    if ( wb_rst_i )begin
137
            command_timeout_reg<=255;
138
            wb_dat_i_storage<=0;
139
            controll_reg<=0;
140
            wb_fifo_we_i<=0;
141
            wb_fifo_adr_i_writer<=0;
142
            time_enable<=0;
143
          end
144
          else if (wb_stb_i  & wb_cyc_i & (~wb_ack_o))begin
145
            if (wb_we_i) begin
146
              case (wb_adr_i)
147
              4'h0 : begin
148
                wb_fifo_adr_i_writer<=0;
149
                wb_fifo_we_i<=1&!delayed_ack;
150
                wb_dat_i_storage<=wb_dat_i;
151
                command_timeout_reg<=255;
152
                time_enable<=1;
153
              end
154
        4'h2 : begin
155
                wb_fifo_adr_i_writer<=2;
156
                wb_fifo_we_i<=1&!delayed_ack;
157
                wb_dat_i_storage<=wb_dat_i;
158
                command_timeout_reg<=255;
159
                time_enable<=0;
160
              end
161
        4'h5 : controll_reg <= wb_dat_i;
162
              endcase
163
            end
164
           end
165
           else begin
166
              wb_fifo_we_i<=0;
167
             if (!status_reg[1])
168
               time_enable<=0;
169
             if ((command_timeout_reg!=0) && (time_enable))
170
                 command_timeout_reg<=command_timeout_reg-1;
171
           end
172
end
173
always @(posedge wb_clk_i or posedge wb_rst_i )begin
174
   if ( wb_rst_i) begin
175
     add_token_read<=0;
176
     delayed_ack<=0;
177
     wb_fifo_re_i<=0;
178
      wb_fifo_adr_i_reader<=0;
179
      wb_dat_o_i<=0;
180
  end
181
 else begin
182
    delayed_ack<=0;
183
    wb_fifo_re_i<=0;
184
   if (wb_stb_i  & wb_cyc_i & (~wb_ack_o)) begin
185
   delayed_ack<=delayed_ack+1;
186
    add_token_read<=0;
187
    if (!wb_we_i) begin
188
      case (wb_adr_i)
189
      4'h1 : begin
190
         add_token_read<=1;
191
         wb_fifo_adr_i_reader<=1;
192
              wb_fifo_re_i<=1&delayed_ack;
193
      end
194
      4'h3 :begin
195
         add_token_read<=1;
196
         wb_fifo_adr_i_reader<=3;
197
               wb_fifo_re_i<=1 & delayed_ack;
198
     end
199
      4'h4 : wb_dat_o_i <= status_reg;
200
      4'h6 : wb_dat_o_i <= command_timeout_reg;
201
     endcase
202
    end
203
  end
204
end
205
end
206
endmodule
207
module sd_cmd_phy (
208
input sd_clk,
209
input rst,
210
input  cmd_dat_i,
211
output reg cmd_dat_o,
212
output reg cmd_oe_o,
213
output  [1:0] sd_adr_o,
214
input [7:0] sd_dat_i,
215
output reg [7:0] sd_dat_o,
216
output reg sd_we_o,
217
output reg sd_re_o,
218
input  [1:2] fifo_full,
219
input [1:2] fifo_empty,
220
output  [1:0]  start_dat_t,
221
output fifo_acces_token
222
);
223
reg [6:0] Response_Size;
224
parameter SEND_SIZE = 48;
225
parameter CONTENT_SIZE = 40;
226
parameter NCR = 2 ;
227
parameter SIZE = 5;
228
parameter
229
INIT          = 5'b00001,
230
IDLE          = 5'b00010,
231
WRITE         = 5'b00100,
232
BUFFER_WRITE  = 5'b01000,
233
READ          = 5'b10000;
234
reg [SIZE-1:0] state;
235
reg [SIZE-1:0] next_state;
236
reg [1:0] start_dat_t_read;
237
reg [1:0] start_dat_t_write;
238
reg [39:0] in_buffer;
239
reg [2:0] read_byte_cnt;
240
reg [7:0] cmd_flow_cnt_write;
241
reg [7:0] cmd_flow_cnt_read;
242
reg cmd_dat_internal;
243
reg big_resp;
244
reg  crc_rst_write;
245
reg  crc_en_write;
246
reg  crc_in_write;
247
wire [6:0] crc_val_write;
248
reg [1:0] sd_adr_o_read;
249
reg [1:0] sd_adr_o_write;
250
reg  crc_rst_read;
251
reg  crc_en_read;
252
reg  crc_in_read;
253
wire [6:0] crc_val_read;
254
reg crc_buffering_write;
255
reg block_write;
256
reg block_read;
257
reg in_buff_ptr;
258
reg out_buff_ptr;
259
reg [2:0] read_index_cnt;
260
reg  [7:0] in_buff_0;
261
reg  [7:0] in_buff_1;
262
reg [6:0] crc_in_buff;
263
reg [7:0] response_status;
264
reg [6:0] index_check;
265
reg add_token_read;
266
CRC_7 CRC_7_WRITE(
267
.BITVAL (crc_in_write),
268
.Enable (crc_en_write),
269
.CLK (sd_clk),
270
.RST (crc_rst_write),
271
.CRC (crc_val_write));
272
CRC_7 CRC_7_READ(
273
.BITVAL (crc_in_read),
274
.Enable (crc_en_read),
275
.CLK (sd_clk),
276
.RST (crc_rst_read),
277
.CRC (crc_val_read));
278
always @ (posedge sd_clk or posedge rst )
279
begin
280
        if  (rst) begin
281
                cmd_dat_internal <=1'b1;
282
        end
283
        else begin
284
                cmd_dat_internal<=cmd_dat_i;
285
        end
286
end
287
always @ (state or cmd_flow_cnt_write or cmd_dat_internal or fifo_empty [1] or read_byte_cnt or cmd_flow_cnt_write or cmd_flow_cnt_read )
288
begin : FSM_COMBO
289
 next_state  = 0;
290
case(state)
291
INIT: begin
292
  if (cmd_flow_cnt_write >= 64 )begin
293
     next_state = IDLE;
294
  end
295
  else begin
296
     next_state = INIT;
297
  end
298
end
299
IDLE: begin
300
    if (!fifo_empty [1])
301
      next_state =BUFFER_WRITE;
302
    else if (!cmd_dat_internal)
303
      next_state =READ;
304
    else
305
      next_state =IDLE;
306
end
307
BUFFER_WRITE: begin
308
  if (read_byte_cnt>=5)
309
   next_state = WRITE;
310
  else
311
   next_state =BUFFER_WRITE;
312
end
313
WRITE : begin
314
     if (cmd_flow_cnt_write >= SEND_SIZE)
315
        next_state = IDLE;
316
      else
317
        next_state = WRITE;
318
end
319
READ : begin
320
      if (cmd_flow_cnt_read >= Response_Size+7)
321
        next_state = IDLE;
322
      else
323
        next_state = READ;
324
end
325
default : next_state  = INIT;
326
 endcase
327
end
328
always @ (posedge sd_clk or posedge rst  )
329
begin : FSM_SEQ
330
  if (rst ) begin
331
    state <= #1 INIT;
332
 end
333
 else begin
334
    state <= #1 next_state;
335
 end
336
end
337
reg fifo_acces_read,fifo_acces_write;
338
assign fifo_acces_token = fifo_acces_read | fifo_acces_write;
339
assign sd_adr_o = add_token_read ? sd_adr_o_read : sd_adr_o_write;
340
assign start_dat_t = add_token_read ?  start_dat_t_read : start_dat_t_write;
341
reg tx_cmd_fifo_empty_tmp;
342
always @ (negedge sd_clk or posedge rst  )
343
begin : OUTPUT_LOGIC
344
 if (rst  ) begin
345
   crc_in_write=0;
346
   crc_en_write=0;
347
   crc_rst_write=0;
348
   fifo_acces_write=0;
349
   cmd_oe_o=1;
350
   cmd_dat_o = 1;
351
   crc_buffering_write=0;
352
   sd_re_o<=0;
353
   read_byte_cnt<=0;
354
   block_read<=0;
355
   sd_adr_o_write<=0;
356
   cmd_flow_cnt_write=0;
357
   start_dat_t_write<=0;
358
   in_buffer<=0;
359
    tx_cmd_fifo_empty_tmp<=0;
360
    Response_Size<=40;
361
 end
362
 else begin
363
  case(state)
364
    INIT : begin
365
      cmd_flow_cnt_write=cmd_flow_cnt_write+1;
366
      cmd_oe_o=1;
367
      cmd_dat_o = 1;
368
      crc_buffering_write=0;
369
      start_dat_t_write<=0;
370
    end
371
    IDLE: begin
372
       cmd_flow_cnt_write=0;
373
       cmd_oe_o=0;
374
       start_dat_t_write<=0;
375
       crc_in_write=0;
376
       crc_en_write=0;
377
       crc_rst_write=1;
378
       read_byte_cnt<=0;
379
       block_read<=0;
380
       fifo_acces_write=0;
381
       in_buffer<=0;
382
    end
383
     BUFFER_WRITE : begin
384
      sd_re_o<=0;
385
      fifo_acces_write=1;
386
      tx_cmd_fifo_empty_tmp<=fifo_empty [1];
387
       if (!tx_cmd_fifo_empty_tmp) begin
388
        if(sd_re_o)
389
          read_byte_cnt <= read_byte_cnt+1;
390
        sd_adr_o_write <=0;
391
        sd_re_o<=1;
392
       if(sd_re_o) begin
393
         case (read_byte_cnt)
394
          0: in_buffer[39:32] <=sd_dat_i;
395
          1: in_buffer[31:24] <=sd_dat_i;
396
          2: in_buffer[23:16] <=sd_dat_i;
397
           3: in_buffer[15:8] <=sd_dat_i;
398
           4: in_buffer[7:0] <=sd_dat_i;
399
         endcase
400
         if (in_buffer[39])
401
           Response_Size<=127;
402
         else
403
           Response_Size<=40;
404
         if (in_buffer[37:32] == 32'h11)
405
               block_read<=1;
406
      end
407
    end
408
   end
409
    WRITE: begin
410
       sd_re_o<=0;
411
       cmd_oe_o=1;
412
       cmd_dat_o = 1;
413
       crc_en_write =0;
414
       crc_rst_write=0;
415
        crc_en_write=1;
416
      if (crc_buffering_write==1)  begin
417
        cmd_oe_o =1;
418
        if ((SEND_SIZE-cmd_flow_cnt_write) > 8 ) begin
419
                                   if (cmd_flow_cnt_write==0)
420
                                    cmd_dat_o = 0;
421
                                   else
422
                                    cmd_dat_o = in_buffer[(CONTENT_SIZE-1-cmd_flow_cnt_write)];
423
                                   if ((SEND_SIZE-cmd_flow_cnt_write) > 9 ) begin
424
                               crc_in_write = in_buffer[(CONTENT_SIZE-1-cmd_flow_cnt_write)-1];
425
                             end else begin
426
                               crc_en_write=0;
427
                                   end
428
                          end
429
                          else if ( ((SEND_SIZE-cmd_flow_cnt_write) <=8) && ((SEND_SIZE-cmd_flow_cnt_write) >=2) ) begin
430
                                  crc_en_write=0;
431
                                  cmd_dat_o = crc_val_write[((SEND_SIZE-cmd_flow_cnt_write))-2];
432
                                   if (block_read)
433
             start_dat_t_write<=2'b10;
434
                          end
435
                          else begin
436
                                  cmd_dat_o =1'b1;
437
                          end
438
                         cmd_flow_cnt_write=cmd_flow_cnt_write+1;
439
                end
440
          else begin
441
                    crc_buffering_write=1;
442
                  crc_in_write = 0;
443
          end
444
    end
445
  endcase
446
 end
447
end
448
always @ (posedge sd_clk or posedge rst  )
449
begin
450
  if (rst) begin
451
   crc_rst_read=1;
452
   crc_en_read=0;
453
   crc_in_read=0;
454
   cmd_flow_cnt_read=0;
455
   response_status =0;
456
   block_write=0;
457
   index_check=0;
458
   in_buff_ptr=0;
459
   out_buff_ptr=0;
460
   sd_adr_o_read<=0;
461
   add_token_read=0;
462
   in_buff_0<=0;
463
   in_buff_1<=0;
464
   read_index_cnt=0;
465
    fifo_acces_read=0;
466
    sd_dat_o<=0;
467
    start_dat_t_read<=0;
468
    sd_we_o<=0;
469
    crc_in_buff=0;
470
  end
471
  else begin
472
   case (state)
473
   IDLE : begin
474
        crc_en_read=0;
475
        crc_rst_read=1;
476
        cmd_flow_cnt_read=1;
477
        index_check=0;
478
        block_write=0;
479
        in_buff_ptr=0;
480
        out_buff_ptr=0;
481
        add_token_read=0;
482
        read_index_cnt=0;
483
        sd_we_o<=0;
484
        add_token_read=0;
485
         fifo_acces_read=0;
486
         start_dat_t_read<=0;
487
   end
488
   READ : begin
489
      fifo_acces_read=1;
490
      add_token_read=1;
491
      crc_en_read=1;
492
      crc_rst_read=0;
493
      sd_we_o<=0;
494
     if (in_buff_ptr != out_buff_ptr) begin
495
     sd_adr_o_read <=1;
496
     sd_we_o<=1;
497
       if (in_buff_ptr)
498
        sd_dat_o <=in_buff_0;
499
      else
500
        sd_dat_o <=in_buff_1;
501
     out_buff_ptr=out_buff_ptr+1;
502
     end
503
     if (cmd_flow_cnt_read < (Response_Size))begin
504
        crc_in_read = cmd_dat_internal;
505
        if (cmd_flow_cnt_read<8 ) begin
506
          index_check[7-cmd_flow_cnt_read] = cmd_dat_internal;
507
          if (index_check[5:0] == 32'h18) begin
508
             block_write=1;
509
          end
510
        end
511
        else begin
512
          if (!in_buff_ptr) begin
513
             in_buff_0[7-read_index_cnt]<=cmd_dat_internal;
514
          end
515
          else begin
516
             in_buff_1[7-read_index_cnt]<=cmd_dat_internal;
517
          end
518
          read_index_cnt=read_index_cnt+1;
519
          if (read_index_cnt==0)
520
             in_buff_ptr=in_buff_ptr+1;
521
        end
522
       end
523
        else if ( cmd_flow_cnt_read - Response_Size <=6 ) begin
524
                          crc_in_buff [(Response_Size+6)-(cmd_flow_cnt_read)] = cmd_dat_internal;
525
                          crc_en_read=0;
526
      end
527
      else begin
528
                           if ((crc_in_buff != crc_val_read)) begin
529
                                   response_status[0]=1;
530
                        end
531
                        else begin
532
                          response_status[0]=0;
533
                        end
534
                        sd_adr_o_read <=1;
535
                         sd_we_o<=1;
536
                        sd_dat_o<=response_status;
537
                     if (block_write)
538
                          start_dat_t_read<=2'b01;
539
      end
540
       cmd_flow_cnt_read = cmd_flow_cnt_read+1;
541
   end
542
  endcase
543
  end
544
end
545
endmodule
546
module sd_fifo
547
  (
548
    input  [1:0] wb_adr_i,
549
    input [7:0]  wb_dat_i,
550
    output [7:0] wb_dat_o,
551
    input        wb_we_i,
552
    input        wb_re_i,
553
    input        wb_clk,
554
    input [1:0]  sd_adr_i,
555
    input [7:0]  sd_dat_i,
556
    output [7:0] sd_dat_o,
557
    input        sd_we_i,
558
    input        sd_re_i,
559
    input        sd_clk,
560
    output [1:4] fifo_full,
561
    output [1:4] fifo_empty,
562
    input        rst
563
   );
564
   wire [8:0]     wptr1, rptr1, wptr2, rptr2, wptr3, rptr3, wptr4, rptr4;
565
   wire [8:0]     wadr1, radr1, wadr2, radr2, wadr3, radr3, wadr4, radr4;
566
   wire          dpram_we_a, dpram_we_b;
567
   wire [10:0]    dpram_a_a, dpram_a_b;
568
   sd_counter wptr1a
569
     (
570
      .q(wptr1),
571
      .q_bin(wadr1),
572
      .cke((wb_adr_i==2'd0) & wb_we_i & !fifo_full[1]),
573
      .clk(wb_clk),
574
      .rst(rst)
575
      );
576
   sd_counter rptr1a
577
     (
578
      .q(rptr1),
579
      .q_bin(radr1),
580
      .cke((sd_adr_i==2'd0) & sd_re_i & !fifo_empty[1]),
581
      .clk(sd_clk),
582
      .rst(rst)
583
      );
584
  versatile_fifo_async_cmp
585
    #
586
    (
587
     .ADDR_WIDTH(9)
588
     )
589
    cmp1
590
    (
591
      .wptr(wptr1),
592
      .rptr(rptr1),
593
      .fifo_empty(fifo_empty[1]),
594
      .fifo_full(fifo_full[1]),
595
      .wclk(wb_clk),
596
      .rclk(sd_clk),
597
      .rst(rst)
598
      );
599
   sd_counter wptr2a
600
     (
601
      .q(wptr2),
602
      .q_bin(wadr2),
603
      .cke((sd_adr_i==2'd1) & sd_we_i & !fifo_full[2]),
604
      .clk(sd_clk),
605
      .rst(rst)
606
      );
607
   sd_counter rptr2a
608
     (
609
      .q(rptr2),
610
      .q_bin(radr2),
611
      .cke((wb_adr_i==2'd1) & wb_re_i & !fifo_empty[2]),
612
      .clk(wb_clk),
613
      .rst(rst)
614
      );
615
  versatile_fifo_async_cmp
616
    #
617
    (
618
     .ADDR_WIDTH(9)
619
     )
620
    cmp2
621
    (
622
      .wptr(wptr2),
623
      .rptr(rptr2),
624
      .fifo_empty(fifo_empty[2]),
625
      .fifo_full(fifo_full[2]),
626
      .wclk(sd_clk),
627
      .rclk(wb_clk),
628
      .rst(rst)
629
      );
630
   sd_counter wptr3a
631
     (
632
      .q(wptr3),
633
      .q_bin(wadr3),
634
      .cke((wb_adr_i==2'd2) & wb_we_i & !fifo_full[3]),
635
      .clk(wb_clk),
636
      .rst(rst)
637
      );
638
   sd_counter rptr3a
639
     (
640
      .q(rptr3),
641
      .q_bin(radr3),
642
      .cke((sd_adr_i==2'd2) & sd_re_i & !fifo_empty[3]),
643
      .clk(sd_clk),
644
      .rst(rst)
645
      );
646
  versatile_fifo_async_cmp
647
    #
648
    (
649
     .ADDR_WIDTH(9)
650
     )
651
    cmp3
652
    (
653
      .wptr(wptr3),
654
      .rptr(rptr3),
655
      .fifo_empty(fifo_empty[3]),
656
      .fifo_full(fifo_full[3]),
657
      .wclk(wb_clk),
658
      .rclk(sd_clk),
659
      .rst(rst)
660
      );
661
   sd_counter wptr4a
662
     (
663
      .q(wptr4),
664
      .q_bin(wadr4),
665
      .cke((sd_adr_i==2'd3) & sd_we_i & !fifo_full[4]),
666
      .clk(sd_clk),
667
      .rst(rst)
668
      );
669
   sd_counter rptr4a
670
     (
671
      .q(rptr4),
672
      .q_bin(radr4),
673
      .cke((wb_adr_i==2'd3) & wb_re_i & !fifo_empty[4]),
674
      .clk(wb_clk),
675
      .rst(rst)
676
      );
677
  versatile_fifo_async_cmp
678
    #
679
    (
680
     .ADDR_WIDTH(9)
681
     )
682
    cmp4
683
    (
684
      .wptr(wptr4),
685
      .rptr(rptr4),
686
      .fifo_empty(fifo_empty[4]),
687
      .fifo_full(fifo_full[4]),
688
      .wclk(sd_clk),
689
      .rclk(wb_clk),
690
      .rst(rst)
691
      );
692
   assign dpram_we_a = ((wb_adr_i==2'd0) & !fifo_full[1]) ? wb_we_i :
693
                       ((wb_adr_i==2'd2) & !fifo_full[3]) ? wb_we_i :
694
                       1'b0;
695
   assign dpram_we_b = ((sd_adr_i==2'd1) & !fifo_full[2]) ? sd_we_i :
696
                       ((sd_adr_i==2'd3) & !fifo_full[4]) ? sd_we_i :
697
                       1'b0;
698
   assign dpram_a_a = (wb_adr_i==2'd0) ? {wb_adr_i,wadr1} :
699
                      (wb_adr_i==2'd1) ? {wb_adr_i,radr2} :
700
                      (wb_adr_i==2'd2) ? {wb_adr_i,wadr3} :
701
                      {wb_adr_i,radr4};
702
   assign dpram_a_b = (sd_adr_i==2'd0) ? {sd_adr_i,radr1} :
703
                      (sd_adr_i==2'd1) ? {sd_adr_i,wadr2} :
704
                      (sd_adr_i==2'd2) ? {sd_adr_i,radr3} :
705
                      {sd_adr_i,wadr4};
706
   versatile_fifo_dptam_dw
707
     dpram
708
     (
709
      .d_a(wb_dat_i),
710
      .q_a(wb_dat_o),
711
      .adr_a(dpram_a_a),
712
      .we_a(dpram_we_a),
713
      .clk_a(wb_clk),
714
      .q_b(sd_dat_o),
715
      .adr_b(dpram_a_b),
716
      .d_b(sd_dat_i),
717
      .we_b(dpram_we_b),
718
      .clk_b(sd_clk)
719
      );
720
endmodule
721
module sd_counter
722
  (
723
    output reg [9:1] q,
724
    output [9:1]    q_bin,
725
    input cke,
726
    input clk,
727
    input rst
728
   );
729
   reg [9:1] qi;
730
   wire [9:1] q_next;
731
   assign q_next =
732
   qi + 9'd1;
733
   always @ (posedge clk or posedge rst)
734
     if (rst)
735
       qi <= 9'd0;
736
     else
737
   if (cke)
738
     qi <= q_next;
739
   always @ (posedge clk or posedge rst)
740
     if (rst)
741
       q <= 9'd0;
742
     else
743
       if (cke)
744
         q <= (q_next>>1) ^ q_next;
745
   assign q_bin = qi;
746
endmodule
747
module versatile_fifo_async_cmp ( wptr, rptr, fifo_empty, fifo_full, wclk, rclk, rst );
748
   parameter ADDR_WIDTH = 4;
749
   parameter N = ADDR_WIDTH-1;
750
   parameter Q1 = 2'b00;
751
   parameter Q2 = 2'b01;
752
   parameter Q3 = 2'b11;
753
   parameter Q4 = 2'b10;
754
   parameter going_empty = 1'b0;
755
   parameter going_full  = 1'b1;
756
   input [N:0]  wptr, rptr;
757
   output reg   fifo_empty, fifo_full;
758
   input        wclk, rclk, rst;
759
   reg  direction, direction_set, direction_clr;
760
   wire async_empty, async_full;
761
   reg  fifo_full2, fifo_empty2;
762
   always @ (wptr[N:N-1] or rptr[N:N-1])
763
     case ({wptr[N:N-1],rptr[N:N-1]})
764
       {Q1,Q2} : direction_set <= 1'b1;
765
       {Q2,Q3} : direction_set <= 1'b1;
766
       {Q3,Q4} : direction_set <= 1'b1;
767
       {Q4,Q1} : direction_set <= 1'b1;
768
       default : direction_set <= 1'b0;
769
     endcase
770
   always @ (wptr[N:N-1] or rptr[N:N-1] or rst)
771
     if (rst)
772
       direction_clr <= 1'b1;
773
     else
774
       case ({wptr[N:N-1],rptr[N:N-1]})
775
         {Q2,Q1} : direction_clr <= 1'b1;
776
         {Q3,Q2} : direction_clr <= 1'b1;
777
         {Q4,Q3} : direction_clr <= 1'b1;
778
         {Q1,Q4} : direction_clr <= 1'b1;
779
         default : direction_clr <= 1'b0;
780
       endcase
781
   always @ (posedge direction_set or posedge direction_clr)
782
     if (direction_clr)
783
       direction <= going_empty;
784
     else
785
       direction <= going_full;
786
   assign async_empty = (wptr == rptr) && (direction==going_empty);
787
   assign async_full  = (wptr == rptr) && (direction==going_full);
788
   always @ (posedge wclk or posedge rst or posedge async_full)
789
     if (rst)
790
       {fifo_full, fifo_full2} <= 2'b00;
791
     else if (async_full)
792
       {fifo_full, fifo_full2} <= 2'b11;
793
     else
794
       {fifo_full, fifo_full2} <= {fifo_full2, async_full};
795
   always @ (posedge rclk or posedge async_empty)
796
     if (async_empty)
797
       {fifo_empty, fifo_empty2} <= 2'b11;
798
     else
799
       {fifo_empty,fifo_empty2} <= {fifo_empty2,async_empty};
800
endmodule
801
module CRC_7(BITVAL, Enable, CLK, RST, CRC);
802
   input        BITVAL;
803
   input Enable;
804
   input        CLK;
805
   input        RST;
806
   output [6:0] CRC;
807
   reg    [6:0] CRC;
808
   wire         inv;
809
   assign inv = BITVAL ^ CRC[6];
810
    always @(posedge CLK or posedge RST) begin
811
                if (RST) begin
812
                        CRC = 0;
813
        end
814
                else begin
815
                        if (Enable==1) begin
816
                                CRC[6] = CRC[5];
817
                                CRC[5] = CRC[4];
818
                                CRC[4] = CRC[3];
819
                                CRC[3] = CRC[2] ^ inv;
820
                                CRC[2] = CRC[1];
821
                                CRC[1] = CRC[0];
822
                                CRC[0] = inv;
823
                        end
824
                end
825
     end
826
endmodule
827
module CRC_16(BITVAL, Enable, CLK, RST, CRC);
828
 input        BITVAL;
829
   input Enable;
830
   input        CLK;
831
   input        RST;
832
   output reg [15:0] CRC;
833
   wire         inv;
834
   assign inv = BITVAL ^ CRC[15];
835
  always @(posedge CLK or posedge RST) begin
836
                if (RST) begin
837
                        CRC = 0;
838
        end
839
      else begin
840
        if (Enable==1) begin
841
         CRC[15] = CRC[14];
842
         CRC[14] = CRC[13];
843
         CRC[13] = CRC[12];
844
         CRC[12] = CRC[11] ^ inv;
845
         CRC[11] = CRC[10];
846
         CRC[10] = CRC[9];
847
         CRC[9] = CRC[8];
848
         CRC[8] = CRC[7];
849
         CRC[7] = CRC[6];
850
         CRC[6] = CRC[5];
851
         CRC[5] = CRC[4] ^ inv;
852
         CRC[4] = CRC[3];
853
         CRC[3] = CRC[2];
854
         CRC[2] = CRC[1];
855
         CRC[1] = CRC[0];
856
         CRC[0] = inv;
857
        end
858
         end
859
      end
860
endmodule
861
module sd_data_phy(
862
input sd_clk,
863
input rst,
864
output reg DAT_oe_o,
865
output reg[3:0] DAT_dat_o,
866
input  [3:0] DAT_dat_i,
867
output  [1:0] sd_adr_o,
868
input [7:0] sd_dat_i,
869
output reg [7:0] sd_dat_o,
870
output reg sd_we_o,
871
output reg sd_re_o,
872
input  [3:4] fifo_full,
873
input [3:4] fifo_empty,
874
input  [1:0] start_dat,
875
input fifo_acces
876
);
877
 reg [5:0] in_buff_ptr_read;
878
 reg [5:0] out_buff_ptr_read;
879
 reg crc_ok;
880
 reg [3:0] last_din_read;
881
reg [7:0] tmp_crc_token ;
882
reg[2:0] crc_read_count;
883
reg [3:0] crc_in_write;
884
reg crc_en_write;
885
reg crc_rst_write;
886
wire [15:0] crc_out_write [3:0];
887
reg [3:0] crc_in_read;
888
reg crc_en_read;
889
reg crc_rst_read;
890
wire [15:0] crc_out_read [3:0];
891
  reg[7:0] next_out;
892
    reg data_read_index;
893
reg [10:0] transf_cnt_write;
894
reg [10:0] transf_cnt_read;
895
parameter SIZE = 6;
896
reg [SIZE-1:0] state;
897
reg [SIZE-1:0] next_state;
898
parameter IDLE        = 6'b000001;
899
parameter WRITE_DAT   = 6'b000010;
900
parameter READ_CRC   = 6'b000100;
901
parameter WRITE_CRC  = 6'b001000;
902
parameter  READ_WAIT = 6'b010000;
903
parameter  READ_DAT  = 6'b100000;
904
reg in_dat_buffer_empty;
905
reg [2:0] crc_status_token;
906
reg busy_int;
907
reg add_token;
908
genvar i;
909
generate
910
for(i=0; i<4; i=i+1) begin:CRC_16_gen_write
911
  CRC_16 CRC_16_i (crc_in_write[i],crc_en_write, sd_clk, crc_rst_write, crc_out_write[i]);
912
end
913
endgenerate
914
generate
915
for(i=0; i<4; i=i+1) begin:CRC_16_gen_read
916
  CRC_16 CRC_16_i (crc_in_read[i],crc_en_read, sd_clk, crc_rst_read, crc_out_read[i]);
917
end
918
endgenerate
919
reg q_start_bit;
920
always @ (state or start_dat or DAT_dat_i[0] or  transf_cnt_write or transf_cnt_read or busy_int or crc_read_count or sd_we_o or  in_dat_buffer_empty )
921
begin : FSM_COMBO
922
 next_state  = 0;
923
case(state)
924
  IDLE: begin
925
   if (start_dat == 2'b01)
926
      next_state=WRITE_DAT;
927
    else if  (start_dat == 2'b10)
928
      next_state=READ_WAIT;
929
    else
930
      next_state=IDLE;
931
    end
932
  WRITE_DAT: begin
933
    if (transf_cnt_write >= 1044+2)
934
       next_state= READ_CRC;
935
   else if (start_dat == 2'b11)
936
        next_state=IDLE;
937
    else
938
       next_state=WRITE_DAT;
939
  end
940
  READ_WAIT: begin
941
    if (DAT_dat_i[0]== 0 )
942
       next_state= READ_DAT;
943
    else
944
       next_state=READ_WAIT;
945
  end
946
  READ_CRC: begin
947
    if ( (crc_read_count == 3'b111) &&(busy_int ==1) )
948
       next_state= WRITE_CRC;
949
    else
950
       next_state=READ_CRC;
951
  end
952
  WRITE_CRC: begin
953
       next_state= IDLE;
954
  end
955
  READ_DAT: begin
956
    if ((transf_cnt_read >= 1044-3)  && (in_dat_buffer_empty))
957
       next_state= IDLE;
958
    else if (start_dat == 2'b11)
959
        next_state=IDLE;
960
    else
961
       next_state=READ_DAT;
962
    end
963
 endcase
964
end
965
always @ (posedge sd_clk or posedge rst   )
966
 begin
967
  if (rst ) begin
968
    q_start_bit<=1;
969
 end
970
 else begin
971
    q_start_bit <= DAT_dat_i[0];
972
 end
973
end
974
always @ (posedge sd_clk or posedge rst   )
975
begin : FSM_SEQ
976
  if (rst ) begin
977
    state <= #1 IDLE;
978
 end
979
 else begin
980
    state <= #1 next_state;
981
 end
982
end
983
reg [4:0] crc_cnt_write;
984
reg [4:0]crc_cnt_read;
985
reg [3:0] last_din;
986
reg [2:0] crc_s ;
987
reg [7:0] write_buf_0,write_buf_1, sd_data_out;
988
reg out_buff_ptr,in_buff_ptr;
989
reg data_send_index;
990
reg [1:0] sd_adr_o_read;
991
reg [1:0] sd_adr_o_write;
992
reg read_byte_cnt;
993
assign sd_adr_o = add_token ? sd_adr_o_read : sd_adr_o_write;
994
assign sd_adr_o = add_token ? sd_adr_o_read : sd_adr_o_write;
995
reg [3:0] in_dat_buffer [63:0];
996
always @ (negedge sd_clk or posedge rst   )
997
begin
998
if (rst) begin
999
  DAT_oe_o<=0;
1000
  crc_en_write<=0;
1001
  crc_rst_write<=1;
1002
  transf_cnt_write<=0;
1003
  crc_cnt_write<=15;
1004
  crc_status_token<=7;
1005
  data_send_index<=0;
1006
  out_buff_ptr<=0;
1007
  in_buff_ptr<=0;
1008
  read_byte_cnt<=0;
1009
   write_buf_0<=0;
1010
    write_buf_1<=0;
1011
    sd_re_o<=0;
1012
    sd_data_out<=0;
1013
    sd_adr_o_write<=0;
1014
    crc_in_write<=0;
1015
    DAT_dat_o<=0;
1016
     last_din<=0;
1017
end
1018
else begin
1019
 case(state)
1020
   IDLE: begin
1021
      DAT_oe_o<=0;
1022
      crc_en_write<=0;
1023
      crc_rst_write<=1;
1024
      crc_cnt_write<=16;
1025
      read_byte_cnt<=0;
1026
      crc_status_token<=7;
1027
      data_send_index<=0;
1028
      out_buff_ptr<=0;
1029
      in_buff_ptr<=0;
1030
        sd_re_o<=0;
1031
        transf_cnt_write<=0;
1032
   end
1033
   WRITE_DAT: begin
1034
      transf_cnt_write<=transf_cnt_write+1;
1035
      if ( (in_buff_ptr != out_buff_ptr) ||  (transf_cnt_write<2) ) begin
1036
       read_byte_cnt<=read_byte_cnt+1;
1037
       sd_re_o<=0;
1038
        case (read_byte_cnt)
1039
        0:begin
1040
           sd_adr_o_write <=2;
1041
           sd_re_o<=1;
1042
        end
1043
        1:begin
1044
          if (!in_buff_ptr)
1045
             write_buf_0<=sd_dat_i;
1046
          else
1047
            write_buf_1 <=sd_dat_i;
1048
          in_buff_ptr<=in_buff_ptr+1;
1049
        end
1050
     endcase
1051
     end
1052
      if (!out_buff_ptr)
1053
        sd_data_out<=write_buf_0;
1054
      else
1055
       sd_data_out<=write_buf_1;
1056
        if (transf_cnt_write==1+2) begin
1057
          crc_rst_write<=0;
1058
          crc_en_write<=1;
1059
          last_din <=write_buf_0[3:0];
1060
          DAT_oe_o<=1;
1061
          DAT_dat_o<=0;
1062
          crc_in_write<= write_buf_0[3:0];
1063
          data_send_index<=1;
1064
          out_buff_ptr<=out_buff_ptr+1;
1065
        end
1066
        else if ( (transf_cnt_write>=2+2) && (transf_cnt_write<=1044-19+2 )) begin
1067
          DAT_oe_o<=1;
1068
        case (data_send_index)
1069
           0:begin
1070
              last_din <=sd_data_out[3:0];
1071
              crc_in_write <=sd_data_out[3:0];
1072
               out_buff_ptr<=out_buff_ptr+1;
1073
           end
1074
           1:begin
1075
              last_din <=sd_data_out[7:4];
1076
              crc_in_write <=sd_data_out[7:4];
1077
           end
1078
         endcase
1079
          data_send_index<=data_send_index+1;
1080
          DAT_dat_o<= last_din;
1081
        if ( transf_cnt_write >=1044-19 +2) begin
1082
             crc_en_write<=0;
1083
         end
1084
       end
1085
       else if (transf_cnt_write>1044-19 +2 & crc_cnt_write!=0) begin
1086
         crc_en_write<=0;
1087
         crc_cnt_write<=crc_cnt_write-1;
1088
         DAT_oe_o<=1;
1089
         DAT_dat_o[0]<=crc_out_write[0][crc_cnt_write-1];
1090
         DAT_dat_o[1]<=crc_out_write[1][crc_cnt_write-1];
1091
         DAT_dat_o[2]<=crc_out_write[2][crc_cnt_write-1];
1092
         DAT_dat_o[3]<=crc_out_write[3][crc_cnt_write-1];
1093
       end
1094
       else if (transf_cnt_write==1044-2+2) begin
1095
          DAT_oe_o<=1;
1096
          DAT_dat_o<=4'b1111;
1097
      end
1098
      else if (transf_cnt_write !=0) begin
1099
         DAT_oe_o<=0;
1100
      end
1101
   end
1102
 endcase
1103
end
1104
end
1105
always @ (posedge sd_clk or posedge rst   )
1106
begin
1107
  if (rst) begin
1108
    add_token<=0;
1109
    sd_adr_o_read<=0;
1110
    crc_read_count<=0;
1111
    sd_we_o<=0;
1112
    tmp_crc_token<=0;
1113
    crc_rst_read<=0;
1114
    crc_en_read<=0;
1115
    in_buff_ptr_read<=0;
1116
    out_buff_ptr_read<=0;
1117
    crc_cnt_read<=0;
1118
    transf_cnt_read<=0;
1119
    data_read_index<=0;
1120
    in_dat_buffer_empty<=0;
1121
    next_out<=0;
1122
    busy_int<=0;
1123
    sd_dat_o<=0;
1124
  end
1125
  else begin
1126
   case(state)
1127
   IDLE: begin
1128
     add_token<=0;
1129
     crc_read_count<=0;
1130
     sd_we_o<=0;
1131
     tmp_crc_token<=0;
1132
      crc_rst_read<=1;
1133
      crc_en_read<=0;
1134
      in_buff_ptr_read<=0;
1135
     out_buff_ptr_read<=0;
1136
      crc_cnt_read<=15;
1137
      transf_cnt_read<=0;
1138
      data_read_index<=0;
1139
      in_dat_buffer_empty<=0;
1140
    end
1141
    READ_DAT: begin
1142
     add_token<=1;
1143
      crc_rst_read<=0;
1144
      crc_en_read<=1;
1145
      if (fifo_acces) begin
1146
        if ( (in_buff_ptr_read - out_buff_ptr_read) >=2) begin
1147
          data_read_index<=~data_read_index;
1148
          case(data_read_index)
1149
            0: begin
1150
             sd_adr_o_read<=3;
1151
             sd_we_o<=0;
1152
             next_out[3:0]<=in_dat_buffer[out_buff_ptr_read ];
1153
             next_out[7:4]<=in_dat_buffer[out_buff_ptr_read+1 ];
1154
           end
1155
           1: begin
1156
              out_buff_ptr_read<=out_buff_ptr_read+2;
1157
            sd_dat_o<=next_out;
1158
            sd_we_o<=1;
1159
            end
1160
          endcase
1161
          end
1162
        else
1163
           in_dat_buffer_empty<=1;
1164
      end
1165
     if (transf_cnt_read<1024) begin
1166
       in_dat_buffer[in_buff_ptr_read]<=DAT_dat_i;
1167
       crc_in_read<=DAT_dat_i;
1168
       crc_ok<=1;
1169
       transf_cnt_read<=transf_cnt_read+1;
1170
       in_buff_ptr_read<=in_buff_ptr_read+1;
1171
     end
1172
     else if  ( transf_cnt_read <= (1024 +16)) begin
1173
       transf_cnt_read<=transf_cnt_read+1;
1174
       crc_en_read<=0;
1175
       last_din_read <=DAT_dat_i;
1176
       if (transf_cnt_read> 1024) begin
1177
         crc_cnt_read <=crc_cnt_read-1;
1178
          if  (crc_out_read[0][crc_cnt_read] != last_din[0])
1179
           crc_ok<=0;
1180
          if  (crc_out_read[1][crc_cnt_read] != last_din[1])
1181
           crc_ok<=0;
1182
          if  (crc_out_read[2][crc_cnt_read] != last_din[2])
1183
           crc_ok<=0;
1184
          if  (crc_out_read[3][crc_cnt_read] != last_din[3])
1185
           crc_ok<=0;
1186
         if (crc_cnt_read==0) begin
1187
         end
1188
      end
1189
    end
1190
    end
1191
    READ_CRC: begin
1192
       if (crc_read_count<3'b111) begin
1193
         crc_read_count<=crc_read_count+1;
1194
         tmp_crc_token[crc_read_count]  <= DAT_dat_i[0];
1195
        end
1196
      busy_int <=DAT_dat_i[0];
1197
    end
1198
    WRITE_CRC: begin
1199
      add_token<=1;
1200
      sd_adr_o_read<=3;
1201
      sd_we_o<=1;
1202
      sd_dat_o<=tmp_crc_token;
1203
    end
1204
  endcase
1205
end
1206
end
1207
endmodule

powered by: WebSVN 2.1.0

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