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/sdc_dma
    from Rev 37 to Rev 38
    Reverse comparison

Rev 37 → Rev 38

/verilog/SD_controller_top.v
15,6 → 15,9
//SD BUS
sd_cmd_dat_i,sd_cmd_out_o, sd_cmd_oe_o,
sd_dat_dat_i, sd_dat_out_o , sd_dat_oe_o, sd_clk_o_pad
`ifdef IRQ_ENABLE
,int_a, int_b, int_c
`endif
);
 
 
58,7 → 61,10
output wire sd_cmd_oe_o;
 
output wire sd_clk_o_pad;
 
//IRQ
`ifdef IRQ_ENABLE
output int_a, int_b, int_c ;
`endif
reg wb_ack_o;
reg wb_inta_o;
reg new_cmd;
124,15 → 130,14
reg [15:0] status_reg;
reg [31:0] cmd_resp_1;
 
reg [7:0] software_reset_reg; //Merge ?
reg [15:0] time_out_reg; //Merge ?
reg [7:0] software_reset_reg;
reg [15:0] time_out_reg;
reg [15:0]normal_int_status_reg;
reg [15:0]error_int_status_reg;
reg [15:0]normal_int_status_enable_reg;
reg [15:0]error_int_status_enable_reg;
//reg [15:0]normal_int_signal_enable_reg;
//reg [15:0]error_int_signal_enable_reg;
reg [15:0]normal_int_signal_enable_reg;
reg [15:0]error_int_signal_enable_reg;
 
 
reg [7:0]clock_divider;
reg [15:0] Bd_Status_reg;
reg [7:0] Bd_isr_reg;
140,6 → 145,9
 
 
reg Bd_isr_reset;
reg normal_isr_reset;
reg error_isr_reset;
 
//Add blockram for bigger BD defines.
192,7 → 200,6
assign cmd_busy = int_busy | status_reg[0];
wire sd_clk_o;
 
 
wire [7:0] bd_int_st_w;
`ifdef SD_CLK_BUS_CLK
assign sd_clk_i = wb_clk_i;
233,6 → 240,8
 
.ERR_INT_REG (error_int_status_reg_w),
.NORMAL_INT_REG (normal_int_status_reg_w),
.ERR_INT_RST (error_isr_reset),
.NORMAL_INT_RST (normal_isr_reset),
.CLK_DIVIDER (clock_divider),
.st_dat_t (st_dat_t)
);
268,6 → 277,7
.start_rx_fifo (start_r),
.sys_adr (sys_adr),
.tx_empt (tx_e ),
.tx_full (tx_f ),
.rx_full(full_rx ),
.busy_n (busy_n),
.transm_complete (trans_complete ),
284,7 → 294,7
wire [`SD_BUS_W -1 : 0 ]data_in_rx_fifo;
 
wire stop_transf;
wire [`SD_BUS_W -1 : 0 ] data_out_tx_fifo;
wire [31: 0 ] data_out_tx_fifo;
SD_DATA_SERIAL_HOST SD_DATA_SERIAL_HOST_1(
.sd_clk (sd_clk_o),
367,7 → 377,8
.sd_clk (sd_clk_o),
.dat_o (data_out_tx_fifo ),
.rd ( rd ),
.empty (tx_e)
.empty (tx_e),
.fe (tx_f)
);
 
SD_FIFO_RX_FILLER FIFO_filer_rx (
394,8 → 405,12
assign m_wb_we_o = start_w ? m_wb_we_o_tx :start_r ?m_wb_we_o_rx: 0;
assign m_wb_adr_o = start_w ? m_wb_adr_o_tx :start_r ?m_wb_adr_o_rx: 0;
 
`ifdef IRQ_ENABLE
assign int_a =normal_int_status_reg & normal_int_signal_enable_reg;
assign int_b = error_int_status_reg & error_int_signal_enable_reg;
assign int_c = Bd_isr_reg & Bd_isr_enable_reg;
`endif
 
 
always @ (re_s_tx_bd_w or a_cmp_tx_bd_w or re_s_rx_bd_w or a_cmp_rx_bd_w or we_req_t) begin
re_s_tx_bd<=re_s_tx_bd_w;
a_cmp_tx_bd <=a_cmp_tx_bd_w;
410,16 → 425,16
 
wire status_reg_busy;
reg cmd_int_busy;
 
always @( cmd_resp_1_w or error_int_status_reg_w or normal_int_status_reg_w ) begin
 
 
cmd_resp_1<= cmd_resp_1_w;
 
normal_int_status_reg<= normal_int_status_reg_w ;
error_int_status_reg<= error_int_status_reg_w ;
normal_int_status_reg<= normal_int_status_reg_w ;
error_int_status_reg<= error_int_status_reg_w ;
end
 
 
 
always @ ( cidat_w or cmd_int_busy or status_reg_w or status_reg_busy or bd_int_st_w) begin
status_reg[0]<= status_reg_busy;
status_reg[15:1]<= status_reg_w[15:1];
451,8 → 466,8
cmd_setting_reg <= 0;
software_reset_reg <= 0;
time_out_reg <= 0;
normal_int_status_enable_reg <= 0;
error_int_status_enable_reg <= 0;
normal_int_signal_enable_reg <= 0;
error_int_signal_enable_reg <= 0;
//normal_int_signal_enable_reg <= 0;
//error_int_signal_enable_reg <= 0;
467,9 → 482,13
dat_in_m_tx_bd<=0;
dat_in_m_rx_bd<=0;
Bd_isr_enable_reg<=0;
normal_isr_reset<=0;
error_isr_reset<=0;
end
else if ((wb_stb_i & wb_cyc_i) || wb_ack_o )begin //CS
Bd_isr_reset<=0;
normal_isr_reset<= 0;
error_isr_reset<= 0;
if (wb_we_i) begin
case (wb_adr_i)
`argument: begin
482,10 → 501,10
end
`software : software_reset_reg <= wb_dat_i;
`timeout : time_out_reg <= wb_dat_i;
`normal_iser : normal_int_status_enable_reg <= wb_dat_i;
`error_iser : error_int_status_enable_reg <= wb_dat_i;
// `normal_isiger : normal_int_signal_enable_reg <= wb_dat_i;
// `error_isiger : error_int_signal_enable_reg <= wb_dat_i;
`normal_iser : normal_int_signal_enable_reg <= wb_dat_i;
`error_iser : error_int_signal_enable_reg <= wb_dat_i;
`normal_isr : normal_isr_reset<= 1;
`error_isr: error_isr_reset<= 1;
`clock_d: clock_divider <= wb_dat_i;
`bd_isr: Bd_isr_reset<= 1;
`bd_iser : Bd_isr_enable_reg <= wb_dat_i ;
561,10 → 580,9
`timeout : wb_dat_o <= time_out_reg ;
`normal_isr : wb_dat_o <= normal_int_status_reg ;
`error_isr : wb_dat_o <= error_int_status_reg ;
`normal_iser : wb_dat_o <= normal_int_status_enable_reg ;
`error_iser : wb_dat_o <= error_int_status_enable_reg ;
//`normal_isiger : wb_dat_o <= normal_int_signal_enable_reg ;
// `error_isiger : wb_dat_o <= error_int_signal_enable_reg ;
`normal_iser : wb_dat_o <= normal_int_signal_enable_reg ;
`error_iser : wb_dat_o <= error_int_signal_enable_reg ;
`capa : wb_dat_o <= capabilies_reg ;
`bd_status : wb_dat_o <= Bd_Status_reg;
`bd_isr : wb_dat_o <= Bd_isr_reg ;
/verilog/SD_data_host.v
11,7 → 11,7
input sd_clk,
input rst,
//Tx Fifo
input [`SD_BUS_W-1:0] data_in ,
input [31:0] data_in ,
 
output reg rd,
//Rx Fifo
148,7 → 148,10
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
if (rst) begin
170,6 → 173,9
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)
185,7 → 191,9
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;
192,22 → 200,78
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
rd<=1;
crc_rst<=0;
crc_en<=1;
last_din <=data_in;
last_din <=write_buf_0[3:0];
DAT_oe_o<=1;
DAT_dat_o<=0;
crc_in<= data_in;
crc_in<= write_buf_0[3:0];
data_send_index<=1;
end
else if ( (transf_cnt>=2) && (transf_cnt<=`BIT_BLOCK-`CRC_OFF )) begin
rd<=1;
DAT_oe_o<=1;
DAT_oe_o<=1;
case (data_send_index)
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
endcase
data_send_index<=data_send_index+1;
DAT_dat_o<= last_din;
last_din <=data_in;
crc_in<= data_in;
if ( transf_cnt >=`BIT_BLOCK-`CRC_OFF ) begin
crc_en<=0;
/verilog/SD_controller_top_tb.v
80,7 → 80,7
.sd_dat_dat_i (data_bluff_in), //sd_dat_pad_io),
.sd_dat_out_o ( sd_dat_out ) ,
.sd_dat_oe_o ( sd_dat_oe ),
.sd_clk_o (sd_clk_pad_o)
.sd_clk_o_pad (sd_clk_pad_o)
);
 
reg [31:0] sd_mem [0:256];
88,8 → 88,8
reg [31:0]in_mem [0:512];
 
// Fill the memory with values taken from a data file
initial $readmemh("data2.txt",sd_mem);
initial $readmemh("data_dat.txt",dat_mem);
initial $readmemh("\\LAPTOP\exjobb\Implement\sd_f_soc\rtl\verilog\sd_flash\data2.txt",sd_mem);
initial $readmemh("\\LAPTOP\exjobb\Implement\sd_f_soc\rtl\verilog\sd_flash\data2.txtdata_dat.txt",dat_mem);
// Display the contents of memory
integer k;
initial begin
149,23 → 149,24
sd_cmd_dat_i = 0 ;
reg_out[0] <= 32'h777F; //Timeout
reg_out[1] <= 32'b0000_0000_0000_0000_0000_0000_0000_0001; //Clock div
//reg_out[2] <= 32'h211; //cmd_setting_reg
//reg_ou1t3] <= 32'b0000_0000_0000_0000_0000_0000_0000_0001; //argument_reg
reg_out[2] <= 32'h0; //cmd_setting_reg
reg_out[3] <= 32'b0000_0000_0000_0000_0000_0000_0000_0000; //argument_reg
 
reg_out[2] <= 32'h0; //System
reg_out[3] <= 32'h0; //card
reg_out[4] <= 128;
reg_out[5] <= 135248;
reg_out[4] <= 32'h31A; //cmd_setting_reg; //System
reg_out[5] <= 32'hf0f0f0f0; //card
 
 
adr_out[0] <= 32'b0000_0000_0000_0000_0000_0000_0010_1100;
adr_out[1] <= 32'b0000_0000_0000_0000_0000_0000_0100_1100;
//adr_out[2] <= 32'b0000_0000_0000_0000_0000_0000_0000_0100;
//adr_out[3] <= 32'b0000_0000_0000_0000_0000_0000_0000_0000;
adr_out[2] <= 32'b0000_0000_0000_0000_0000_0000_0000_0100;
adr_out[3] <= 32'b0000_0000_0000_0000_0000_0000_0000_0000;
adr_out[4] <= 32'b0000_0000_0000_0000_0000_0000_0000_0100;
adr_out[5] <= 32'b0000_0000_0000_0000_0000_0000_0000_0000;
 
