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] - Rev 39
Go to most recent revision | Compare with Previous | Blame | View Log
//------------------------- //------------------------- `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
Go to most recent revision | Compare with Previous | Blame | View Log