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

📄 rec_buf.vhd

📁 USART coded in VHDL. It is writted in 5 files. I am uploading the files in order.
💻 VHD
字号:

					--		RECEIVE BLOCK

library ieee;
use ieee.std_logic_1164.all;  

entity rec_buf is
port(rxclk				: in		std_logic;
		ciport				: in		std_logic_vector(7 downto 0);
		miport				: in		std_logic_vector(7 downto 0);
		syn1port			: in		std_logic_vector(7 downto 0);
		syn2port			: in		std_logic_vector(7 downto 0);
		statusport		: in		std_logic_vector(7 downto 0);
		writeport			: out		std_logic_vector(7 downto 0);
		rxrdy					: out		std_logic;	
		rxd						: in		std_logic; 
		syndet 				: inout	std_logic;
		parity_error	: out		std_logic;
		framing_error	: out		std_logic;
		overrun_error : out		std_logic;
		syndet_status	: out		std_logic; 
		status_read		: in		std_logic;
		data_read			: in		std_logic;	
		rxrdy_status	: out		std_logic );
end rec_buf;								

architecture rec_buf_arc of rec_buf is	 

	type 	serial1 is ( start, dbits, parity, stop );
	type 	serial2 is ( syn1det, syn2det, dbits, parity );
	type	serial3 is ( stop, dbits, parity );

	signal 	currrxd1	: serial1;
	signal 	nextrxd1	: serial1;
	signal 	currrxd2	: serial2;
	signal 	nextrxd2	: serial2;
	signal 	currrxd3	: serial3;
	signal 	nextrxd3	: serial3;
	signal 	holdreg		: std_logic_vector(7 downto 0):="11111111";	  
	signal 	i					: integer:=0;
	signal 	j					: integer:=0;
	signal 	k					: integer:=0;
	signal 	len				: integer;	
	signal	width			: integer:=2;
	signal 	baud			: integer;
	signal 	count			: integer:= 1;
	signal 	par_err		: std_logic:='0';
	signal 	rxreg_full: std_logic:='0';
	signal 	syndet_in	: std_logic:='0';
	signal 	syndet_out: std_logic:='0';  
	signal 	brkdet		: std_logic:='0';	 
	signal 	brk				: integer:=0; 
	signal 	rxrdy_in	: std_logic:='0';

begin
	
	len <= 	5 when miport(3 downto 2) = "00" else
					6 when miport(3 downto 2) = "01" else
					7 when miport(3 downto 2) = "10" else
					8; 										 
			
	baud <= 1  when miport(1 downto 0) = "01" else
					16 when miport(1 downto 0) = "10" else
					64 when miport(1 downto 0) = "11" else
					1; 
	rxrdy <= rxrdy_in;
	rxrdy_status <= rxrdy_in;

	process( rxclk )
	begin
		currrxd1 <= nextrxd1; 
		currrxd2 <= nextrxd2; 
		currrxd3 <= nextrxd3; 
	end process; 
	
	process ( rxclk )
	begin	
		if rxclk = '0' and rxclk'event then	
			if miport(1 downto 0) = "01" then
				count <= baud/2;
			elsif miport(1) = '1' then
				if count = baud then
					count <= 1;
				else
					count <= count + 1;
				end if;
			end if;
		end if;
	end process;
	
	process ( rxclk, status_read )
	variable rxreg : std_logic_vector(7 downto 0):="11111111";
	begin		

	if status_read = '1' then
		syndet_out <= '0';
	end if;

	if rxclk = '1' and rxclk'event and ciport(2) = '1' then
		if miport(1 downto 0) /= "00" and brkdet = '0' then
			if count = baud/2 then
				case currrxd1 is
					when start =>		
						if rxd = '0' then
							nextrxd1 <= dbits;
							i <= 0;
						else
							nextrxd1 <= start;
						end if;
			
					when dbits => 
						rxreg(i) := rxd;
						if i <= len-2 then
							i <= i + 1;
							nextrxd1 <= dbits;
						elsif miport(4) = '1' then
							i <= 0;
							nextrxd1 <= parity;
						else	 			  
							i <= 0;
							nextrxd1 <= stop;
						end if;				 

					when parity =>		
						i <= 0; 
						nextrxd1 <= stop; 
			
					when stop =>			
						i <= 0;
						if rxd = '1' then
							nextrxd1 <= start;	
						end if;	
						nextrxd1 <= start;
				end	case;
			end if;
		elsif miport(1 downto 0) = "00" and miport(6) = '0' then 
			case currrxd2 is
				when syn1det =>
					if j <= len-1 then
						syndet_out <= '0';
						rxreg(j) := rxd;
						j <= j + 1;
					else
						rxreg(len-1 downto 0) := rxd & rxreg(len-1 downto 1) ;
					end if;				

					if rxreg(len-1 downto 0) = syn1port(len-1 downto 0) and j >= len-1 then
						j <= 0;
						if miport(7) = '0' then
							syndet_out <= '0';
							if miport(4) = '1' then
								nextrxd2 <= parity;
							else
								nextrxd2 <= syn2det;
							end if;
						else				   
							syndet_out <= '1';
							if miport(4) = '1' then
								nextrxd2 <= parity;
							else
								nextrxd2 <= dbits;
							end if;
						end if;
					else				
						syndet_out <= '0';
						nextrxd2 <= syn1det;
					end if;
			
				when syn2det =>
					if j <= len-1 then	
						syndet_out <= '0';
						rxreg(j) := rxd;
						j <= j + 1;
					end if;		
								   
					if j = len-1 then
						if rxreg(len-1 downto 0) = syn2port(len-1 downto 0) then
							syndet_out <= '1';
							if miport(4) = '1' then
								nextrxd2 <= parity;
							else
								nextrxd2 <= dbits;
							end if;
						else
							syndet_out <= '0';
							nextrxd2 <= syn1det;
						end if;
					else
						syndet_out <= '0';
						nextrxd2 <= syn2det;
					end if;
		
				when dbits => 
					rxreg(j) := rxd;
					if j <= len-2 then
						j <= j + 1;
						nextrxd2 <= dbits;
					elsif miport(4) = '1' then
						j <= 0;
						nextrxd2 <= parity;
					elsif syndet_out = '1' then	 			  
						j <= 0;
						nextrxd2 <= dbits; 
					elsif syndet_out = '0' then
						j <= 0;
						nextrxd2 <= syn1det;
					end if;					  

				when parity =>		
					j <= 0;
					if syndet_out = '1' then
		 				nextrxd2 <= dbits;
					elsif syndet_out = '0' then
						if rxreg(len-1 downto 0) = syn1port(len-1 downto 0) then
							nextrxd2 <= syn2det; 
						else		
							nextrxd2 <= syn1det;
						end if;
					end if;
			end case;
		elsif miport(1 downto 0) = "00" and miport(6) = '1' then 
			case currrxd3 is
				when dbits => 
					rxreg(k) := rxd;
					if k <= len-2 then
						k <= k + 1;
						nextrxd3 <= dbits;
					elsif miport(4) = '1' then
						k <= 0;
						nextrxd3 <= parity;
					else
						k <= 0;
						nextrxd3 <= dbits; 
					end if;					  

				when parity =>		
					k <= 0;
					nextrxd3 <= dbits; 
				when stop =>								
					k <= 0;
					if syndet_in = '1' then
		 				nextrxd3 <= dbits;
					elsif syndet_in = '0' then
						nextrxd3 <= stop; 
					end if; 
			end case;
		end if;							
		holdreg <= rxreg;
	end if;	 

	end process;

	process ( rxclk, currrxd1,currrxd2, currrxd3,ciport )
	variable par: std_logic:='0';
	begin	
		if ciport(4) = '1' then
			parity_error <= '0';
		end if;
		if rxclk = '1' and rxclk'event then
			if currrxd1 = parity or currrxd2 = parity or currrxd3 = parity then
				for l in 0 to len-1 loop
					par := par xor holdreg(l);
				end loop;
				parity_error <= (par xor rxd);
			end if;
		end if;
	end process;		
	
	process ( rxclk, currrxd1, ciport )
	begin	
		if ciport(4) = '1' then
			framing_error <= '0';
		end if;
		if rxclk = '1' and rxclk'event then
			if miport(1 downto 0) /= "00" then
				if currrxd1 = stop and rxd = '1' then
					framing_error <= '0';
				elsif currrxd1 = stop and rxd = '0' then
					framing_error <= '1';
				end if;
			end if;
		end if;
	end process;	

	process ( i, currrxd1, currrxd2, currrxd3, rxclk, ciport )
	begin
		if ciport(4) = '1' then
				overrun_error <= '0';   
		end if;				 
		if rxclk = '1' and rxclk'event then
			if miport(1 downto 0) /= "00" then
				if currrxd1 = stop then
					if rxrdy_in = '1' then 
						overrun_error <= '1';   
					end if;
					rxreg_full <= '1';
				else	
					rxreg_full <= '0';
				end if;
			elsif miport(1 downto 0) = "00" and miport(6) = '0' then
				if currrxd2 = dbits and j= len-1 then
					if rxrdy_in = '1' then 
						overrun_error <= '1';   
					end if;
					rxreg_full <= '1';
				else	
					rxreg_full <= '0';
				end if;
			elsif miport(1 downto 0) = "00" and miport(6) = '1' then 
				if currrxd3 = dbits and k = len-1 then
					if rxrdy_in = '1' then 
						overrun_error <= '1';   
					end if;
					rxreg_full <= '1';
				else	
					rxreg_full <= '0';
				end if;	 	
			end if;			
		end if;				
	end process;

	process ( rxclk, rxreg_full )
	begin	
		if rxreg_full = '1' then
			writeport <= holdreg;
		end if;
	end process;  				 

	process ( rxreg_full, data_read, ciport(2) )
	begin
		if rxreg_full = '1' then
			rxrdy_in <= '1';
		elsif data_read = '1' then
			rxrdy_in <= '0';
		elsif ciport(2) = '0' then
			rxrdy_in <= '0';	
		end if;
	end process;

	process (syndet_out, status_read, miport, rxclk, brkdet )
	begin		
		if miport(1 downto 0) = "00" and miport(6) = '0' then
			if status_read = '1' then
				syndet <= '0';
				syndet_status <= '0';				
			else
				syndet <= syndet_out;
				syndet_status <= syndet_out;
			end if;
		elsif miport(1 downto 0) /= "00" then
			syndet <= brkdet;				 
			syndet_status <= brkdet;
		else			   
			syndet_status <= 'Z';
			syndet <= 'Z';
		end if;
	end process;						   

	process ( syndet, miport, rxclk, status_read)
	begin
		if miport(1 downto 0) = "00" and miport(6) = '1' then
			syndet_in <= syndet; 
			if status_read = '1' then
				syndet_status <= '0';				
			elsif syndet = '1' then
				syndet_status <= '1';
			end if;
		else						
			syndet_status <= 'Z';
			syndet_in <= 'Z';
		end if;	 
	end process;   
	
	process ( rxclk )
	begin
		if rxclk = '1' and rxclk'event then
			if miport(1 downto 0) /= "00" and count = baud/2 then
				if rxd = '0' then
					brk <= brk + 1;
				else
					brk <= 0;
				end if;
			end if;
		end if;
	end process;  
	
	process( miport, len )		   
	variable w : integer:=0;
	begin
		if miport(1 downto 0) /= "00" then
			w := len + 2;
			if miport(4) = '1' then
				w := w + 1;
			end if;	
			if miport(7 downto 6) = "10" or miport(7 downto 6) = "11" then
				w := w + 1;
			end if;
			width <= w + w;
		end if;
	end process;

	process ( brk, rxd )
	begin
		if rxd = '1' then
			brkdet <= '0';	
		elsif brk >= width then
			brkdet <= '1';
		else
			brkdet <= '0';
		end if;
	end process;  

end rec_buf_arc;

⌨️ 快捷键说明

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