adr_out[2] <= 32'h60;
adr_out[3] <= 32'h60;
adr_out[4] <= 32'h80;
adr_out[5] <= 32'h80;
//adr_out[2] <= 32'h60;
//adr_out[3] <= 32'h60;
//adr_out[4] <= 32'h80;
//adr_out[5] <= 32'h80;
 
 
//adr_out[2] <= 32'h80;
185,11 → 186,11
wb_rst =1 ;
@ (posedge wb_clk_i);
wb_rst = 0;
wbs_sds_dat_i <= reg_out[out_cnt][31:0];
wbs_sds_dat_i <= reg_out[0][31:0];
wbs_sds_we_i <=1;
wbs_sds_stb_i <=1;
wbs_sds_cyc_i <=1;
wbs_sds_adr_i <= adr_out[out_cnt];
wbs_sds_adr_i <= adr_out[0];
out_cnt = out_cnt +1;
-> reset_done_trigger;
end
200,24 → 201,70
end
always @ (posedge wb_clk_i) begin
if (out_cnt <=6) begin
if (wbs_sds_ack_o == 1) begin
wbs_sds_dat_i <= reg_out[out_cnt][31:0];
 
out_cnt = out_cnt +1;
// if (out_cnt==76)
// out_cnt=2;
if (out_cnt ==6) begin
wbs_sds_dat_i <= reg_out[1][31:0];
wbs_sds_we_i <= 1;
wbs_sds_stb_i <= 1;
wbs_sds_cyc_i <= 1;
wbs_sds_adr_i <=adr_out[out_cnt];
out_cnt = out_cnt +1;
wbs_sds_adr_i <=adr_out[1];
end
else if (out_cnt ==9) begin
if (wbs_sds_ack_o != 1) begin
wbs_sds_dat_i <= reg_out[2][31:0];
wbs_sds_we_i <= 1;
wbs_sds_stb_i <= 1;
wbs_sds_cyc_i <= 1;
wbs_sds_adr_i <=adr_out[2];
end
end
else if (out_cnt ==12) begin
if (wbs_sds_ack_o != 1) begin
wbs_sds_dat_i <= reg_out[3][31:0];
wbs_sds_we_i <= 1;
wbs_sds_stb_i <= 1;
wbs_sds_cyc_i <= 1;
wbs_sds_adr_i <=adr_out[3];
end
end
else if (out_cnt ==281) begin
if (wbs_sds_ack_o != 1) begin
wbs_sds_dat_i <= reg_out[4][31:0];
wbs_sds_we_i <= 1;
wbs_sds_stb_i <= 1;
wbs_sds_cyc_i <= 1;
wbs_sds_adr_i <=adr_out[4];
end
end
 
else if (out_cnt ==286) begin
if (wbs_sds_ack_o != 1) begin
wbs_sds_dat_i <= reg_out[5][31:0];
wbs_sds_we_i <= 1;
wbs_sds_stb_i <= 1;
wbs_sds_cyc_i <= 1;
wbs_sds_adr_i <=adr_out[5];
end
end
else begin
wbs_sds_we_i <=0;
wbs_sds_stb_i <=0;
wbs_sds_cyc_i <=0;
out_cnt = out_cnt +1;
//out_cnt = out_cnt +1;
end
// if (out_cnt==76)
// out_cnt=2;
if (out_cnt==100) begin
data_bluff_in<=4'b1011;
/verilog/SD_FIFO_TX_Filler.v
1,187 → 1,122
`include "SD_defines.v"
module SD_FIFO_TX_FILLER
(
input clk,
input rst,
//WB Signals
output [31:0] m_wb_adr_o,
 
output reg m_wb_we_o,
input [31:0] m_wb_dat_i,
 
output reg m_wb_cyc_o,
output reg m_wb_stb_o,
input m_wb_ack_i,
//output [2:0] m_wb_cti_o,
//output [1:0] m_wb_bte_o,
 
//Data Master Control signals
input en,
input [31:0] adr,
 
 
//Data Serial signals
input sd_clk,
output [`SD_BUS_W-1:0] dat_o,
input rd,
output empty
//
 
);
reg reset_tx_fifo;
 
reg [3:0] din;
reg wr_tx;
reg [8:0] we;
reg [8:0] offset;
wire [5:0]mem_empt;
sd_tx_fifo Tx_Fifo (
.d ( din ),
.wr ( wr_tx ),
.wclk (clk),
.q ( dat_o),
.rd (rd),
.full (fe),
.empty (empty),
.mem_empt (mem_empt),
.rclk (sd_clk),
.rst (rst | reset_tx_fifo)
);
 
reg [3:0] t_c_buffer_0;
reg [3:0] t_c_buffer_1;
assign m_wb_adr_o = adr+offset;
 
reg write_ptr;
reg read_ptr;
reg first;
reg [31:0] tmp_dat_buffer_0;
reg [31:0] tmp_dat_buffer_1;
 
 
always @(posedge clk or posedge rst )begin
if (rst) begin
offset <=0;
we <= 8'h1;
m_wb_we_o <=0;
m_wb_cyc_o <= 0;
m_wb_stb_o <= 0;
wr_tx<=0;
tmp_dat_buffer_0<=0;
tmp_dat_buffer_1<=0;
t_c_buffer_0<=0;
t_c_buffer_1<=0;
reset_tx_fifo<=1;
write_ptr<=0;
read_ptr<=0;
first<=1;
din<=0;
end
else if (en) begin //Start filling the TX buffer
reset_tx_fifo<=0;
if (m_wb_ack_i) begin
write_ptr<=write_ptr+1;
offset<=offset+`MEM_OFFSET;
if (!write_ptr) begin
tmp_dat_buffer_0 <= m_wb_dat_i;
t_c_buffer_0<=9;
end
else begin
tmp_dat_buffer_1 <= m_wb_dat_i;
t_c_buffer_1<=9;
end
m_wb_cyc_o <= 0;
m_wb_stb_o <= 0;
end
if ((t_c_buffer_0>0 ) && (read_ptr==0)) begin
if (!fe) begin
we <= {we[9-1:0],we[9-1]};
wr_tx <=1;
t_c_buffer_0<=t_c_buffer_0-1;
if (we[0])
din <= tmp_dat_buffer_0 [3:0];
else if (we[1])
din <= tmp_dat_buffer_0 [7:4];
else if (we[2])
din <= tmp_dat_buffer_0 [11:8] ;
else if (we[3])
din <= tmp_dat_buffer_0 [15:12];
else if (we[4])
din <= tmp_dat_buffer_0 [19:16] ;
else if (we[5])
din <= tmp_dat_buffer_0 [23:20] ;
else if (we[6])
din <= tmp_dat_buffer_0 [27:24];
else if (we[7])
din <= tmp_dat_buffer_0 [31:28] ;
else if (we[8]) begin
wr_tx <=0;
read_ptr<=read_ptr+1;
end
end
end
else if ((t_c_buffer_1>0 ) && (read_ptr==1)) begin
if (!fe) begin
we <= {we[9-1:0],we[9-1]};
wr_tx <=1;
t_c_buffer_1<=t_c_buffer_1-1;
if (we[0])
din <= tmp_dat_buffer_1 [3:0];
else if (we[1])
din <= tmp_dat_buffer_1 [7:4];
else if (we[2])
din <= tmp_dat_buffer_1 [11:8] ;
else if (we[3])
din <= tmp_dat_buffer_1 [15:12];
else if (we[4])
din <= tmp_dat_buffer_1 [19:16] ;
else if (we[5])
din <= tmp_dat_buffer_1 [23:20] ;
else if (we[6])
din <= tmp_dat_buffer_1 [27:24];
else if (we[7])
din <= tmp_dat_buffer_1 [31:28] ;
else if (we[8]) begin
wr_tx <=0;
read_ptr<=read_ptr+1;
end
end
end
else begin
wr_tx <=0;
we <=1;
end
if ((!m_wb_ack_i) & ( first || (write_ptr != read_ptr) ) ) begin //If not full And no Ack
m_wb_we_o <=0;
m_wb_cyc_o <= 1;
m_wb_stb_o <= 1;
first<=0;
end
 
end
else begin
offset <=0;
reset_tx_fifo<=1;
m_wb_cyc_o <= 0;
m_wb_stb_o <= 0;
m_wb_we_o <=0;
first<=1;
t_c_buffer_0<=0;
t_c_buffer_1<=0;
write_ptr<=0;
read_ptr<=0;
first<=1;
din<=0;
end
end
endmodule
 
`include "SD_defines.v"
module SD_FIFO_TX_FILLER
(
input clk,
input rst,
//WB Signals
output [31:0] m_wb_adr_o,
 
output reg m_wb_we_o,
input [31:0] m_wb_dat_i,
 
output reg m_wb_cyc_o,
output reg m_wb_stb_o,
input m_wb_ack_i,
//output [2:0] m_wb_cti_o,
//output [1:0] m_wb_bte_o,
 
//Data Master Control signals
input en,
input [31:0] adr,
 
 
//Data Serial signals
input sd_clk,
output [31:0] dat_o,
input rd,
output empty,
output fe
//
 
);
reg reset_tx_fifo;
 
reg [31:0] din;
reg wr_tx;
reg [8:0] we;
reg [8:0] offset;
wire [5:0]mem_empt;
sd_tx_fifo Tx_Fifo (
.d ( din ),
.wr ( wr_tx ),
.wclk (clk),
.q ( dat_o),
.rd (rd),
.full (fe),
.empty (empty),
.mem_empt (mem_empt),
.rclk (sd_clk),
.rst (rst | reset_tx_fifo)
);
 
reg [3:0] t_c_buffer_0;
reg [3:0] t_c_buffer_1;
assign m_wb_adr_o = adr+offset;
 
 
reg first;
 
reg ackd;
reg delay;
always @(posedge clk or posedge rst )begin
if (rst) begin
offset <=0;
we <= 8'h1;
m_wb_we_o <=0;
m_wb_cyc_o <= 0;
m_wb_stb_o <= 0;
wr_tx<=0;
ackd <=1;
delay<=0;
reset_tx_fifo<=1;
first<=1;
din<=0;
end
else if (en) begin //Start filling the TX buffer
reset_tx_fifo<=0;
if (m_wb_ack_i) begin
wr_tx <=1;
din <=m_wb_dat_i;
m_wb_cyc_o <= 0;
m_wb_stb_o <= 0;
delay<=~ delay;
end
 
else begin
wr_tx <=0;
end
if (delay)begin
offset<=offset+`MEM_OFFSET;
ackd<=ackd+1;
delay<=~ delay;
wr_tx <=0;
end
if ( !m_wb_ack_i & !fe & ackd ) begin //If not full And no Ack
m_wb_we_o <=0;
m_wb_cyc_o <= 1;
m_wb_stb_o <= 1;
ackd<=0;
end
end
else begin
offset <=0;
reset_tx_fifo<=1;
m_wb_cyc_o <= 0;
m_wb_stb_o <= 0;
m_wb_we_o <=0;
end
end
endmodule
 
 
/verilog/SD_defines.v
6,6 → 6,7
//`define SIM
`define SYN
 
//`define IRQ_ENABLE
`define ACTEL
 
//`define CUSTOM
57,16 → 58,15
`define BIT_BLOCK 1044
`define CRC_OFF 19
`define BIT_BLOCK_REC 1024
 
`define BIT_CRC_CYCLE 16
 
 
//FIFO defines---------------
`define FIFO_RX_MEM_DEPTH 4
`define FIFO_RX_MEM_ADR_SIZE 3
`define FIFO_RX_MEM_DEPTH 16
`define FIFO_RX_MEM_ADR_SIZE 5
 
