?? 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 + -