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

📄 recvresp.vhd

📁 SD卡读卡器模块的VHDL及软件驱动代码
💻 VHD
字号:
library IEEE;
use IEEE.std_logic_1164.all;
use WORK.pck_CRC7.all;

entity recvresp is
	port
	(
		clk:		in std_logic;	-- sd clk
		areset:		in std_logic;	-- async reset
		recv:		in std_logic;	-- recv response
		longresp:	in std_logic;	-- long response(136) /short(48)
		cmd:		in std_logic;	-- cmd port
		buzy:		out std_logic;	-- buzy receiving
		cmdno:		out std_logic_vector( 5 downto 0 ); -- response cmd number
		content:	out std_logic_vector( 126 downto 0 ); -- response content
---------- for debug ----------------
--		ocnt:		out integer range 0 to 126;
--		ocrc:		out std_logic_vector( 6 downto 0 );
-------------------------------------
		crcerr:		out std_logic	-- response crc error
	);
end recvresp;

architecture RTL of recvresp is
	
	type RR_STAT is
	(
		RR_IDLE,	-- idle, wait for recv signal
		RR_PRERECV,		-- wait for card responsing
		RR_PRERECVCMDNO,	-- pre-recv cmd number, only load counter
		RR_RECVCMDNO,		-- recv cmd number
		RR_PRERECVCONTENT,	-- pre-recv content(load counter and recv first bit)
		RR_RECVCONTENT,		-- recv content
		RR_PRECHECKCRC,		-- pre-check crc7(load counter and check first bit)
		RR_CHECKCRC,		-- check crc7
		RR_WAITFINISH,	-- wait for receiving response finished
		RR_SUCCESS,		-- received a correct response
		RR_WAITRECVEND -- wait for "recv" become low
	);
	
	signal stat:		RR_STAT;
	signal stat_next:	RR_STAT;
	signal cnt_q:		integer range 0 to 126;
	signal cnt_d:		integer range 0 to 126;
	signal contlen:		integer range 0 to 126; -- latch
	signal longresp_r:	std_logic;	-- latch
	signal cmdno_r:		std_logic_vector( 5 downto 0 ); -- latch
	signal content_r:	std_logic_vector( 126 downto 0 ); -- latch
	signal crcerr_r:	std_logic;	-- latch
	signal crc:			std_logic_vector( 6 downto 0 );
	signal crc_next:	std_logic_vector( 6 downto 0 );
	