`define FIFO_TX_MEM_DEPTH 64
`define FIFO_TX_MEM_ADR_SIZE 7
`define FIFO_TX_MEM_DEPTH 16
`define FIFO_TX_MEM_ADR_SIZE 5
//---------------------------
 
 
75,3 → 75,4
 
 
 
 
/verilog/SD_cmd_serial_host.v
335,7 → 335,7
CRC_Enable=0;
CMD_OUT=0;
st_dat_t<=0;
word_select_counter<=0;
end
WRITE_WR: begin
/verilog/SD_clock_divider.v
1,4 → 1,4
`include "SD_defines.v"
`include "SD_defines.v"//NONONW
module CLOCK_DIVIDER (
input wire CLK,
input [7:0] DIVIDER,
15,9 → 15,9
);
`endif
//`ifdef SIM
// assign SD_CLK = SD_CLK_O;
//endif
`ifdef SIM
assign SD_CLK = SD_CLK_O;
`endif
always @ (posedge CLK or posedge RST)
begin
/verilog/SD_data_master.v
1,453 → 1,487
`include "SD_defines.v"
 
module SD_DATA_MASTER (
input clk,
input rst,
//Tx Bd
input new_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 new_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 rx_full,
//SD-DATA_Host
input busy_n ,
input transm_complete ,
input crc_ok,
output reg ack_transfer,
//status output
output reg [7:0] bd_int_st ,
input bd_int_st_rst,
output reg CIDAT
);
`define BD_EMPTY (`BD_SIZE /4)
`ifdef RAM_MEM_WIDTH_32
`define READ_CYCLE 2
reg bd_cnt ;
`else `ifdef RAM_MEM_WIDTH_16
`define READ_CYCLE 4
reg [1: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;
 
 
always @ (state 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))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;
bd_int_st<=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;
`ifdef RAM_MEM_WIDTH_16
if (ack_i_s_tx) begin
if( bd_cnt == 2'b00) begin
sys_adr [15:0] <= dat_in_tx; end
else if ( bd_cnt == 2'b01) begin
sys_adr [31:16] <= dat_in_tx; end
else if ( bd_cnt == 2) begin
cmd_arg [15:0] <= dat_in_tx;
re_s_tx <= 0; end
else if ( bd_cnt == 3) begin
cmd_arg [31:16] <= dat_in_tx;
re_s_tx <= 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 <= CMD24;
tx_cycle <=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 (tx_cycle)
start_tx_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;
bd_int_st[4] <=1;
end
`endif
`ifdef SIM
rec_done<=1;
`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
end
else
rec_failed<=1; //CRC-Error, CIC-Error or timeout
end
end
DATA_TRANSFER: begin
CIDAT<=1;
if (tx_cycle) begin
if (tx_empt) begin
bd_int_st[2] <=1;
trans_failed<=1;
end
end
else begin
if (rx_full) begin
bd_int_st[2] <=1;
trans_failed<=1;
end
end
//Check for fifo underflow,
//2 DO: if deteced stop transfer, reset data host
if (transm_complete) begin //Transfer complete
ack_transfer<=1;
if ((!crc_ok) && (busy_n)) begin //Wrong CRC and Data line free.
bd_int_st[5] <=1;
trans_failed<=1;
end
else if ((crc_ok) && (busy_n)) begin //Data Line free
trans_done <=1;
bd_int_st[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)
bd_int_st[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 (bd_int_st_rst)
bd_int_st<=0;
end
end
endmodule
`include "SD_defines.v"
 
module SD_DATA_MASTER (
input clk,
input rst,
//Tx Bd
input new_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 new_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] bd_int_st ,
input bd_int_st_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;
 
 
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;
bd_int_st<=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;
bd_int_st[4] <=1;
start_tx_fifo<=0;
end
`endif
`ifdef SIM
rec_done<=1;
start_tx_fifo<=1;
`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
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
bd_int_st[2] <=1;
trans_failed<=1;
end
end
else begin
if (rx_full) begin
bd_int_st[2] <=1;
trans_failed<=1;
end
end
//Check for fifo underflow,
//2 DO: if deteced stop transfer, reset data host
if (transm_complete) begin //Transfer complete
ack_transfer<=1;
if ((!crc_ok) && (busy_n)) begin //Wrong CRC and Data line free.
bd_int_st[5] <=1;
trans_failed<=1;
end
else if ((crc_ok) && (busy_n)) begin //Data Line free
trans_done <=1;
bd_int_st[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)
bd_int_st[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 (bd_int_st_rst)
bd_int_st<=0;
end
end
endmodule

powered by: WebSVN 2.1.0

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