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_cmd_phy.v] - Rev 91
Compare with Previous | Blame | View Log
`include "sd_defines.v" //------------------------- //------------------------- module sd_cmd_phy ( input sd_clk, input rst, input cmd_dat_i, output reg cmd_dat_o, output reg cmd_oe_o, 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 [1:2] fifo_full, input [1:2] fifo_empty, output [1:0] start_dat_t, output fifo_acces_token ); //---------------Input ports--------------- `define WRITE_CMD 32'h18 `define READ_CMD 32'h11 reg [6:0] Response_Size; `ifdef SIM `define INIT_DELAY 64 `else `define INIT_DELAY 64 `endif `define tx_cmd_fifo_empty fifo_empty [1] parameter SEND_SIZE = 48; parameter CONTENT_SIZE = 40; parameter NCR = 2 ; `define Vector_Index_Write (CONTENT_SIZE-1-cmd_flow_cnt_write) `define Bit_Nr_Write (SEND_SIZE-cmd_flow_cnt_write) //FSM parameter SIZE = 5; parameter INIT = 5'b00001, IDLE = 5'b00010, WRITE = 5'b00100, BUFFER_WRITE = 5'b01000, READ = 5'b10000; reg [SIZE-1:0] state; reg [SIZE-1:0] next_state; reg [1:0] start_dat_t_read; reg [1:0] start_dat_t_write; reg [39:0] in_buffer; reg [2:0] read_byte_cnt; // reg [7:0] cmd_flow_cnt_write; reg [7:0] cmd_flow_cnt_read; reg cmd_dat_internal; // reg big_resp; reg crc_rst_write; reg crc_en_write; reg crc_in_write; wire [6:0] crc_val_write; reg [1:0] sd_adr_o_read; reg [1:0] sd_adr_o_write; reg crc_rst_read; reg crc_en_read; reg crc_in_read; wire [6:0] crc_val_read; reg crc_buffering_write; reg block_write; reg block_read; reg in_buff_ptr; reg out_buff_ptr; reg [2:0] read_index_cnt; reg [7:0] in_buff_0; reg [7:0] in_buff_1; reg [6:0] crc_in_buff; reg [7:0] response_status; reg [6:0] index_check; reg add_token_read; CRC_7 CRC_7_WRITE( .BITVAL (crc_in_write), .Enable (crc_en_write), .CLK (sd_clk), .RST (crc_rst_write), .CRC (crc_val_write)); CRC_7 CRC_7_READ( .BITVAL (crc_in_read), .Enable (crc_en_read), .CLK (sd_clk), .RST (crc_rst_read), .CRC (crc_val_read)); always @ (posedge sd_clk or posedge rst ) begin if (rst) begin cmd_dat_internal <=1'b1; end else begin cmd_dat_internal<=cmd_dat_i; end end always @ (state or cmd_flow_cnt_write or cmd_dat_internal or `tx_cmd_fifo_empty or read_byte_cnt or cmd_flow_cnt_write or cmd_flow_cnt_read ) begin : FSM_COMBO next_state = 0; case(state) INIT: begin if (cmd_flow_cnt_write >= `INIT_DELAY )begin next_state = IDLE; end else begin next_state = INIT; end end IDLE: begin if (!`tx_cmd_fifo_empty) next_state =BUFFER_WRITE; else if (!cmd_dat_internal) next_state =READ; else next_state =IDLE; end BUFFER_WRITE: begin if (read_byte_cnt>=5) next_state = WRITE; else next_state =BUFFER_WRITE; end WRITE : begin if (cmd_flow_cnt_write >= SEND_SIZE) next_state = IDLE; else next_state = WRITE; end READ : begin if (cmd_flow_cnt_read >= Response_Size+7) next_state = IDLE; else next_state = READ; end default : next_state = INIT; endcase end always @ (posedge sd_clk or posedge rst ) begin : FSM_SEQ if (rst ) begin state <= #1 INIT; end else begin state <= #1 next_state; end end reg fifo_acces_read,fifo_acces_write; assign fifo_acces_token = fifo_acces_read | fifo_acces_write; assign sd_adr_o = add_token_read ? sd_adr_o_read : sd_adr_o_write; assign start_dat_t = add_token_read ? start_dat_t_read : start_dat_t_write; reg tx_cmd_fifo_empty_tmp; always @ (negedge sd_clk or posedge rst ) begin : OUTPUT_LOGIC if (rst ) begin crc_in_write=0; crc_en_write=0; crc_rst_write=0; fifo_acces_write=0; cmd_oe_o=1; cmd_dat_o = 1; crc_buffering_write=0; sd_re_o<=0; read_byte_cnt<=0; block_read<=0; sd_adr_o_write<=0; cmd_flow_cnt_write=0; start_dat_t_write<=0; in_buffer<=0; tx_cmd_fifo_empty_tmp<=0; Response_Size<=40; end else begin case(state) INIT : begin cmd_flow_cnt_write=cmd_flow_cnt_write+1; cmd_oe_o=1; cmd_dat_o = 1; crc_buffering_write=0; start_dat_t_write<=0; end IDLE: begin cmd_flow_cnt_write=0; cmd_oe_o=0; // cmd_dat_o = 0; start_dat_t_write<=0; crc_in_write=0; crc_en_write=0; crc_rst_write=1; read_byte_cnt<=0; block_read<=0; fifo_acces_write=0; in_buffer<=0; end BUFFER_WRITE : begin sd_re_o<=0; fifo_acces_write=1; tx_cmd_fifo_empty_tmp<=`tx_cmd_fifo_empty; if (!tx_cmd_fifo_empty_tmp) begin if(sd_re_o) read_byte_cnt <= read_byte_cnt+1; sd_adr_o_write <=0; sd_re_o<=1; if(sd_re_o) begin case (read_byte_cnt) //If data is Avaible next cycle? 0: in_buffer[39:32] <=sd_dat_i; 1: in_buffer[31:24] <=sd_dat_i; 2: in_buffer[23:16] <=sd_dat_i; 3: in_buffer[15:8] <=sd_dat_i; 4: in_buffer[7:0] <=sd_dat_i; endcase if (in_buffer[39]) Response_Size<=127; else Response_Size<=40; if (in_buffer[37:32] == `READ_CMD) block_read<=1; end end end WRITE: begin sd_re_o<=0; cmd_oe_o=1; cmd_dat_o = 1; crc_en_write =0; crc_rst_write=0; crc_en_write=1; if (crc_buffering_write==1) begin cmd_oe_o =1; if (`Bit_Nr_Write > 8 ) begin // 1->40 CMD, (41 >= CNT && CNT <=47) CRC, 48 stop_bit if (cmd_flow_cnt_write==0) cmd_dat_o = 0; else cmd_dat_o = in_buffer[`Vector_Index_Write]; if (`Bit_Nr_Write > 9 ) begin //1 step ahead crc_in_write = in_buffer[`Vector_Index_Write-1]; end else begin crc_en_write=0; end end else if ( (`Bit_Nr_Write <=8) && (`Bit_Nr_Write >=2) ) begin crc_en_write=0; cmd_dat_o = crc_val_write[(`Bit_Nr_Write)-2]; if (block_read) start_dat_t_write<=2'b10; end else begin cmd_dat_o =1'b1; end cmd_flow_cnt_write=cmd_flow_cnt_write+1; end else begin //Pre load CRC crc_buffering_write=1; crc_in_write = 0; end end endcase end end always @ (posedge sd_clk or posedge rst ) begin if (rst) begin crc_rst_read=1; crc_en_read=0; crc_in_read=0; cmd_flow_cnt_read=0; response_status =0; block_write=0; index_check=0; in_buff_ptr=0; out_buff_ptr=0; sd_adr_o_read<=0; add_token_read=0; in_buff_0<=0; in_buff_1<=0; read_index_cnt=0; fifo_acces_read=0; sd_dat_o<=0; start_dat_t_read<=0; sd_we_o<=0; crc_in_buff=0; end else begin case (state) IDLE : begin crc_en_read=0; crc_rst_read=1; cmd_flow_cnt_read=1; index_check=0; block_write=0; in_buff_ptr=0; out_buff_ptr=0; add_token_read=0; read_index_cnt=0; sd_we_o<=0; add_token_read=0; fifo_acces_read=0; start_dat_t_read<=0; end READ : begin fifo_acces_read=1; add_token_read=1; //Takes command over addres crc_en_read=1; crc_rst_read=0; sd_we_o<=0; if (in_buff_ptr != out_buff_ptr) begin sd_adr_o_read <=1; sd_we_o<=1; if (in_buff_ptr) sd_dat_o <=in_buff_0; else sd_dat_o <=in_buff_1; out_buff_ptr=out_buff_ptr+1; end if (cmd_flow_cnt_read < (Response_Size))begin //40 First Bits crc_in_read = cmd_dat_internal; if (cmd_flow_cnt_read<8 ) begin //1+1+6 (S,T,Index) index_check[7-cmd_flow_cnt_read] = cmd_dat_internal; if (index_check[5:0] == `WRITE_CMD) begin block_write=1; end end else begin if (!in_buff_ptr) begin in_buff_0[7-read_index_cnt]<=cmd_dat_internal; end else begin in_buff_1[7-read_index_cnt]<=cmd_dat_internal; end read_index_cnt=read_index_cnt+1; if (read_index_cnt==0) in_buff_ptr=in_buff_ptr+1; end end else if ( cmd_flow_cnt_read - Response_Size <=6 ) begin //7-Crc Bit crc_in_buff [(Response_Size+6)-(cmd_flow_cnt_read)] = cmd_dat_internal; crc_en_read=0; end else begin //Commpare CRC read with calcualted. if ((crc_in_buff != crc_val_read)) begin response_status[0]=1; end else begin response_status[0]=0; end sd_adr_o_read <=1; sd_we_o<=1; sd_dat_o<=response_status; if (block_write) start_dat_t_read<=2'b01; end cmd_flow_cnt_read = cmd_flow_cnt_read+1; end endcase end end endmodule