begin
	
	Reg: process( clk, longresp )
	begin
		if( rising_edge( clk ) ) then
			longresp_r <= longresp;
		end if;
	end process Reg;
	
	Stat_P: process( clk, areset, stat_next )
	begin
		if( areset = '1' ) then
			stat <= RR_IDLE;
		elsif( rising_edge( clk ) ) then
			stat <= stat_next;
		end if;
	end process Stat_P;
	
	Stat_next_P: process( stat, recv, cmd, crc, cnt_q, longresp_r )
	begin
		case stat is
			
			when RR_IDLE =>
				if( recv = '1' ) then
					stat_next <= RR_PRERECV;
				else
					stat_next <= RR_IDLE;
				end if;
			
			when RR_PRERECV =>
				if( cmd = '0' ) then
					stat_next <= RR_PRERECVCMDNO;
				else
					stat_next <= RR_PRERECV;
				end if;
			
			when RR_PRERECVCMDNO =>
				stat_next <= RR_RECVCMDNO;
			
			when RR_RECVCMDNO =>
				if( cnt_q = 0 ) then
					stat_next <= RR_PRERECVCONTENT;
				else
					stat_next <= RR_RECVCMDNO;
				end if;
			
			when RR_PRERECVCONTENT =>
				stat_next <= RR_RECVCONTENT;
			
			when RR_RECVCONTENT =>
				if( cnt_q = 0 ) then
					if( longresp_r = '1' ) then
						stat_next <= RR_SUCCESS;
					else
						stat_next <= RR_PRECHECKCRC;
					end if;
				else
					stat_next <= RR_RECVCONTENT;
				end if;
			
			when RR_PRECHECKCRC =>
				if( crc(6) = cmd ) then
					stat_next <= RR_CHECKCRC;
				else
					stat_next <= RR_WAITFINISH;
				end if;
			
			when RR_CHECKCRC =>
				if( crc(cnt_q) = cmd ) then
					if( cnt_q = 0 ) then
						stat_next <= RR_SUCCESS;
					else
						stat_next <= RR_CHECKCRC;
					end if;
				else
					stat_next <= RR_WAITFINISH;
				end if;
			
			when RR_SUCCESS =>
				if( recv = '1' ) then
					stat_next <= RR_WAITRECVEND;
				else
					stat_next <= RR_IDLE;
				end if;
			
			when RR_WAITFINISH =>
				if( cnt_q = 0 ) then
					if( recv = '1' ) then
						stat_next <= RR_WAITRECVEND;
					else
						stat_next <= RR_IDLE;
					end if;
				else
					stat_next <= RR_WAITFINISH;
				end if;
			
			when RR_WAITRECVEND =>
				if( recv = '1' ) then
					stat_next <= RR_WAITRECVEND;
				else
					stat_next <= RR_IDLE;
				end if;
			
			when others =>
				stat_next <= RR_IDLE;
			
		end case;
	end process Stat_next_P;
	
	Contlen_P: process( clk, recv )
	begin
		if( rising_edge( clk ) ) then
			if( recv = '1' ) then
				if( longresp = '1' ) then
					contlen <= 127 - 1;
				else
					contlen <= 32 - 1;
				end if;
			else
				contlen <= contlen;
			end if;
		end if;
	end process Contlen_P;
	
	Cnt_q_P: process( clk, stat, contlen, cnt_d )
	begin
		if( rising_edge( clk ) ) then
			case stat is
				
				when RR_PRERECVCMDNO =>
					cnt_q <= 5;
				
				when RR_PRERECVCONTENT =>
					cnt_q <= contlen - 1;
				
				when RR_PRECHECKCRC =>
					cnt_q <= 6 - 1;
				
				when others =>
					cnt_q <= cnt_d;
				
			end case;
		end if;
	end process Cnt_q_P;
	
	Cnt_d_P: process( cnt_q )
	begin
		if( cnt_q > 0 ) then
			cnt_d <= cnt_q - 1;
		else
			cnt_d <= 0;
		end if;
	end process Cnt_d_P;
	
	Crc_P: process( clk, crc, crc_next )
	begin
		if( rising_edge( clk ) ) then
			case stat is
				
				when RR_PRERECV =>
					crc <= ( others => '0' );
				
				when RR_PRERECVCMDNO =>
					crc <= crc_next;
				
				when RR_RECVCMDNO =>
					crc <= crc_next;
				
				when RR_PRERECVCONTENT =>
					crc <= crc_next;
				
				when RR_RECVCONTENT =>
					crc <= crc_next;
				
				when others =>
					crc <= crc;
				
			end case;
		end if;
	end process Crc_P;
	
	Crc_next_P: process( crc, cmd )
	begin
		crc_next <= nextCRC7( cmd, crc );
	end process Crc_next_P;
	
	Buzy_P: process( stat )
	begin
		case stat is
			
			when RR_IDLE =>
				buzy <= '0';
			
			when RR_WAITRECVEND =>
				buzy <= '0';
			
			when others =>
				buzy <= '1';
			
		end case;
	end process Buzy_P;
	
	Output: process( clk, stat, cmdno_r, content_r, crcerr_r, cnt_q, cmd, contlen )
	begin
		if( rising_edge( clk ) ) then
			
			cmdno_r <= cmdno_r;
			content_r <= content_r;
			crcerr_r <= crcerr_r;
			
			case stat is
				
				when RR_PRERECV =>
					crcerr_r <= '1';
				
				when RR_RECVCMDNO =>
					cmdno_r( cnt_q ) <= cmd;
				
				when RR_PRERECVCONTENT =>
					content_r( contlen ) <= cmd;
				
				when RR_RECVCONTENT =>
					content_r( cnt_q ) <= cmd;
				
				when RR_SUCCESS =>
					crcerr_r <= '0';
				
				when others =>
				
			end case;
		end if;
	end process Output;
	
	cmdno <= cmdno_r;
	content <= content_r;
	crcerr <= crcerr_r;
	
---------- for debug ----------------
--	ocnt <= cnt_q;
--	ocrc <= crc;
-------------------------------------
	
end RTL;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -