⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sd_control.v

📁 基于QUARTUSII软件 实现FPGA(ATERA CYCLONE II系列)与SD卡SD模式通信 所用语言位verilog HDL
💻 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 + -