OpenCores
URL https://opencores.org/ocsvn/sdcard_mass_storage_controller/sdcard_mass_storage_controller/trunk

Subversion Repositories sdcard_mass_storage_controller

Compare Revisions

  • This comparison shows the changes necessary to convert path
    /sdcard_mass_storage_controller/trunk/rtl
    from Rev 124 to Rev 127
    Reverse comparison

Rev 124 → Rev 127

/sdc_dma/verilog/SD_data_host.v
1,457 → 1,458
 
 
`include "SD_defines.v"
 
 
module SD_DATA_SERIAL_HOST(
input sd_clk,
input rst,
//Tx Fifo
input [31:0] data_in ,
 
output reg rd,
//Rx Fifo
output reg [`SD_BUS_W-1:0] data_out ,
output reg we,
//tristate data
output reg DAT_oe_o,
output reg[`SD_BUS_W-1:0] DAT_dat_o,
input [`SD_BUS_W-1:0] DAT_dat_i,
//Controll signals
input [1:0] start_dat,
input ack_transfer,
 
output reg busy_n,
output reg transm_complete,
output reg crc_ok
);
 
//CRC16
reg [`SD_BUS_W-1:0] crc_in;
reg crc_en;
reg crc_rst;
wire [15:0] crc_out [`SD_BUS_W-1:0];
reg [`SD_BUS_W-1:0] temp_in;
reg [10:0] transf_cnt;
parameter SIZE = 6;
reg [SIZE-1:0] state;
reg [SIZE-1:0] next_state;
parameter IDLE = 6'b000001;
parameter WRITE_DAT = 6'b000010;
parameter WRITE_CRC = 6'b000100;
parameter WRITE_BUSY = 6'b001000;
parameter READ_WAIT = 6'b010000;
parameter READ_DAT = 6'b100000;
reg [2:0] crc_status;
reg busy_int;
 
genvar i;
generate
for(i=0; i<`SD_BUS_W; i=i+1) begin:CRC_16_gen
SD_CRC_16 CRC_16_i (crc_in[i],crc_en, sd_clk, crc_rst, crc_out[i]);
end
endgenerate
 
reg ack_transfer_int;
reg ack_q;
always @ (posedge sd_clk or posedge rst )
begin: ACK_SYNC
if (rst) begin
ack_transfer_int <=0;
ack_q<=0;end
else begin
ack_q<=ack_transfer;
ack_transfer_int<=ack_q;
end
end
 
reg q_start_bit;
always @ (state or start_dat or q_start_bit or transf_cnt or crc_status or busy_int or DAT_dat_i or ack_transfer_int)
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 >= `BIT_BLOCK)
next_state= WRITE_CRC;
else if (start_dat == 2'b11)
next_state=IDLE;
else
next_state=WRITE_DAT;
end
 
WRITE_CRC: begin
if (crc_status ==0)
next_state= WRITE_BUSY;
else
next_state=WRITE_CRC;
end
WRITE_BUSY: begin
if ( (busy_int ==1) & ack_transfer_int)
next_state= IDLE;
else
next_state = WRITE_BUSY;
end
READ_WAIT: begin
if (q_start_bit== 0 )
next_state= READ_DAT;
else
next_state=READ_WAIT;
end
READ_DAT: begin
if ( ack_transfer_int) //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 :START_SYNC
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_c;
reg [3:0] last_din;
reg [2:0] crc_s ;
reg [31:0] write_buf_0,write_buf_1, sd_data_out;
reg out_buff_ptr,in_buff_ptr;
reg [2:0] data_send_index;
always @ (negedge sd_clk or posedge rst )
begin : FSM_OUT
if (rst) begin
write_buf_0<=0;
write_buf_1<=0;
DAT_oe_o<=0;
crc_en<=0;
crc_rst<=1;
transf_cnt<=0;
crc_c<=15;
rd<=0;
last_din<=0;
crc_c<=0;
crc_in<=0;
DAT_dat_o<=0;
crc_status<=7;
crc_s<=0;
transm_complete<=0;
busy_n<=1;
we<=0;
data_out<=0;
crc_ok<=0;
busy_int<=0;
data_send_index<=0;
out_buff_ptr<=0;
in_buff_ptr<=0;
end
else begin
case(state)
IDLE: begin
DAT_oe_o<=0;
DAT_dat_o<=4'b1111;
crc_en<=0;
crc_rst<=1;
transf_cnt<=0;
crc_c<=16;
crc_status<=7;
crc_s<=0;
we<=0;
rd<=0;
busy_n<=1;
data_send_index<=0;
out_buff_ptr<=0;
in_buff_ptr<=0;
end
WRITE_DAT: begin
transm_complete <=0;
busy_n<=0;
crc_ok<=0;
transf_cnt<=transf_cnt+1;
rd<=0;
if ( (in_buff_ptr != out_buff_ptr) || (!transf_cnt) ) begin
rd <=1;
if (!in_buff_ptr)
write_buf_0<=data_in;
else
write_buf_1 <=data_in;
in_buff_ptr<=in_buff_ptr+1;
end
if (!out_buff_ptr)
sd_data_out<=write_buf_0;
else
sd_data_out<=write_buf_1;
if (transf_cnt==1) begin
crc_rst<=0;
crc_en<=1;
`ifdef LITLE_ENDIAN
last_din <=write_buf_0[3:0];
crc_in<= write_buf_0[3:0];
`endif
`ifdef BIG_ENDIAN
last_din <=write_buf_0[31:28];
crc_in<= write_buf_0[31:28];
`endif
DAT_oe_o<=1;
DAT_dat_o<=0;
data_send_index<=1;
end
else if ( (transf_cnt>=2) && (transf_cnt<=`BIT_BLOCK-`CRC_OFF )) begin
DAT_oe_o<=1;
case (data_send_index)
`ifdef LITLE_ENDIAN
0:begin
last_din <=sd_data_out[3:0];
crc_in <=sd_data_out[3:0];
end
1:begin
last_din <=sd_data_out[7:4];
crc_in <=sd_data_out[7:4];
end
2:begin
last_din <=sd_data_out[11:8];
crc_in <=sd_data_out[11:8];
end
3:begin
last_din <=sd_data_out[15:12];
crc_in <=sd_data_out[15:12];
end
4:begin
last_din <=sd_data_out[19:16];
crc_in <=sd_data_out[19:16];
end
5:begin
last_din <=sd_data_out[23:20];
crc_in <=sd_data_out[23:20];
end
6:begin
last_din <=sd_data_out[27:24];
crc_in <=sd_data_out[27:24];
out_buff_ptr<=out_buff_ptr+1;
end
7:begin
last_din <=sd_data_out[31:28];
crc_in <=sd_data_out[31:28];
end
`endif
`ifdef BIG_ENDIAN
0:begin
last_din <=sd_data_out[31:28];
crc_in <=sd_data_out[31:28];
end
1:begin
last_din <=sd_data_out[27:24];
crc_in <=sd_data_out[27:24];
end
2:begin
last_din <=sd_data_out[23:20];
crc_in <=sd_data_out[23:20];
end
3:begin
last_din <=sd_data_out[19:16];
crc_in <=sd_data_out[19:16];
end
4:begin
last_din <=sd_data_out[15:12];
crc_in <=sd_data_out[15:12];
end
5:begin
last_din <=sd_data_out[11:8];
crc_in <=sd_data_out[11:8];
end
6:begin
last_din <=sd_data_out[7:4];
crc_in <=sd_data_out[7:4];
out_buff_ptr<=out_buff_ptr+1;
end
7:begin
last_din <=sd_data_out[3:0];
crc_in <=sd_data_out[3:0];
end
`endif
endcase
data_send_index<=data_send_index+1;
DAT_dat_o<= last_din;
if ( transf_cnt >=`BIT_BLOCK-`CRC_OFF ) begin
crc_en<=0;
end
end
else if (transf_cnt>`BIT_BLOCK-`CRC_OFF & crc_c!=0) begin
rd<=0;
crc_en<=0;
crc_c<=crc_c-1;
DAT_oe_o<=1;
DAT_dat_o[0]<=crc_out[0][crc_c-1];
DAT_dat_o[1]<=crc_out[1][crc_c-1];
DAT_dat_o[2]<=crc_out[2][crc_c-1];
DAT_dat_o[3]<=crc_out[3][crc_c-1];
end
else if (transf_cnt==`BIT_BLOCK-2) begin
DAT_oe_o<=1;
DAT_dat_o<=4'b1111;
rd<=0;
end
else if (transf_cnt !=0) begin
DAT_oe_o<=0;
rd<=0;
end
end
WRITE_CRC : begin
rd<=0;
DAT_oe_o<=0;
crc_status<=crc_status-1;
if (( crc_status<=4) && ( crc_status>=2) )
crc_s[crc_status-2] <=DAT_dat_i[0];
end
WRITE_BUSY : begin
transm_complete <=1;
if (crc_s == 3'b010)
crc_ok<=1;
else
crc_ok<=0;
busy_int<=DAT_dat_i[0];
end
READ_WAIT:begin
DAT_oe_o<=0;
crc_rst<=0;
crc_en<=1;
crc_in<=0;
crc_c<=15;// end
busy_n<=0;
transm_complete<=0;
end
READ_DAT: begin
if (transf_cnt<`BIT_BLOCK_REC) begin
we<=1;
data_out<=DAT_dat_i;
crc_in<=DAT_dat_i;
crc_ok<=1;
transf_cnt<=transf_cnt+1;
end
else if ( transf_cnt <= (`BIT_BLOCK_REC +`BIT_CRC_CYCLE)) begin
transf_cnt<=transf_cnt+1;
crc_en<=0;
last_din <=DAT_dat_i;
if (transf_cnt> `BIT_BLOCK_REC) begin
crc_c<=crc_c-1;
we<=0;
`ifdef SD_BUS_WIDTH_1
if (crc_out[0][crc_status] == last_din[0])
crc_ok<=0;
`endif
`ifdef SD_BUS_WIDTH_4
if (crc_out[0][crc_c] != last_din[0])
crc_ok<=0;
if (crc_out[1][crc_c] != last_din[1])
crc_ok<=0;
if (crc_out[2][crc_c] != last_din[2])
crc_ok<=0;
if (crc_out[3][crc_c] != last_din[3])
crc_ok<=0;
`endif
`ifdef SIM
crc_ok<=1;
`endif
if (crc_c==0) begin
transm_complete <=1;
busy_n<=0;
we<=0;
end
end
end
end
endcase
end
 
end
 
 
 
 
 
 
 
 
//Sync
 
 
 
 
 
endmodule
 
 
 
 
 
 
`include "SD_defines.v"
 
 
module SD_DATA_SERIAL_HOST(
input sd_clk,
input rst,
//Tx Fifo
input [31:0] data_in ,
 
output reg rd,
//Rx Fifo
output reg [`SD_BUS_W-1:0] data_out ,
output reg we,
//tristate data
output reg DAT_oe_o,
output reg[`SD_BUS_W-1:0] DAT_dat_o,
input [`SD_BUS_W-1:0] DAT_dat_i,
//Controll signals
input [1:0] start_dat,
input ack_transfer,
 
