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_data_phy.v] - Diff between revs 6 and 10

Go to most recent revision | Show entire file | Details | Blame | View Log

Rev 6 Rev 10
Line 1... Line 1...
 
//-------------------------
 
//-------------------------
 
 
 
 
 
 
 
 
 
`include "SD_defines.v"
 
`define BUFFER_OFFSET 2
 
 
 
module sd_data_phy(
 
input sd_clk,
 
input rst,
 
output reg DAT_oe_o,
 
output reg[3:0] DAT_dat_o,
 
input  [3:0] DAT_dat_i,
 
 
 
output  [1:0] sd_adr_o,
 
input [7:0] sd_dat_i,
 
output reg [7:0] sd_dat_o,
 
output reg sd_we_o,
 
output reg sd_re_o,
 
input  [3:4] fifo_full,
 
input [3:4] fifo_empty,
 
input  [1:0] start_dat,
 
input fifo_acces
 
 
 
);
 
 reg [5:0] in_buff_ptr_read;
 
 reg [5:0] out_buff_ptr_read;
 
 reg crc_ok;
 
 reg [3:0] last_din_read;
 
 
 
 
 
 
 
reg [7:0] tmp_crc_token ;
 
reg[2:0] crc_read_count;
 
 
 
//CRC16 
 
reg [3:0] crc_in_write;
 
reg crc_en_write;
 
reg crc_rst_write;
 
wire [15:0] crc_out_write [3:0];
 
 
 
reg [3:0] crc_in_read;
 
reg crc_en_read;
 
reg crc_rst_read;
 
wire [15:0] crc_out_read [3:0];
 
 
 
  reg[7:0] next_out;
 
    reg data_read_index;
 
 
 
reg [10:0] transf_cnt_write;
 
reg [10:0] transf_cnt_read;
 
parameter SIZE = 6;
 
reg [SIZE-1:0] state;
 
reg [SIZE-1:0] next_state;
 
parameter IDLE        = 6'b000001;
 
parameter WRITE_DAT   = 6'b000010;
 
parameter READ_CRC   = 6'b000100;
 
parameter WRITE_CRC  = 6'b001000;
 
parameter  READ_WAIT = 6'b010000;
 
parameter  READ_DAT  = 6'b100000;
 
 
 
reg in_dat_buffer_empty;
 
reg [2:0] crc_status_token;
 
reg busy_int;
 
reg add_token;
 
genvar i;
 
generate
 
for(i=0; i<4; i=i+1) begin:CRC_16_gen_write
 
  CRC_16 CRC_16_i (crc_in_write[i],crc_en_write, sd_clk, crc_rst_write, crc_out_write[i]);
 
end
 
endgenerate
 
 
 
 
 
generate
 
for(i=0; i<4; i=i+1) begin:CRC_16_gen_read
 
  CRC_16 CRC_16_i (crc_in_read[i],crc_en_read, sd_clk, crc_rst_read, crc_out_read[i]);
 
end
 
endgenerate
 
 
 
 
 
 
 
reg q_start_bit;
 
 
 
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 )
 
begin : FSM_COMBO
 
 next_state  = 0;
 
case(state)
 
  IDLE: begin
 
   if (start_dat == 2'b01)
 
      next_state=WRITE_DAT;
 
    else if  (start_dat == 2'b10)
 
      next_state=READ_WAIT;
 
    else
 
      next_state=IDLE;
 
    end
 
  WRITE_DAT: begin
 
    if (transf_cnt_write >= `BIT_BLOCK+`BUFFER_OFFSET)
 
       next_state= READ_CRC;
 
   else if (start_dat == 2'b11)
 
        next_state=IDLE;
 
    else
 
       next_state=WRITE_DAT;
 
  end
 
 
 
  READ_WAIT: begin
 
    if (DAT_dat_i[0]== 0 )
 
       next_state= READ_DAT;
 
    else
 
       next_state=READ_WAIT;
 
  end
 
 
 
 
 
  READ_CRC: begin
 
    if ( (crc_read_count == 3'b111) &&(busy_int ==1) )
 
       next_state= WRITE_CRC;
 
    else
 
       next_state=READ_CRC;
 
  end
 
  WRITE_CRC: begin
 
 
 
       next_state= IDLE;
 
 
 
  end
 
 
 
 
 
 
 
  READ_DAT: begin
 
    if ((transf_cnt_read >= `BIT_BLOCK-3)  && (in_dat_buffer_empty)) //Startbit consumed...
 
       next_state= IDLE;
 
    else if (start_dat == 2'b11)
 
        next_state=IDLE;
 
    else
 
       next_state=READ_DAT;
 
    end
 
 endcase
 
end
 
 
 
always @ (posedge sd_clk or posedge rst   )
 
 begin
 
  if (rst ) begin
 
    q_start_bit<=1;
 
 end
 
 else begin
 
    q_start_bit <= DAT_dat_i[0];
 
 end
 
end
 
 
 
 
 
//----------------Seq logic------------
 
always @ (posedge sd_clk or posedge rst   )
 
begin : FSM_SEQ
 
  if (rst ) begin
 
    state <= #1 IDLE;
 
 end
 
 else begin
 
    state <= #1 next_state;
 
 end
 
end
 
 
 
reg [4:0] crc_cnt_write;
 
reg [4:0]crc_cnt_read;
 
reg [3:0] last_din;
 
reg [2:0] crc_s ;
 
reg [7:0] write_buf_0,write_buf_1, sd_data_out;
 
reg out_buff_ptr,in_buff_ptr;
 
reg data_send_index;
 
reg [1:0] sd_adr_o_read;
 
reg [1:0] sd_adr_o_write;
 
 
 
 
 
reg read_byte_cnt;
 
assign sd_adr_o = add_token ? sd_adr_o_read : sd_adr_o_write;
 
 
 
 
 
 
 
 
 
assign sd_adr_o = add_token ? sd_adr_o_read : sd_adr_o_write;
 
 
 
reg [3:0] in_dat_buffer [63:0];
 
 
 
always @ (negedge sd_clk or posedge rst   )
 
begin
 
if (rst) begin
 
  DAT_oe_o<=0;
 
  crc_en_write<=0;
 
  crc_rst_write<=1;
 
  transf_cnt_write<=0;
 
  crc_cnt_write<=15;
 
  crc_status_token<=7;
 
 
 
  data_send_index<=0;
 
  out_buff_ptr<=0;
 
  in_buff_ptr<=0;
 
  read_byte_cnt<=0;
 
   write_buf_0<=0;
 
    write_buf_1<=0;
 
    sd_re_o<=0;
 
    sd_data_out<=0;
 
    sd_adr_o_write<=0;
 
    crc_in_write<=0;
 
    DAT_dat_o<=0;
 
     last_din<=0;
 
end
 
else begin
 
 case(state)
 
   IDLE: begin
 
      DAT_oe_o<=0;
 
      crc_en_write<=0;
 
      crc_rst_write<=1;
 
      crc_cnt_write<=16;
 
      read_byte_cnt<=0;
 
 
 
      crc_status_token<=7;
 
      data_send_index<=0;
 
      out_buff_ptr<=0;
 
      in_buff_ptr<=0;
 
        sd_re_o<=0;
 
        transf_cnt_write<=0;
 
 
 
   end
 
   WRITE_DAT: begin
 
 
 
      transf_cnt_write<=transf_cnt_write+1;
 
 
 
 
 
      if ( (in_buff_ptr != out_buff_ptr) ||  (transf_cnt_write<2) ) begin
 
       read_byte_cnt<=read_byte_cnt+1;
 
       sd_re_o<=0;
 
        case (read_byte_cnt)
 
        0:begin
 
           sd_adr_o_write <=2;
 
           sd_re_o<=1;
 
        end
 
        1:begin
 
          if (!in_buff_ptr)
 
             write_buf_0<=sd_dat_i;
 
          else
 
            write_buf_1 <=sd_dat_i;
 
          in_buff_ptr<=in_buff_ptr+1;
 
        end
 
     endcase
 
     end
 
 
 
      if (!out_buff_ptr)
 
        sd_data_out<=write_buf_0;
 
      else
 
       sd_data_out<=write_buf_1;
 
 
 
        if (transf_cnt_write==1+`BUFFER_OFFSET) begin
 
 
 
          crc_rst_write<=0;
 
          crc_en_write<=1;
 
          last_din <=write_buf_0[3:0];
 
          DAT_oe_o<=1;
 
          DAT_dat_o<=0;
 
          crc_in_write<= write_buf_0[3:0];
 
          data_send_index<=1;
 
          out_buff_ptr<=out_buff_ptr+1;
 
        end
 
        else if ( (transf_cnt_write>=2+`BUFFER_OFFSET) && (transf_cnt_write<=`BIT_BLOCK-`CRC_OFF+`BUFFER_OFFSET )) begin
 
          DAT_oe_o<=1;
 
        case (data_send_index)
 
           0:begin
 
              last_din <=sd_data_out[3:0];
 
              crc_in_write <=sd_data_out[3:0];
 
               out_buff_ptr<=out_buff_ptr+1;
 
           end
 
           1:begin
 
              last_din <=sd_data_out[7:4];
 
              crc_in_write <=sd_data_out[7:4];
 
           end
 
 
 
         endcase
 
          data_send_index<=data_send_index+1;
 
 
 
          DAT_dat_o<= last_din;
 
 
 
        if ( transf_cnt_write >=`BIT_BLOCK-`CRC_OFF +`BUFFER_OFFSET) begin
 
             crc_en_write<=0;
 
         end
 
       end
 
       else if (transf_cnt_write>`BIT_BLOCK-`CRC_OFF +`BUFFER_OFFSET & crc_cnt_write!=0) begin
 
 
 
         crc_en_write<=0;
 
         crc_cnt_write<=crc_cnt_write-1;
 
         DAT_oe_o<=1;
 
         DAT_dat_o[0]<=crc_out_write[0][crc_cnt_write-1];
 
         DAT_dat_o[1]<=crc_out_write[1][crc_cnt_write-1];
 
         DAT_dat_o[2]<=crc_out_write[2][crc_cnt_write-1];
 
         DAT_dat_o[3]<=crc_out_write[3][crc_cnt_write-1];
 
       end
 
       else if (transf_cnt_write==`BIT_BLOCK-2+`BUFFER_OFFSET) begin
 
          DAT_oe_o<=1;
 
          DAT_dat_o<=4'b1111;
 
 
 
      end
 
      else if (transf_cnt_write !=0) begin
 
         DAT_oe_o<=0;
 
      end
 
 
 
 
 
   end
 
 
 
 
 
 endcase
 
end
 
end
 
 
 
 
 
always @ (posedge sd_clk or posedge rst   )
 
begin
 
  if (rst) begin
 
    add_token<=0;
 
    sd_adr_o_read<=0;
 
    crc_read_count<=0;
 
    sd_we_o<=0;
 
    tmp_crc_token<=0;
 
    crc_rst_read<=0;
 
    crc_en_read<=0;
 
    in_buff_ptr_read<=0;
 
    out_buff_ptr_read<=0;
 
    crc_cnt_read<=0;
 
    transf_cnt_read<=0;
 
    data_read_index<=0;
 
    in_dat_buffer_empty<=0;
 
 
 
    next_out<=0;
 
    busy_int<=0;
 
    sd_dat_o<=0;
 
  end
 
  else begin
 
   case(state)
 
   IDLE: begin
 
     add_token<=0;
 
     crc_read_count<=0;
 
     sd_we_o<=0;
 
     tmp_crc_token<=0;
 
      crc_rst_read<=1;
 
      crc_en_read<=0;
 
      in_buff_ptr_read<=0;
 
     out_buff_ptr_read<=0;
 
      crc_cnt_read<=15;
 
      transf_cnt_read<=0;
 
      data_read_index<=0;
 
      in_dat_buffer_empty<=0;
 
    end
 
 
 
    READ_DAT: begin
 
     add_token<=1;
 
      crc_rst_read<=0;
 
      crc_en_read<=1;
 
 
 
 
 
 
 
      if (fifo_acces) begin
 
        if ( (in_buff_ptr_read - out_buff_ptr_read) >=2) begin
 
          data_read_index<=~data_read_index;
 
          case(data_read_index)
 
            0: begin
 
             sd_adr_o_read<=3;
 
             sd_we_o<=0;
 
             next_out[3:0]<=in_dat_buffer[out_buff_ptr_read ];
 
             next_out[7:4]<=in_dat_buffer[out_buff_ptr_read+1 ];
 
           end
 
           1: begin
 
              out_buff_ptr_read<=out_buff_ptr_read+2;
 
            sd_dat_o<=next_out;
 
            sd_we_o<=1;
 
            end
 
          endcase
 
          end
 
        else
 
           in_dat_buffer_empty<=1;
 
      end
 
 
 
     if (transf_cnt_read<`BIT_BLOCK_REC) begin
 
 
 
       in_dat_buffer[in_buff_ptr_read]<=DAT_dat_i;
 
       crc_in_read<=DAT_dat_i;
 
       crc_ok<=1;
 
       transf_cnt_read<=transf_cnt_read+1;
 
       in_buff_ptr_read<=in_buff_ptr_read+1;
 
     end
 
     else if  ( transf_cnt_read <= (`BIT_BLOCK_REC +`BIT_CRC_CYCLE)) begin
 
       transf_cnt_read<=transf_cnt_read+1;
 
       crc_en_read<=0;
 
       last_din_read <=DAT_dat_i;
 
 
 
       if (transf_cnt_read> `BIT_BLOCK_REC) begin
 
         crc_cnt_read <=crc_cnt_read-1;
 
 
 
 
 
          if  (crc_out_read[0][crc_cnt_read] != last_din[0])
 
           crc_ok<=0;
 
          if  (crc_out_read[1][crc_cnt_read] != last_din[1])
 
           crc_ok<=0;
 
          if  (crc_out_read[2][crc_cnt_read] != last_din[2])
 
           crc_ok<=0;
 
          if  (crc_out_read[3][crc_cnt_read] != last_din[3])
 
           crc_ok<=0;
 
 
 
         if (crc_cnt_read==0) begin
 
          //in_dat_buffer[in_buff_ptr_read] <= {7'b0,crc_ok}
 
         end
 
      end
 
    end
 
 
 
 
 
 
 
    end
 
    READ_CRC: begin
 
       if (crc_read_count<3'b111) begin
 
         crc_read_count<=crc_read_count+1;
 
         tmp_crc_token[crc_read_count]  <= DAT_dat_i[0];
 
        end
 
 
 
      busy_int <=DAT_dat_i[0];
 
 
 
    end
 
    WRITE_CRC: begin
 
      add_token<=1;
 
      sd_adr_o_read<=3;
 
      sd_we_o<=1;
 
      sd_dat_o<=tmp_crc_token;
 
    end
 
 
 
  endcase
 
end
 
 
 
end
 
//Sync
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
endmodule
 
 
 
 
 
 
 
 
 No newline at end of file
 No newline at end of file

powered by: WebSVN 2.1.0

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