module LDM_SDCARD
(
//Avalon Clock
input csi_clk,
input csi_rst_n,
//Avalon-MM
input avs_chipselect,
input [1:0] avs_address, //multiple of 4
// input [1:0] avs_byteenable_n, //1,2,4,8,16,54,128
input avs_write,
input [31:0] avs_writedata, //32bit cpu
input avs_read,
output reg [31:0] avs_readdata, //32bit cpu
//Avalon Conduit
output reg coe_sd_cs,
output reg coe_sd_clk,
input coe_sd_miso,
output reg coe_sd_mosi
);
//------------------------------------------------------
always @(posedge csi_clk or negedge csi_rst_n)
begin
if(!csi_rst_n)
begin
coe_sd_cs = 1;
end
else if (avs_chipselect && avs_write && (avs_address == 2'b00))
begin
coe_sd_cs = avs_writedata[0];
end
end
//------------------------------------------------------
reg[7:0] avs_writedata_r;
reg[7:0] avs_writestatus_r;
reg writedate_flag;
always @(posedge csi_clk or negedge csi_rst_n)
begin
if(!csi_rst_n)
begin avs_writedata_r = 7'd0;writedate_flag=1'b0;end
else if (avs_chipselect && avs_write && (avs_address == 2'b01) && (write_flg ==1'b0)) //for steady state
begin avs_writedata_r = avs_writedata[7:0];
writedate_flag=1'b1;
end
else if( avs_writestatus_r==8'h40)
writedate_flag=1'b0;
end
//------------------------------------------------------
//read
reg[7:0] avs_readstatus_r;
reg[7:0] avs_readdata_r;
reg readdate_flag;
reg readfinish;
always @(posedge csi_clk or negedge csi_rst_n)
begin
if(!csi_rst_n)
avs_readdata = 0;
else if (avs_chipselect && avs_read ) //for steady state
case(avs_address)
2'b10:begin
avs_readdata=avs_readstatus_r ;
if(avs_readstatus_r==8'h00)begin readfinish=1'b0;readdate_flag=1'b1;end
else if(avs_readstatus_r==8'h80)readdate_flag=1'b0;
end
2'b11:begin avs_readdata=avs_readdata_r; readfinish=1'b1;end
default:avs_readdata=32'h0000;
endcase
else if(avs_readstatus_r==8'h80)readdate_flag=1'b0;
end
//------------------------------------------------------
reg [4:0]cstate,nstate;
/*always @(posedge csi_clk or negedge csi_rst_n)
begin
if(!csi_rst_n)cstate=5'd0;
else cstate= nstate;
end*/
always@(nstate)
begin
cstate=nstate;
end
//wire[4:0]cstate;
//assign cstate=nstate;
//------------------------------------------------------
reg write_flg;
//reg[2:0]count;
always @(posedge csi_clk or negedge csi_rst_n)
begin
if(!csi_rst_n)
begin
write_flg =1'b0;//enable write to sd card flag
coe_sd_clk=1'b1;
coe_sd_mosi=1'b0;
nstate = 5'd0;
//count = 3'd0;
avs_readstatus_r =8'h00;
avs_writestatus_r=8'h00;
end
else if(writedate_flag )
case(cstate)
5'd0: begin coe_sd_clk=1'b0;coe_sd_mosi=avs_writedata_r[7]; nstate = 5'd1; write_flg =1'b1;avs_writestatus_r=8'h00;end
5'd1: begin coe_sd_clk=1'b1; nstate = 5'd2; end
5'd2: begin coe_sd_clk=1'b0;coe_sd_mosi=avs_writedata_r[6]; nstate = 5'd3; end
5'd3: begin coe_sd_clk=1'b1; nstate = 5'd4; end
5'd4: begin coe_sd_clk=1'b0;coe_sd_mosi=avs_writedata_r[5]; nstate = 5'd5; end
5'd5: begin coe_sd_clk=1'b1; nstate = 5'd6; end
5'd6: begin coe_sd_clk=1'b0;coe_sd_mosi=avs_writedata_r[4]; nstate = 5'd7; end
5'd7: begin coe_sd_clk=1'b1; nstate = 5'd8; end
5'd8: begin coe_sd_clk=1'b0;coe_sd_mosi=avs_writedata_r[3]; nstate = 5'd9; end
5'd9: begin coe_sd_clk=1'b1; nstate = 5'd10; end
5'd10: begin coe_sd_clk=1'b0;coe_sd_mosi=avs_writedata_r[2]; nstate = 5'd11; end
5'd11: begin coe_sd_clk=1'b1; nstate= 5'd12; end
5'd12: begin coe_sd_clk=1'b0;coe_sd_mosi=avs_writedata_r[1]; nstate = 5'd13; end
5'd13: begin coe_sd_clk=1'b1; nstate = 5'd14; end
5'd14: begin coe_sd_clk=1'b0;coe_sd_mosi=avs_writedata_r[0]; nstate = 5'd15; end
5'd15: begin coe_sd_clk=1'b1; nstate = 5'd16; write_flg =1'b0;end
5'd16: begin nstate = 5'd16; avs_writestatus_r=8'h40;end
default: nstate = 5'd0;
endcase
else if(readdate_flag)
case(cstate)
5'd0: begin coe_sd_clk=1'b0; nstate = 5'd1; avs_readstatus_r =8'h00;end
5'd1: begin coe_sd_clk=1'b1; avs_readdata_r[7]=coe_sd_miso; nstate = 5'd2; end
5'd2: begin coe_sd_clk=1'b0; nstate = 5'd3; end
5'd3: begin coe_sd_clk=1'b1; avs_readdata_r[6]=coe_sd_miso; nstate = 5'd4; end
5'd4: begin coe_sd_clk=1'b0; nstate = 5'd5; end
5'd5: begin coe_sd_clk=1'b1; avs_readdata_r[5]=coe_sd_miso; nstate = 5'd6; end
5'd6: begin coe_sd_clk=1'b0; nstate = 5'd7; end
5'd7: begin coe_sd_clk=1'b1; avs_readdata_r[4]=coe_sd_miso; nstate = 5'd8; end
5'd8: begin coe_sd_clk=1'b0; nstate = 5'd9; end
5'd9: begin coe_sd_clk=1'b1; avs_readdata_r[3]=coe_sd_miso; nstate = 5'd10; end
5'd10: begin coe_sd_clk=1'b0; nstate = 5'd11; end
5'd11: begin coe_sd_clk=1'b1; avs_readdata_r[2]=coe_sd_miso; nstate= 5'd12; end
5'd12: begin coe_sd_clk=1'b0; nstate = 5'd13; end
5'd13: begin coe_sd_clk=1'b1; avs_readdata_r[1]=coe_sd_miso; nstate = 5'd14; end
5'd14: begin coe_sd_clk=1'b0; nstate = 5'd15; end
5'd15: begin coe_sd_clk=1'b1; avs_readdata_r[0]=coe_sd_miso; nstate = 5'd16; end
5'd16: begin nstate = 5'd16; avs_readstatus_r =8'h80;end
default: nstate = 5'd0;
endcase
else
begin
write_flg =1'b0;
coe_sd_clk=1'b1;
coe_sd_mosi=1'b0;
nstate = 5'd0;
avs_writestatus_r=8'h00;
if(readfinish==1'b1)avs_readstatus_r =8'h00;
//if(avs_readstatus_r==8'h80)count=count+1'b1; //read finish delay N clk
//if(count == 3'd5)begin count=3'd0; avs_readstatus_r =8'h00;end
end
end
//------------------------------------------------------
endmodule