output reg busy_n,
output reg transm_complete,
output reg crc_ok
);
 
//CRC16
reg [`SD_BUS_W-1:0] crc_in;
reg crc_en;
reg crc_rst;
wire [15:0] crc_out [`SD_BUS_W-1:0];
reg [`SD_BUS_W-1:0] temp_in;
reg [10:0] transf_cnt;
parameter SIZE = 6;
reg [SIZE-1:0] state;
reg [SIZE-1:0] next_state;
parameter IDLE = 6'b000001;
parameter WRITE_DAT = 6'b000010;
parameter WRITE_CRC = 6'b000100;
parameter WRITE_BUSY = 6'b001000;
parameter READ_WAIT = 6'b010000;
parameter READ_DAT = 6'b100000;
reg [2:0] crc_status;
reg busy_int;
 
genvar i;
generate
for(i=0; i<`SD_BUS_W; i=i+1) begin:CRC_16_gen
SD_CRC_16 CRC_16_i (crc_in[i],crc_en, sd_clk, crc_rst, crc_out[i]);
end
endgenerate
 
reg ack_transfer_int;
reg ack_q;
always @ (posedge sd_clk or posedge rst )
begin: ACK_SYNC
if (rst) begin
ack_transfer_int <=0;
ack_q<=0;end
else begin
ack_q<=ack_transfer;
ack_transfer_int<=ack_q;
end
end
 
reg q_start_bit;
always @ (state or start_dat or q_start_bit or transf_cnt or crc_status or busy_int or DAT_dat_i or ack_transfer_int)
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 >= `BIT_BLOCK)
next_state= WRITE_CRC;
else if (start_dat == 2'b11)
next_state=IDLE;
else
next_state=WRITE_DAT;
end
 
WRITE_CRC: begin
if (crc_status ==0)
next_state= WRITE_BUSY;
else
next_state=WRITE_CRC;
end
WRITE_BUSY: begin
if ( (busy_int ==1) & ack_transfer_int)
next_state= IDLE;
else
next_state = WRITE_BUSY;
end
READ_WAIT: begin
if (q_start_bit== 0 )
next_state= READ_DAT;
else
next_state=READ_WAIT;
end
READ_DAT: begin
if ( ack_transfer_int) //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 :START_SYNC
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_c;
reg [3:0] last_din;
reg [2:0] crc_s ;
reg [31:0] write_buf_0,write_buf_1, sd_data_out;
reg out_buff_ptr,in_buff_ptr;
reg [2:0] data_send_index;
always @ (negedge sd_clk or posedge rst )
begin : FSM_OUT
if (rst) begin
write_buf_0<=0;
write_buf_1<=0;
DAT_oe_o<=0;
crc_en<=0;
crc_rst<=1;
transf_cnt<=0;
crc_c<=15;
rd<=0;
last_din<=0;
crc_c<=0;
crc_in<=0;
DAT_dat_o<=0;
crc_status<=7;
crc_s<=0;
transm_complete<=0;
busy_n<=1;
we<=0;
data_out<=0;
crc_ok<=0;
busy_int<=0;
data_send_index<=0;
out_buff_ptr<=0;
in_buff_ptr<=0;
end
else begin
case(state)
IDLE: begin
DAT_oe_o<=0;
DAT_dat_o<=4'b1111;
crc_en<=0;
crc_rst<=1;
transf_cnt<=0;
crc_c<=16;
crc_status<=7;
crc_s<=0;
we<=0;
rd<=0;
busy_n<=1;
data_send_index<=0;
out_buff_ptr<=0;
in_buff_ptr<=0;
end
WRITE_DAT: begin
transm_complete <=0;
busy_n<=0;
crc_ok<=0;
transf_cnt<=transf_cnt+1;
rd<=0;
if ( (in_buff_ptr != out_buff_ptr) || (!transf_cnt) ) begin
rd <=1;
if (!in_buff_ptr)
write_buf_0<=data_in;
else
write_buf_1 <=data_in;
in_buff_ptr<=in_buff_ptr+1;
end
if (!out_buff_ptr)
sd_data_out<=write_buf_0;
else
sd_data_out<=write_buf_1;
if (transf_cnt==1) begin
crc_rst<=0;
crc_en<=1;
`ifdef LITLE_ENDIAN
last_din <=write_buf_0[3:0];
crc_in<= write_buf_0[3:0];
`endif
`ifdef BIG_ENDIAN
last_din <=write_buf_0[31:28];
crc_in<= write_buf_0[31:28];
`endif
DAT_oe_o<=1;
DAT_dat_o<=0;
data_send_index<=1;
end
else if ( (transf_cnt>=2) && (transf_cnt<=`BIT_BLOCK-`CRC_OFF )) begin
DAT_oe_o<=1;
case (data_send_index)
`ifdef LITLE_ENDIAN
0:begin
last_din <=sd_data_out[3:0];
crc_in <=sd_data_out[3:0];
end
1:begin
last_din <=sd_data_out[7:4];
crc_in <=sd_data_out[7:4];
end
2:begin
last_din <=sd_data_out[11:8];
crc_in <=sd_data_out[11:8];
end
3:begin
last_din <=sd_data_out[15:12];
crc_in <=sd_data_out[15:12];
end
4:begin
last_din <=sd_data_out[19:16];
crc_in <=sd_data_out[19:16];
end
5:begin
last_din <=sd_data_out[23:20];
crc_in <=sd_data_out[23:20];
end
6:begin
last_din <=sd_data_out[27:24];
crc_in <=sd_data_out[27:24];
out_buff_ptr<=out_buff_ptr+1;
end
7:begin
last_din <=sd_data_out[31:28];
crc_in <=sd_data_out[31:28];
end
`endif
`ifdef BIG_ENDIAN
0:begin
last_din <=sd_data_out[31:28];
crc_in <=sd_data_out[31:28];
end
1:begin
last_din <=sd_data_out[27:24];
crc_in <=sd_data_out[27:24];
end
2:begin
last_din <=sd_data_out[23:20];
crc_in <=sd_data_out[23:20];
end
3:begin
last_din <=sd_data_out[19:16];
crc_in <=sd_data_out[19:16];
end
4:begin
last_din <=sd_data_out[15:12];
crc_in <=sd_data_out[15:12];
end
5:begin
last_din <=sd_data_out[11:8];
crc_in <=sd_data_out[11:8];
end
6:begin
last_din <=sd_data_out[7:4];
crc_in <=sd_data_out[7:4];
out_buff_ptr<=out_buff_ptr+1;
end
7:begin
last_din <=sd_data_out[3:0];
crc_in <=sd_data_out[3:0];
end
`endif
endcase
data_send_index<=data_send_index+1;
DAT_dat_o<= last_din;
if ( transf_cnt >=`BIT_BLOCK-`CRC_OFF ) begin
crc_en<=0;
end
end
else if (transf_cnt>`BIT_BLOCK-`CRC_OFF & crc_c!=0) begin
rd<=0;
crc_en<=0;
crc_c<=crc_c-1;
DAT_oe_o<=1;
DAT_dat_o[0]<=crc_out[0][crc_c-1];
DAT_dat_o[1]<=crc_out[1][crc_c-1];
DAT_dat_o[2]<=crc_out[2][crc_c-1];
DAT_dat_o[3]<=crc_out[3][crc_c-1];
end
else if (transf_cnt==`BIT_BLOCK-2) begin
DAT_oe_o<=1;
DAT_dat_o<=4'b1111;
rd<=0;
end
else if (transf_cnt !=0) begin
DAT_oe_o<=0;
rd<=0;
end
end
WRITE_CRC : begin
rd<=0;
DAT_oe_o<=0;
crc_status<=crc_status-1;
if (( crc_status<=4) && ( crc_status>=2) )
crc_s[crc_status-2] <=DAT_dat_i[0];
end
WRITE_BUSY : begin
transm_complete <=1;
if (crc_s == 3'b010)
crc_ok<=1;
else
crc_ok<=0;
busy_int<=DAT_dat_i[0];
end
READ_WAIT:begin
DAT_oe_o<=0;
crc_rst<=0;
crc_en<=1;
crc_in<=0;
crc_c<=15;// end
busy_n<=0;
transm_complete<=0;
end
READ_DAT: begin
if (transf_cnt<`BIT_BLOCK_REC) begin
we<=1;
data_out<=DAT_dat_i;
crc_in<=DAT_dat_i;
crc_ok<=1;
transf_cnt<=transf_cnt+1;
end
else if ( transf_cnt <= (`BIT_BLOCK_REC +`BIT_CRC_CYCLE)) begin
transf_cnt<=transf_cnt+1;
crc_en<=0;
last_din <=DAT_dat_i;
if (transf_cnt> `BIT_BLOCK_REC) begin
crc_c<=crc_c-1;
we<=0;
`ifdef SD_BUS_WIDTH_1
if (crc_out[0][crc_status] == last_din[0])
crc_ok<=0;
`endif
`ifdef SD_BUS_WIDTH_4
if (crc_out[0][crc_c] != last_din[0])
crc_ok<=0;
if (crc_out[1][crc_c] != last_din[1])
crc_ok<=0;
if (crc_out[2][crc_c] != last_din[2])
crc_ok<=0;
if (crc_out[3][crc_c] != last_din[3])
crc_ok<=0;
`endif
`ifdef SIM
crc_ok<=1;
`endif
if (crc_c==0) begin
transm_complete <=1;
busy_n<=0;
we<=0;
end
end
end
end
endcase
end
 
end
 
 
 
 
 
 
 
 
//Sync
 
 
 
 
 
endmodule
 
 
 
 
 
/sdc_dma/verilog/fifo/smii_rx_fifo.v
1,121 → 1,121
`include "SD_defines.v"
 
module sd_rx_fifo
(
input [4-1:0] d,
input wr,
input wclk,
output [32-1:0] q,
input rd,
output full,
output empty,
output [1:0] mem_empt,
input rclk,
input rst
);
reg [32-1:0] ram [0:`FIFO_RX_MEM_DEPTH-1];
reg [`FIFO_RX_MEM_ADR_SIZE-1:0] adr_i, adr_o;
wire ram_we;
wire [32-1:0] ram_din;
reg [8-1:0] we;
reg [4*(8)-1:0] tmp;
reg ft;
always @ (posedge wclk or posedge rst)
if (rst)
we <= 8'h1;
else
if (wr)
we <= {we[8-2:0],we[8-1]};
always @ (posedge wclk or posedge rst)
if (rst) begin
tmp <= {4*(8-1){1'b0}};
ft<=0;
end
else
begin
`ifdef BIG_ENDIAN
if (wr & we[7]) begin
tmp[4*1-1:4*0] <= d;
ft<=1; end
if (wr & we[6])
tmp[4*2-1:4*1] <= d;
if (wr & we[5])
tmp[4*3-1:4*2] <= d;
if (wr & we[4])
tmp[4*4-1:4*3] <= d;
if (wr & we[3])
tmp[4*5-1:4*4] <= d;
if (wr & we[2])
tmp[4*6-1:4*5] <= d;
if (wr & we[1])
tmp[4*7-1:4*6] <= d;
if (wr & we[0])
tmp[4*8-1:4*7] <= d;
`endif
`ifdef LITTLE_ENDIAN
if (wr & we[0])
tmp[4*1-1:4*0] <= d;
if (wr & we[1])
tmp[4*2-1:4*1] <= d;
if (wr & we[2])
tmp[4*3-1:4*2] <= d;
if (wr & we[3])
tmp[4*4-1:4*3] <= d;
if (wr & we[4])
tmp[4*5-1:4*4] <= d;
if (wr & we[5])
tmp[4*6-1:4*5] <= d;
if (wr & we[6])
tmp[4*7-1:4*6] <= d;
if (wr & we[7]) begin
tmp[4*8-1:4*7] <= d;
ft<=1;
end
`endif
end
assign ram_we = wr & we[0] &ft;
assign ram_din = tmp;
always @ (posedge wclk)
if (ram_we)
ram[adr_i[`FIFO_RX_MEM_ADR_SIZE-2:0]] <= ram_din;
always @ (posedge wclk or posedge rst)
if (rst)
adr_i <= `FIFO_RX_MEM_ADR_SIZE'h0;
else
if (ram_we)
if (adr_i == `FIFO_RX_MEM_DEPTH-1) begin
adr_i[`FIFO_RX_MEM_ADR_SIZE-2:0] <=0;
adr_i[`FIFO_RX_MEM_ADR_SIZE-1]<=~adr_i[`FIFO_RX_MEM_ADR_SIZE-1];
end
else
adr_i <= adr_i + `FIFO_RX_MEM_ADR_SIZE'h1;
always @ (posedge rclk or posedge rst)
if (rst)
adr_o <= `FIFO_RX_MEM_ADR_SIZE'h0;
else
if (!empty & rd)
if (adr_o == `FIFO_RX_MEM_DEPTH-1) begin
adr_o[`FIFO_RX_MEM_ADR_SIZE-2:0] <=0;
adr_o[`FIFO_RX_MEM_ADR_SIZE-1] <=~adr_o[`FIFO_RX_MEM_ADR_SIZE-1];
end
else
adr_o <= adr_o + `FIFO_RX_MEM_ADR_SIZE'h1;
//------------------------------------------------------------------
// Simplified version of the three necessary full-tests:
// assign wfull_val=((wgnext[ADDRSIZE] !=wq2_rptr[ADDRSIZE] ) &&
// (wgnext[ADDRSIZE-1] !=wq2_rptr[ADDRSIZE-1]) &&
// (wgnext[ADDRSIZE-2:0]==wq2_rptr[ADDRSIZE-2:0]));
//------------------------------------------------------------------
assign full = (adr_i[`FIFO_RX_MEM_ADR_SIZE-2:0] == adr_o[`FIFO_RX_MEM_ADR_SIZE-2:0] ) & (adr_i[`FIFO_RX_MEM_ADR_SIZE-1] ^ adr_o[`FIFO_RX_MEM_ADR_SIZE-1]) ;
assign empty = (adr_i == adr_o) ;
assign mem_empt = ( adr_i-adr_o);
assign q = ram[adr_o[`FIFO_RX_MEM_ADR_SIZE-2:0]];
endmodule
`include "SD_defines.v"
`include "timescale.v"
module sd_rx_fifo
(
input [4-1:0] d,
input wr,
input wclk,
output [32-1:0] q,
input rd,
output full,
output empty,
output [1:0] mem_empt,
input rclk,
input rst
);
reg [32-1:0] ram [0:`FIFO_RX_MEM_DEPTH-1];
reg [`FIFO_RX_MEM_ADR_SIZE-1:0] adr_i, adr_o;
wire ram_we;
wire [32-1:0] ram_din;
reg [8-1:0] we;
reg [4*(8)-1:0] tmp;
reg ft;
always @ (posedge wclk or posedge rst)
if (rst)
we <= 8'h1;
else
if (wr)
we <= {we[8-2:0],we[8-1]};
always @ (posedge wclk or posedge rst)
if (rst) begin
tmp <= {4*(8-1){1'b0}};
ft<=0;
end
else
begin
`ifdef BIG_ENDIAN
if (wr & we[7]) begin
tmp[4*1-1:4*0] <= d;
ft<=1; end
if (wr & we[6])
tmp[4*2-1:4*1] <= d;
if (wr & we[5])
tmp[4*3-1:4*2] <= d;
if (wr & we[4])
tmp[4*4-1:4*3] <= d;
if (wr & we[3])
tmp[4*5-1:4*4] <= d;
if (wr & we[2])
tmp[4*6-1:4*5] <= d;
if (wr & we[1])
tmp[4*7-1:4*6] <= d;
if (wr & we[0])
tmp[4*8-1:4*7] <= d;
`endif
`ifdef LITTLE_ENDIAN
if (wr & we[0])
tmp[4*1-1:4*0] <= d;
if (wr & we[1])
tmp[4*2-1:4*1] <= d;
if (wr & we[2])
tmp[4*3-1:4*2] <= d;
if (wr & we[3])
tmp[4*4-1:4*3] <= d;
if (wr & we[4])
tmp[4*5-1:4*4] <= d;
if (wr & we[5])
tmp[4*6-1:4*5] <= d;
if (wr & we[6])
tmp[4*7-1:4*6] <= d;
if (wr & we[7]) begin
tmp[4*8-1:4*7] <= d;
ft<=1;
end
`endif
end
assign ram_we = wr & we[0] &ft;
assign ram_din = tmp;
always @ (posedge wclk)
if (ram_we)
ram[adr_i[`FIFO_RX_MEM_ADR_SIZE-2:0]] <= ram_din;
always @ (posedge wclk or posedge rst)
if (rst)
adr_i <= `FIFO_RX_MEM_ADR_SIZE'h0;
else
if (ram_we)
if (adr_i == `FIFO_RX_MEM_DEPTH-1) begin
adr_i[`FIFO_RX_MEM_ADR_SIZE-2:0] <=0;
adr_i[`FIFO_RX_MEM_ADR_SIZE-1]<=~adr_i[`FIFO_RX_MEM_ADR_SIZE-1];
end
else
adr_i <= adr_i + `FIFO_RX_MEM_ADR_SIZE'h1;
always @ (posedge rclk or posedge rst)
if (rst)
adr_o <= `FIFO_RX_MEM_ADR_SIZE'h0;
else
if (!empty & rd)
if (adr_o == `FIFO_RX_MEM_DEPTH-1) begin
adr_o[`FIFO_RX_MEM_ADR_SIZE-2:0] <=0;
adr_o[`FIFO_RX_MEM_ADR_SIZE-1] <=~adr_o[`FIFO_RX_MEM_ADR_SIZE-1];
end
else
adr_o <= adr_o + `FIFO_RX_MEM_ADR_SIZE'h1;
//------------------------------------------------------------------
// Simplified version of the three necessary full-tests:
// assign wfull_val=((wgnext[ADDRSIZE] !=wq2_rptr[ADDRSIZE] ) &&
// (wgnext[ADDRSIZE-1] !=wq2_rptr[ADDRSIZE-1]) &&
// (wgnext[ADDRSIZE-2:0]==wq2_rptr[ADDRSIZE-2:0]));
//------------------------------------------------------------------
assign full = (adr_i[`FIFO_RX_MEM_ADR_SIZE-2:0] == adr_o[`FIFO_RX_MEM_ADR_SIZE-2:0] ) & (adr_i[`FIFO_RX_MEM_ADR_SIZE-1] ^ adr_o[`FIFO_RX_MEM_ADR_SIZE-1]) ;
assign empty = (adr_i == adr_o) ;
assign mem_empt = ( adr_i-adr_o);
assign q = ram[adr_o[`FIFO_RX_MEM_ADR_SIZE-2:0]];
endmodule
/sdc_dma/verilog/fifo/smii_tx_fifo.v
1,6 → 1,6
 
`include "timescale.v"
`include "SD_defines.v"
 
 
module sd_tx_fifo
(
input [32-1:0] d,
/sdc_dma/verilog/fifo/SD_defines.v
3,8 → 3,8
`define BIG_ENDIAN
//`define LITLE_ENDIAN
 
//`define SIM
`define SYN
`define SIM
//`define SYN
 
`define IRQ_ENABLE
`define ACTEL
/sdc_dma/verilog/SD_FIFO_TX_Filler.v
58,6 → 58,7
 
reg ackd;
reg delay;
 
always @(posedge clk or posedge rst )begin
if (rst) begin
offset <=0;
/sdc_dma/verilog/SD_defines.v
3,8 → 3,8
`define BIG_ENDIAN
//`define LITLE_ENDIAN
 
//`define SIM
`define SYN
`define SIM
//`define SYN
 
`define IRQ_ENABLE
`define ACTEL
14,28 → 14,30
//`define XLINX
//`define SIMULATOR
 
`define RESEND_MAX_CNT 3
 
//MAX 255 BD
//BD size/4
 
`ifdef ACTEL
`define NR_O_BD_4
`define BD_WIDTH 5
`define BD_SIZE 32
`define NR_O_BD_4
`define BD_WIDTH 5
`define BD_SIZE 32
`define RAM_MEM_WIDTH_16
`define RAM_MEM_WIDTH 16
`define RAM_MEM_WIDTH 16
`endif
 
`ifdef CUSTOM
`define NR_O_BD_4
`define BD_WIDTH 5
`define BD_SIZE 32
`define RAM_MEM_WIDTH_32
`define RAM_MEM_WIDTH 32
`endif
//`ifdef CUSTOM
// `define NR_O_BD_4
// `define BD_WIDTH 5
// `define BD_SIZE 32
// `define RAM_MEM_WIDTH_32
// `define RAM_MEM_WIDTH 32
//`endif
 
`define RESEND_MAX_CNT 3
 
 
`ifdef SYN
`define RESET_CLK_DIV 1
`define MEM_OFFSET 4
43,7 → 45,7
 
`ifdef SIM
`define RESET_CLK_DIV 0
`define MEM_OFFSET 1
`define MEM_OFFSET 4
`endif
 
//SD-Clock Defines ---------
/sdc_dma/verilog/SD_data_master.v
1,516 → 1,510
`include "SD_defines.v"
 
module SD_DATA_MASTER (
input clk,
input rst,
//Tx Bd
input [`RAM_MEM_WIDTH-1:0] dat_in_tx,
input [`BD_WIDTH-1:0] free_tx_bd,
input ack_i_s_tx,
output reg re_s_tx,
output reg a_cmp_tx,
//Rx Bd
 
input [`RAM_MEM_WIDTH-1:0] dat_in_rx,
input [`BD_WIDTH-1:0] free_rx_bd,
input ack_i_s_rx,
output reg re_s_rx,
output reg a_cmp_rx,
//Input from SD-Host Reg
input cmd_busy, //STATUS_REG[0] and mux
//Output to SD-Host Reg
output reg we_req,
input we_ack,
output reg d_write,
output reg d_read,
output reg [31:0] cmd_arg,
output reg [15:0] cmd_set,
input cmd_tsf_err,
input [4:0] card_status,
//To fifo filler
output reg start_tx_fifo,
output reg start_rx_fifo,
output reg [31:0] sys_adr,
input tx_empt,
input tx_full,
input rx_full,
//SD-DATA_Host
input busy_n ,
input transm_complete ,
input crc_ok,
output reg ack_transfer,
//status output
output reg [7:0] Dat_Int_Status ,
input Dat_Int_Status_rst,
output reg CIDAT
);
 
`ifdef RAM_MEM_WIDTH_32
`define READ_CYCLE 2
reg [1:0]bd_cnt ;
`define BD_EMPTY (`BD_SIZE /2)
`else `ifdef RAM_MEM_WIDTH_16
`define READ_CYCLE 4
reg [2:0] bd_cnt;
`define BD_EMPTY (`BD_SIZE /4)
`endif
`endif
 
reg send_done;
reg rec_done;
reg rec_failed;
reg tx_cycle;
reg rx_cycle;
reg [2:0] resend_try_cnt;
`ifdef SIM
parameter CMD24 = 16'h181A ; //11000 0001 1010
parameter CMD17 = 16'h111A; //10001 0001 1010
parameter CMD12 = 16'hC1A ; //01100 0001 1010
`else
parameter CMD24 = 16'h181A;
parameter CMD17 = 16'h111A;
parameter CMD12 = 16'hC1A ;
`endif
parameter SIZE = 9;
reg [SIZE-1:0] state;
reg [SIZE-1:0] next_state;
parameter IDLE = 9'b000000001;
parameter GET_TX_BD = 9'b000000010;
parameter GET_RX_BD = 9'b000000100;
parameter SEND_CMD = 9'b000001000;
parameter RECIVE_CMD = 9'b000010000;
parameter DATA_TRANSFER = 9'b000100000;
parameter STOP = 9'b001000000;
parameter STOP_SEND = 9'b010000000;
parameter STOP_RECIVE_CMD = 9'b100000000;
 
reg trans_done;
reg trans_failed;
reg internal_transm_complete;
reg transm_complete_q;
 
always @ (posedge clk or posedge rst )
begin
if (rst) begin
internal_transm_complete <=1'b0;
transm_complete_q<=0;
end
else begin
transm_complete_q<=transm_complete;
internal_transm_complete<=transm_complete_q;
end
 
 
end
 
 
 
 
always @ (state or resend_try_cnt or tx_full or free_tx_bd or free_rx_bd or bd_cnt or send_done or rec_done or rec_failed or trans_done or trans_failed)
begin : FSM_COMBO
next_state = 0;
case(state)
IDLE: begin
if (free_tx_bd !=`BD_EMPTY)begin
next_state = GET_TX_BD;
end
else if (free_rx_bd !=`BD_EMPTY) begin
next_state = GET_RX_BD;
end
else begin
next_state = IDLE;
end
end
GET_TX_BD: begin
if ( ( bd_cnt> `READ_CYCLE-1) && (tx_full==1) )begin
next_state = SEND_CMD;
end
else begin
next_state = GET_TX_BD;
end
end
GET_RX_BD: begin
if (bd_cnt >= (`READ_CYCLE-1))begin
next_state = SEND_CMD;
end
else begin
next_state = GET_RX_BD;
end
end
SEND_CMD: begin
if (send_done)begin
next_state = RECIVE_CMD;
end
else begin
next_state = SEND_CMD;
end
end
RECIVE_CMD: begin
if (rec_done)
next_state = DATA_TRANSFER;
else if (rec_failed)
next_state = SEND_CMD;
else
next_state = RECIVE_CMD;
end
 
DATA_TRANSFER: begin
if (trans_done)
next_state = IDLE;
else if (trans_failed)
next_state = STOP;
else
next_state = DATA_TRANSFER;
end
STOP: begin
next_state = STOP_SEND;
end
STOP_SEND: begin
if (send_done)begin
next_state = STOP_RECIVE_CMD;
end
else begin
next_state = STOP_SEND;
end
end
STOP_RECIVE_CMD : begin
if (rec_done)
next_state = SEND_CMD;
else if (rec_failed)
next_state = STOP;
else if (resend_try_cnt>=`RESEND_MAX_CNT)
next_state = IDLE;
else
next_state = STOP_RECIVE_CMD;
end
default : next_state = IDLE;
endcase
 
end
 
//----------------Seq logic------------
always @ (posedge clk or posedge rst )
begin : FSM_SEQ
if (rst ) begin
state <= #1 IDLE;
end
else begin
state <= #1 next_state;
end
end
 
 
 
//Output logic-----------------
 
 
always @ (posedge clk or posedge rst )
begin
if (rst) begin
send_done<=0;
bd_cnt<=0;
sys_adr<=0;
cmd_arg<=0;
rec_done<=0;
start_tx_fifo<=0;
start_rx_fifo<=0;
send_done<=0;
rec_failed<=0;
d_write <=0;
d_read <=0;
trans_failed<=0;
trans_done<=0;
tx_cycle <=0;
rx_cycle <=0;
ack_transfer<=0;
a_cmp_tx<=0;
a_cmp_rx<=0;
CIDAT<=0;
Dat_Int_Status<=0;
we_req<=0;
re_s_tx<=0;
re_s_rx<=0;
cmd_set<=0;
resend_try_cnt=0;
end
else begin
case(state)
IDLE: begin
send_done<=0;
bd_cnt<=0;
sys_adr<=0;
cmd_arg<=0;
rec_done<=0;
rec_failed<=0;
start_tx_fifo<=0;
start_rx_fifo<=0;
send_done<=0;
d_write <=0;
d_read <=0;
trans_failed<=0;
trans_done<=0;
tx_cycle <=0;
rx_cycle <=0;
ack_transfer<=0;
a_cmp_tx<=0;
a_cmp_rx<=0;
resend_try_cnt=0;
end
GET_RX_BD: begin
//0,1,2,3...
re_s_rx <= 1;
`ifdef RAM_MEM_WIDTH_32
if (ack_i_s_rx) begin
if( bd_cnt == 2'b0) begin
sys_adr <= dat_in_rx;
bd_cnt <= bd_cnt+1;
end
else if ( bd_cnt == 2'b1) begin
cmd_arg <= dat_in_rx;
re_s_rx <= 0;
end
end
`endif
`ifdef RAM_MEM_WIDTH_16
if (ack_i_s_rx) begin
if( bd_cnt == 2'b00) begin
sys_adr [15:0] <= dat_in_rx;
end
else if ( bd_cnt == 2'b01) begin
sys_adr [31:16] <= dat_in_rx;
end
else if ( bd_cnt == 2) begin
cmd_arg [15:0] <= dat_in_rx;
re_s_rx <= 0;
end
else if ( bd_cnt == 3) begin
cmd_arg [31:16] <= dat_in_rx;
re_s_rx <= 0;
end
bd_cnt <= bd_cnt+1;
end
`endif
//Add Later Save last block addres for comparison with current (For multiple block cmd)
//Add support for Pre-erased
cmd_set <= CMD17;
rx_cycle<=1;
end
GET_TX_BD: begin
//0,1,2,3...
re_s_tx <= 1;
if ( bd_cnt == `READ_CYCLE)
re_s_tx <= 0;
`ifdef RAM_MEM_WIDTH_32
if (ack_i_s_tx) begin
if( bd_cnt == 2'b0) begin
sys_adr <= dat_in_tx;
bd_cnt <= bd_cnt+1;
end
else if ( bd_cnt == 2'b1) begin
cmd_arg <= dat_in_tx;
re_s_tx <= 0;
end
end
`endif
`ifdef RAM_MEM_WIDTH_16
if (ack_i_s_tx) begin
if( bd_cnt == 0) begin
sys_adr [15:0] <= dat_in_tx;
bd_cnt <= bd_cnt+1; end
else if ( bd_cnt == 1) begin
sys_adr [31:16] <= dat_in_tx;
bd_cnt <= bd_cnt+1; end
else if ( bd_cnt == 2) begin
cmd_arg [15:0] <= dat_in_tx;
re_s_tx <= 0;
bd_cnt <= bd_cnt+1; end
else if ( bd_cnt == 3) begin
cmd_arg [31:16] <= dat_in_tx;
re_s_tx <= 0;
bd_cnt <= bd_cnt+1;
end
end
`endif
//Add Later Save last block addres for comparison with current (For multiple block cmd)
//Add support for Pre-erased
cmd_set <= CMD24;
tx_cycle <=1;
start_tx_fifo<=1;
end
SEND_CMD : begin
rec_done<=0;
if (rx_cycle) begin
re_s_rx <=0;
d_read<=1;
end
else begin
re_s_tx <=0;
d_write<=1;
end
start_rx_fifo<=0; //Reset FIFO
// start_tx_fifo<=0; //Reset FIFO
if (!cmd_busy) begin
we_req <= 1;
end //When send complete change state and wait for reply
if (we_ack) begin
send_done<=1;
we_req <= 1;
end
end
RECIVE_CMD : begin
//When waiting for reply fill TX fifo
if (rx_cycle)
start_rx_fifo<=1; //start_fifo prebuffering
//else
//start_rx_fifo <=1;
we_req <= 0;
send_done<=0;
if (!cmd_busy) begin //Means the sending is completed,
d_read<=0;
d_write<=0;
if (!cmd_tsf_err) begin
if (card_status[0]) begin
`ifdef SYN
if ( (card_status[4:1] == 4'b0100) || (card_status[4:1] == 4'b0110) || (card_status[4:1] == 4'b0101) )
rec_done<=1;
else begin
rec_failed<=1;
Dat_Int_Status[4] <=1;
start_tx_fifo<=0;
end
`endif
//Check card_status[5:1] for state 4 or 6...
//If wrong state change interupt status reg,so software can put card in
// transfer state and restart/cancel Data transfer
end
`ifdef SIM
rec_done<=1;
start_tx_fifo<=1;
`endif
end
else begin
rec_failed<=1; //CRC-Error, CIC-Error or timeout
start_tx_fifo<=0;
`ifdef SIM
rec_done<=1;
start_tx_fifo<=1;
`endif end
end
end
DATA_TRANSFER: begin
CIDAT<=1;
if (tx_cycle) begin
if (tx_empt) begin
Dat_Int_Status[2] <=1;
trans_failed<=1;
end
end
else begin
if (rx_full) begin
Dat_Int_Status[2] <=1;
trans_failed<=1;
end
end
//Check for fifo underflow,
//2 DO: if deteced stop transfer, reset data host
if (internal_transm_complete) begin //Transfer complete
ack_transfer<=1;
if ((!crc_ok) && (busy_n)) begin //Wrong CRC and Data line free.
Dat_Int_Status[5] <=1;
trans_failed<=1;
end
else if ((crc_ok) && (busy_n)) begin //Data Line free
trans_done <=1;
Dat_Int_Status[0]<=1;
if (tx_cycle)
a_cmp_tx<=1;
else
a_cmp_rx<=1;
end
end
end
STOP: begin
cmd_set <= CMD12;
rec_done<=0;
rec_failed<=0;
send_done<=0;
trans_failed<=0;
trans_done<=0;
d_read<=1;
d_write<=1;
start_rx_fifo <=0;
start_tx_fifo <=0;
end
STOP_SEND: begin
resend_try_cnt=resend_try_cnt+1;
if (resend_try_cnt==`RESEND_MAX_CNT)
Dat_Int_Status[1]<=1;
if (!cmd_busy)
we_req <= 1;
if (we_ack)
send_done<=1;
end
STOP_RECIVE_CMD: begin
we_req <= 0;
if (!cmd_busy) begin //Means the sending is completed,
if (!cmd_tsf_err) begin
rec_done<=1;
send_done<=0;
d_read<=0;
d_write<=0;
if (tx_cycle)
cmd_set<= CMD24;
else
cmd_set <= CMD17;
end
else
rec_failed<=1;
end
end
endcase
if (Dat_Int_Status_rst)
Dat_Int_Status<=0;
end
end
endmodule
`include "SD_defines.v"
 
module SD_DATA_MASTER (
input clk,
input rst,
//Tx Bd
input [`RAM_MEM_WIDTH-1:0] dat_in_tx,
input [`BD_WIDTH-1:0] free_tx_bd,
input ack_i_s_tx,
output reg re_s_tx,
output reg a_cmp_tx,
//Rx Bd
 
input [`RAM_MEM_WIDTH-1:0] dat_in_rx,
input [`BD_WIDTH-1:0] free_rx_bd,
input ack_i_s_rx,
output reg re_s_rx,
output reg a_cmp_rx,
//Input from SD-Host Reg
input cmd_busy, //STATUS_REG[0] and mux
//Output to SD-Host Reg
output reg we_req,
input we_ack,
output reg d_write,
output reg d_read,
output reg [31:0] cmd_arg,
output reg [15:0] cmd_set,
input cmd_tsf_err,
input [4:0] card_status,
//To fifo filler
output reg start_tx_fifo,
output reg start_rx_fifo,
output reg [31:0] sys_adr,
input tx_empt,
input tx_full,
input rx_full,
//SD-DATA_Host
input busy_n ,
input transm_complete ,
input crc_ok,
output reg ack_transfer,
//status output
output reg [7:0] Dat_Int_Status ,
input Dat_Int_Status_rst,
output reg CIDAT
);
`define RESEND_MAX_CNT 3
`ifdef RAM_MEM_WIDTH_32
`define READ_CYCLE 2
reg [1:0]bd_cnt ;
`define BD_EMPTY (`BD_SIZE /2)
`else `ifdef RAM_MEM_WIDTH_16
`define READ_CYCLE 4
reg [2:0] bd_cnt;
`define BD_EMPTY (`BD_SIZE /4)
`endif
`endif
 
reg send_done;
reg rec_done;
reg rec_failed;
reg tx_cycle;
reg rx_cycle;
reg [2:0] resend_try_cnt;
`ifdef SIM
parameter CMD24 = 16'h181A ; //11000 0001 1010
parameter CMD17 = 16'h111A; //10001 0001 1010
parameter CMD12 = 16'hC1A ; //01100 0001 1010
`else
parameter CMD24 = 16'h181A;
parameter CMD17 = 16'h111A;
parameter CMD12 = 16'hC1A ;
`endif
parameter SIZE = 9;
reg [SIZE-1:0] state;
reg [SIZE-1:0] next_state;
parameter IDLE = 9'b000000001;
parameter GET_TX_BD = 9'b000000010;
parameter GET_RX_BD = 9'b000000100;
parameter SEND_CMD = 9'b000001000;
parameter RECIVE_CMD = 9'b000010000;
parameter DATA_TRANSFER = 9'b000100000;
parameter STOP = 9'b001000000;
parameter STOP_SEND = 9'b010000000;
parameter STOP_RECIVE_CMD = 9'b100000000;
 
reg trans_done;
reg trans_failed;
reg internal_transm_complete;
reg transm_complete_q;
 
always @ (posedge clk or posedge rst )
begin
if (rst) begin
internal_transm_complete <=1'b0;
transm_complete_q<=0;
end
else begin
transm_complete_q<=transm_complete;
internal_transm_complete<=transm_complete_q;
end
 
 
end
 
 
 
 
always @ (state or resend_try_cnt or tx_full or free_tx_bd or free_rx_bd or bd_cnt or send_done or rec_done or rec_failed or trans_done or trans_failed)
begin : FSM_COMBO
next_state = 0;
case(state)
IDLE: begin
if (free_tx_bd !=`BD_EMPTY)begin
next_state = GET_TX_BD;
end
else if (free_rx_bd !=`BD_EMPTY) begin
next_state = GET_RX_BD;
end
else begin
next_state = IDLE;
end
end
GET_TX_BD: begin
if ( ( bd_cnt> `READ_CYCLE-1) && (tx_full==1) )begin
next_state = SEND_CMD;
end
else begin
next_state = GET_TX_BD;
end
end
GET_RX_BD: begin
if (bd_cnt >= (`READ_CYCLE-1))begin
next_state = SEND_CMD;
end
else begin
next_state = GET_RX_BD;
end
end
SEND_CMD: begin
if (send_done)begin
next_state = RECIVE_CMD;
end
else begin
next_state = SEND_CMD;
end
end
RECIVE_CMD: begin
if (rec_done)
next_state = DATA_TRANSFER;
else if (rec_failed)
next_state = SEND_CMD;
else
next_state = RECIVE_CMD;
end
 
DATA_TRANSFER: begin
if (trans_done)
next_state = IDLE;
else if (trans_failed)
next_state = STOP;
else
next_state = DATA_TRANSFER;
end
STOP: begin
next_state = STOP_SEND;
end
STOP_SEND: begin
if (send_done)begin
next_state = STOP_RECIVE_CMD;
end
else begin
next_state = STOP_SEND;
end
end
STOP_RECIVE_CMD : begin
if (rec_done)
next_state = SEND_CMD;
else if (rec_failed)
next_state = STOP;
else if (resend_try_cnt>=`RESEND_MAX_CNT)
next_state = IDLE;
else
next_state = STOP_RECIVE_CMD;
end
default : next_state = IDLE;
endcase
 
end
 
//----------------Seq logic------------
always @ (posedge clk or posedge rst )
begin : FSM_SEQ
if (rst ) begin
state <= #1 IDLE;
end
else begin
state <= #1 next_state;
end
end
 
 
 
//Output logic-----------------
 
 
always @ (posedge clk or posedge rst )
begin
if (rst) begin
send_done<=0;
bd_cnt<=0;
sys_adr<=0;
cmd_arg<=0;
rec_done<=0;
start_tx_fifo<=0;
start_rx_fifo<=0;
send_done<=0;
rec_failed<=0;
d_write <=0;
d_read <=0;
trans_failed<=0;
trans_done<=0;
tx_cycle <=0;
rx_cycle <=0;
ack_transfer<=0;
a_cmp_tx<=0;
a_cmp_rx<=0;
CIDAT<=0;
Dat_Int_Status<=0;
we_req<=0;
re_s_tx<=0;
re_s_rx<=0;
cmd_set<=0;
resend_try_cnt=0;
end
else begin
case(state)
IDLE: begin
send_done<=0;
bd_cnt<=0;
sys_adr<=0;
cmd_arg<=0;
rec_done<=0;
rec_failed<=0;
start_tx_fifo<=0;
start_rx_fifo<=0;
send_done<=0;
d_write <=0;
d_read <=0;
trans_failed<=0;
trans_done<=0;
tx_cycle <=0;
rx_cycle <=0;
ack_transfer<=0;
a_cmp_tx<=0;
a_cmp_rx<=0;
resend_try_cnt=0;
end
GET_RX_BD: begin
//0,1,2,3...
re_s_rx <= 1;
`ifdef RAM_MEM_WIDTH_32
if (ack_i_s_rx) begin
if( bd_cnt == 2'b0) begin
sys_adr <= dat_in_rx;
bd_cnt <= bd_cnt+1;
end
else if ( bd_cnt == 2'b1) begin
cmd_arg <= dat_in_rx;
re_s_rx <= 0;
end
end
`endif
`ifdef RAM_MEM_WIDTH_16
if (ack_i_s_rx) begin
if( bd_cnt == 2'b00) begin
sys_adr [15:0] <= dat_in_rx;
end
else if ( bd_cnt == 2'b01) begin
sys_adr [31:16] <= dat_in_rx;
end
else if ( bd_cnt == 2) begin
cmd_arg [15:0] <= dat_in_rx;
re_s_rx <= 0;
end
else if ( bd_cnt == 3) begin
cmd_arg [31:16] <= dat_in_rx;
re_s_rx <= 0;
end
bd_cnt <= bd_cnt+1;
end
`endif
//Add Later Save last block addres for comparison with current (For multiple block cmd)
//Add support for Pre-erased
cmd_set <= CMD17;
rx_cycle<=1;
end
GET_TX_BD: begin
//0,1,2,3...
re_s_tx <= 1;
if ( bd_cnt == `READ_CYCLE)
re_s_tx <= 0;
`ifdef RAM_MEM_WIDTH_32
if (ack_i_s_tx) begin
if( bd_cnt == 2'b0) begin
sys_adr <= dat_in_tx;
bd_cnt <= bd_cnt+1;
end
else if ( bd_cnt == 2'b1) begin
cmd_arg <= dat_in_tx;
re_s_tx <= 0;
end
end
`endif
`ifdef RAM_MEM_WIDTH_16
if (ack_i_s_tx) begin
if( bd_cnt == 0) begin
sys_adr [15:0] <= dat_in_tx;
bd_cnt <= bd_cnt+1; end
else if ( bd_cnt == 1) begin
sys_adr [31:16] <= dat_in_tx;
bd_cnt <= bd_cnt+1; end
else if ( bd_cnt == 2) begin
cmd_arg [15:0] <= dat_in_tx;
re_s_tx <= 0;
bd_cnt <= bd_cnt+1; end
else if ( bd_cnt == 3) begin
cmd_arg [31:16] <= dat_in_tx;
re_s_tx <= 0;
bd_cnt <= bd_cnt+1;
end
end
`endif
//Add Later Save last block addres for comparison with current (For multiple block cmd)
//Add support for Pre-erased
cmd_set <= CMD24;
tx_cycle <=1;
start_tx_fifo<=1;
end
SEND_CMD : begin
rec_done<=0;
if (rx_cycle) begin
re_s_rx <=0;
d_read<=1;
end
else begin
re_s_tx <=0;
d_write<=1;
end
start_rx_fifo<=0; //Reset FIFO
// start_tx_fifo<=0; //Reset FIFO
if (!cmd_busy) begin
we_req <= 1;
end //When send complete change state and wait for reply
if (we_ack) begin
send_done<=1;
we_req <= 1;
end
end
RECIVE_CMD : begin
//When waiting for reply fill TX fifo
if (rx_cycle)
start_rx_fifo<=1; //start_fifo prebuffering
//else
//start_rx_fifo <=1;
we_req <= 0;
send_done<=0;
if (!cmd_busy) begin //Means the sending is completed,
d_read<=0;
d_write<=0;
if (!cmd_tsf_err) begin
if (card_status[0]) begin
if ( (card_status[4:1] == 4'b0100) || (card_status[4:1] == 4'b0110) || (card_status[4:1] == 4'b0101) )
rec_done<=1;
else begin
rec_failed<=1;
Dat_Int_Status[4] <=1;
start_tx_fifo<=0;
end
//Check card_status[5:1] for state 4 or 6...
//If wrong state change interupt status reg,so software can put card in
// transfer state and restart/cancel Data transfer
end
end
else begin
rec_failed<=1; //CRC-Error, CIC-Error or timeout
start_tx_fifo<=0;
end
end
end
DATA_TRANSFER: begin
CIDAT<=1;
if (tx_cycle) begin
if (tx_empt) begin
Dat_Int_Status[2] <=1;
trans_failed<=1;
end
end
else begin
if (rx_full) begin
Dat_Int_Status[2] <=1;
trans_failed<=1;
end
end
//Check for fifo underflow,
//2 DO: if deteced stop transfer, reset data host
if (internal_transm_complete) begin //Transfer complete
ack_transfer<=1;
if ((!crc_ok) && (busy_n)) begin //Wrong CRC and Data line free.
Dat_Int_Status[5] <=1;
trans_failed<=1;
end
else if ((crc_ok) && (busy_n)) begin //Data Line free
trans_done <=1;
Dat_Int_Status[0]<=1;
if (tx_cycle)
a_cmp_tx<=1;
else
a_cmp_rx<=1;
end
end
end
STOP: begin
cmd_set <= CMD12;
rec_done<=0;
rec_failed<=0;
send_done<=0;
trans_failed<=0;
trans_done<=0;
d_read<=1;
d_write<=1;
start_rx_fifo <=0;
start_tx_fifo <=0;
end
STOP_SEND: begin
resend_try_cnt=resend_try_cnt+1;
if (resend_try_cnt==`RESEND_MAX_CNT)
Dat_Int_Status[1]<=1;
if (!cmd_busy)
we_req <= 1;
if (we_ack)
send_done<=1;
end
STOP_RECIVE_CMD: begin
we_req <= 0;
if (!cmd_busy) begin //Means the sending is completed,
if (!cmd_tsf_err) begin
rec_done<=1;
send_done<=0;
d_read<=0;
d_write<=0;
if (tx_cycle)
cmd_set<= CMD24;
else
cmd_set <= CMD17;
end
else
rec_failed<=1;
end
end
endcase
if (Dat_Int_Status_rst)
Dat_Int_Status<=0;
end
end
endmodule

powered by: WebSVN 2.1.0

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