📄 sd_control.v
字号:
/***********************************************
函数名:sd_control
功 能:实现sd卡文件读取的控制
参 数:
**********************************************/
module sd_control( enable,
sd_data,
sd_cmd_in,
sd_cmd_out,
clk,
ram1_wen,
ram1_ren,
wraddress,
ram2_wen,
ram2_ren,
flag,
crc_en,
dcrc,
cmddata,
crcfini,
fifo_ef,
block_num
);
parameter ram_wide=7;
parameter sd_data_wide=4;
parameter sd_ad_wide=32;
parameter cmd_1_en=1;
input enable,clk,sd_cmd_in,crcfini,fifo_ef;
input [sd_data_wide-1:0]sd_data;
input [46:0]cmddata;
output [31:0]block_num;
output sd_cmd_out,ram1_wen,ram1_ren,ram2_wen,ram2_ren,flag,crc_en;
output [ram_wide-1:0]wraddress;
output [39:0]dcrc;
reg [ram_wide-1:0]ram_address;
reg [5:0]n;
reg sd_cmd_out,flag1,ram1_wen,ram1_ren,ram2_wen,ram2_ren,datain_en,timer_f;
reg crc_en;
reg [39:0]dcrc;
reg [47:0]cmd;
reg [2:0]nn;
reg [4:0]timer_clk;
reg temp_fifo_ef,temp_crcfini;
reg temp_enable,crce;
reg [5:0]num_crc;
integer block_ad;
reg [31:0]block_num;
reg mm;
assign wraddress=ram_address;
//控制ram1,ram2的读写,去除每一块后的校验位
always @(negedge clk)
begin
if(!enable)
begin
ram_address<=7'b0;
ram1_wen<=1'b0;
ram1_ren<=1'b0;
ram2_wen<=1'b0;
ram2_ren<=1'b0;
datain_en<=1'b0;
nn<=3'b001;
timer_clk<=5'b0;
timer_f<=1'b0;
block_num<=32'h0;
end
else
begin
if(!timer_f)
begin
if(!datain_en)
begin
if(sd_data==4'b0000 && flag1==0)
begin
ram1_wen<=1'b1; //开始的时候先写人ram1
datain_en<=1'b1; //数据开始位检测标志信号
ram_address<=7'b0;
end
end
else
begin
if(ram_address==127)
begin
if(ram1_wen==1)
begin
ram_address<=7'b0;
ram1_wen<=1'b0;
ram1_ren<=1'b1;
ram2_wen<=1'b1;
ram2_ren<=1'b0;
end
else if(ram2_wen==1)
begin
ram_address<=7'b0;
ram2_wen<=1'b0;
ram2_ren<=1'b1;
ram1_ren<=1'b0;
if(nn==4)
begin
nn<=3'b001;
timer_f<=1'b1;
ram1_wen<=1'b0;
datain_en<=1'b0;
if(block_num==492)
begin
datain_en<=1'b0;
block_num<=32'h0;
end
else
block_num<=block_num+32'h00000001;
end
else
begin
ram1_wen<=1'b1;
nn<=nn+3'b001;
end
end
end
else
begin
ram_address<=ram_address+7'b0000001;
end
end
end
else //跳过校验位
begin
if(timer_clk<15)
timer_clk<=timer_clk+5'b00001;
else
begin
timer_clk<=5'b0;
timer_f<=1'b0;
end
end
end
end
//控制地址参数
always @(posedge clk)
begin
if(!enable)
begin
crc_en<=1'b0;
temp_fifo_ef<=1'b0;
dcrc<=40'h520001f200; //初始块地址
end
else
begin
if(crcfini==1'b1)
crc_en<=1'b0;
else if(temp_fifo_ef==1'b0 && fifo_ef==1'b1)
begin
crc_en<=1'b1;
dcrc[31:0]<=dcrc[31:0]+32'h0003da00; //每次读取29*17个块
dcrc[39:32]<=8'h52;
end
temp_fifo_ef<=fifo_ef;
end
end
//产生连续读取数据命令cmd18
always @(posedge clk)
begin
if(crce==1'b1 && num_crc<49)
num_crc<=num_crc+6'b000001;
else
begin
num_crc<=6'b000000;
crce<=1'b0;
end
if(!enable)
begin
mm<=1'b0;
crce<=1'b0;
temp_enable<=enable;
num_crc<=6'b000000;
end
else if(temp_enable==1'b0 && enable==1'b1)
begin
cmd<=48'h520001f20079;
crce<=1'b1;
temp_enable<=enable;
end
else if(ram_address==127 && nn==4 && block_num==492)
begin
if(!mm)
mm<=1'b1;
else
begin
cmd<=48'h4c0000000061;
crce<=1'b1;
mm<=1'b0;
end
end
else
begin
cmd[47:1]<=cmddata;
cmd[0]<=1'b1;
end
end
//cmd18命令产生后,控制命令的发送
always @(negedge clk)
begin
if(!enable)
begin
n<=6'b0;
flag1<=1'b0;
block_ad<=0;
temp_crcfini<=crcfini;
end
else
begin
if(temp_crcfini==1'b1 && crcfini==1'b0)
begin
if(n<49)
begin
flag1<=1'b1;
n<=n+6'b000001;
end
else
begin
n<=6'b0;
flag1<=1'b0;
temp_crcfini<=crcfini;
end
end
else
temp_crcfini<=crcfini;
end
end
assign flag=flag1 || crce;
shift_reg cmd18(clk,cmd,sd_cmd_out,flag,cmd_1_en,cmd_1_en);
endmodule
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -