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
    from Rev 119 to Rev 120
    Reverse comparison

Rev 119 → Rev 120

/rtl/sdc_dma/verilog/SD_Bd.v
1,200 → 1,200
 
`include "SD_defines.v"
 
 
 
module SD_Bd (
input clk,
input rst,
//input stb_m,
input we_m,
 
input [`RAM_MEM_WIDTH-1:0] dat_in_m,
 
output reg [`BD_WIDTH-1 :0] free_bd,
 
input re_s,
output reg ack_o_s,
input a_cmp,
output reg[`RAM_MEM_WIDTH-1:0] dat_out_s
);
reg new_bw;
reg last_a_cmp;
`ifdef RAM_MEM_WIDTH_32
`ifdef ACTEL
reg [RAM_MEM_WIDTH -1:0] bd_mem [ `BD_SIZE -1 :0]; /* synthesis syn_ramstyle = "no_rw_check"*/
`else
reg [RAM_MEM_WIDTH -1:0] bd_mem [ `BD_SIZE -1 :0];
`endif
 
reg write_cnt;
reg read_cnt;
reg [`BD_WIDTH -1 :0] m_wr_pnt;
 
reg [`BD_WIDTH -1 :0] s_rd_pnt ;
//Main side read/write
always @(posedge clk or posedge rst )
begin
new_bw =0;
if (rst) begin
m_wr_pnt<=0;
write_cnt<=0;
new_bw =0;
 
end
else if (we_m) begin
if (free_bd >0) begin
write_cnt <=~ write_cnt;
m_wr_pnt<=m_wr_pnt+1;
if (!write_cnt) begin //First write indicate source buffer addr
bd_mem[m_wr_pnt]<=dat_in_m;
end
else begin //Second write indicate SD card block addr
bd_mem[m_wr_pnt]<=dat_in_m;
new_bw =1;
end
end
end
end
 
end
 
always @(posedge clk or posedge rst)
begin
if (rst) begin
free_bd <=(`BD_SIZE /2);
end
else if (new_bw ) begin
free_bd <= free_bd-1;
end
else if (a_cmp) begin
free_bd <= free_bd+1;
end
end
 
 
//Second side read
always @(posedge clk or posedge rst)
begin
if (rst) begin
s_rd_pnt<=0;
end
else if (re_s) begin
s_rd_pnt<=s_rd_pnt+1;
dat_out_s<= bd_mem[s_rd_pnt];
end
end
 
`else `ifdef RAM_MEM_WIDTH_16
`ifdef ACTEL
reg [ `RAM_MEM_WIDTH -1:0] bd_mem [ `BD_SIZE -1 :0]; //synthesis syn_ramstyle = "no_rw_check"
`else
reg [ `RAM_MEM_WIDTH -1:0] bd_mem [ `BD_SIZE -1 :0];
`endif
 
reg [1:0]write_cnt;
reg [1:0]read_s_cnt;
reg read_cnt;
 
reg [`BD_WIDTH -1 :0] m_wr_pnt;
 
reg [`BD_WIDTH -1 :0] s_rd_pnt ;
//Main side read/write
always @(posedge clk or posedge rst )
begin
new_bw =0;
if (rst) begin
m_wr_pnt<=0;
write_cnt<=0;
new_bw =0;
read_cnt<=0;
end
else if (we_m) begin
if (free_bd >0) begin
write_cnt <=write_cnt+1;
m_wr_pnt<=m_wr_pnt+1;
if (!write_cnt[1]) begin //First write indicate source buffer addr (2x16)
bd_mem[m_wr_pnt]<=dat_in_m;
end
else begin //Second write indicate SD card block addr (2x16)
bd_mem[m_wr_pnt]<=dat_in_m;
new_bw =write_cnt[0]; //Second 16 bytes writen, complete BD
end
end
end
 
end
 
always @(posedge clk or posedge rst)
begin
if (rst) begin
free_bd <=(`BD_SIZE /4);
last_a_cmp<=0;
end
else if (new_bw ) begin
free_bd <= free_bd-1;
end
else if (a_cmp) begin
last_a_cmp <=a_cmp;
if (!last_a_cmp)
free_bd <= free_bd+1;
end
else
last_a_cmp <=a_cmp;
end
 
 
//Second side read
always @(posedge clk or posedge rst)
begin
if (rst) begin
s_rd_pnt<=0;
read_s_cnt<=0;
ack_o_s<=0;
end
else if (re_s) begin
read_s_cnt <=read_s_cnt+1;
s_rd_pnt<=s_rd_pnt+1;
ack_o_s<=1;
if (!read_s_cnt[1]) //First read indicate source buffer addr (2x16)
dat_out_s<= bd_mem[s_rd_pnt];
else //Second read indicate SD card block addr (2x16)
dat_out_s<= bd_mem[s_rd_pnt];
end
else
ack_o_s<=0;
end
 
`endif
 
`endif
 
 
endmodule
 
 
`include "SD_defines.v"
 
 
 
module SD_Bd (
input clk,
input rst,
//input stb_m,
input we_m,
 
input [`RAM_MEM_WIDTH-1:0] dat_in_m,
 
output reg [`BD_WIDTH-1 :0] free_bd,
 
input re_s,
output reg ack_o_s,
input a_cmp,
output reg[`RAM_MEM_WIDTH-1:0] dat_out_s
);
reg new_bw;
reg last_a_cmp;
`ifdef RAM_MEM_WIDTH_32
`ifdef ACTEL
reg [`RAM_MEM_WIDTH -1:0] bd_mem [ `BD_SIZE -1 :0]; /* synthesis syn_ramstyle = "no_rw_check"*/
`else
reg [`RAM_MEM_WIDTH -1:0] bd_mem [ `BD_SIZE -1 :0];
`endif
 
reg write_cnt;
reg read_cnt;
reg [`BD_WIDTH -1 :0] m_wr_pnt;
 
reg [`BD_WIDTH -1 :0] s_rd_pnt ;
//Main side read/write
always @(posedge clk or posedge rst )
begin
new_bw =0;
if (rst) begin
m_wr_pnt<=0;
write_cnt<=0;
new_bw =0;
 
end
else if (we_m) begin
if (free_bd >0) begin
write_cnt <=~ write_cnt;
m_wr_pnt<=m_wr_pnt+1;
if (!write_cnt) begin //First write indicate source buffer addr
bd_mem[m_wr_pnt]<=dat_in_m;
end
else begin //Second write indicate SD card block addr
bd_mem[m_wr_pnt]<=dat_in_m;
new_bw =1;
end
end
end
end
 
 
 
always @(posedge clk or posedge rst)
begin
if (rst) begin
free_bd <=(`BD_SIZE /2);
end
else if (new_bw ) begin
free_bd <= free_bd-1;
end
else if (a_cmp) begin
free_bd <= free_bd+1;
end
end
 
 
//Second side read
always @(posedge clk or posedge rst)
begin
if (rst) begin
s_rd_pnt<=0;
end
else if (re_s) begin
s_rd_pnt<=s_rd_pnt+1;
dat_out_s<= bd_mem[s_rd_pnt];
end
end
 
`else `ifdef RAM_MEM_WIDTH_16
`ifdef ACTEL
reg [ `RAM_MEM_WIDTH -1:0] bd_mem [ `BD_SIZE -1 :0]; //synthesis syn_ramstyle = "no_rw_check"
`else
reg [ `RAM_MEM_WIDTH -1:0] bd_mem [ `BD_SIZE -1 :0];
`endif
 
reg [1:0]write_cnt;
reg [1:0]read_s_cnt;
reg read_cnt;
 
reg [`BD_WIDTH -1 :0] m_wr_pnt;
 
reg [`BD_WIDTH -1 :0] s_rd_pnt ;
//Main side read/write
always @(posedge clk or posedge rst )
begin
new_bw =0;
if (rst) begin
m_wr_pnt<=0;
write_cnt<=0;
new_bw =0;
read_cnt<=0;
end
else if (we_m) begin
if (free_bd >0) begin
write_cnt <=write_cnt+1;
m_wr_pnt<=m_wr_pnt+1;
if (!write_cnt[1]) begin //First write indicate source buffer addr (2x16)
bd_mem[m_wr_pnt]<=dat_in_m;
end
else begin //Second write indicate SD card block addr (2x16)
bd_mem[m_wr_pnt]<=dat_in_m;
new_bw =write_cnt[0]; //Second 16 bytes writen, complete BD
end
end
end
 
end
 
always @(posedge clk or posedge rst)
begin
if (rst) begin
free_bd <=(`BD_SIZE /4);
last_a_cmp<=0;
end
else if (new_bw ) begin
free_bd <= free_bd-1;
end
else if (a_cmp) begin
last_a_cmp <=a_cmp;
if (!last_a_cmp)
free_bd <= free_bd+1;
end
else
last_a_cmp <=a_cmp;
end
 
 
//Second side read
always @(posedge clk or posedge rst)
begin
if (rst) begin
s_rd_pnt<=0;
read_s_cnt<=0;
ack_o_s<=0;
end
else if (re_s) begin
read_s_cnt <=read_s_cnt+1;
s_rd_pnt<=s_rd_pnt+1;
ack_o_s<=1;
if (!read_s_cnt[1]) //First read indicate source buffer addr (2x16)
dat_out_s<= bd_mem[s_rd_pnt];
else //Second read indicate SD card block addr (2x16)
dat_out_s<= bd_mem[s_rd_pnt];
end
else
ack_o_s<=0;
end
 
`endif
 
`endif
 
 
endmodule
 
/rtl/sdc_dma/verilog/SD_data_master.v
1,506 → 1,516
`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 BD_EMPTY (`BD_SIZE /4)
`ifdef RAM_MEM_WIDTH_32
`define READ_CYCLE 2
reg [1:0]bd_cnt ;
`else `ifdef RAM_MEM_WIDTH_16
`define READ_CYCLE 4
reg [2:0] bd_cnt;
`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_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
);
 
`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

powered by: WebSVN 2.1.0

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