OpenCores
URL https://opencores.org/ocsvn/uart_block/uart_block/trunk

Subversion Repositories uart_block

[/] [uart_block/] [trunk/] [hdl/] [iseProject/] [serial_receiver.vhd] - Rev 39

Go to most recent revision | Compare with Previous | Blame | View Log

--! @file
--! @brief Serial receiver http://www.fpga4fun.com/SerialInterface.html
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
 
--! Use CPU Definitions package
use work.pkgDefinitions.all;
 
entity serial_receiver is
    Port ( 
			  rst : in STD_LOGIC;													--! Reset input		  
			  baudOverSampleClk : in  STD_LOGIC;								--! Baud oversampled 8x (Best way to detect start bit)
           serial_in : in  STD_LOGIC;											--! Uart serial input
           data_ready : out  STD_LOGIC;										--! Data received and ready to be read
           data_byte : out  STD_LOGIC_VECTOR ((nBits-1) downto 0));	--! Data byte received
end serial_receiver;
 
--! @brief Serial receiver http://www.fpga4fun.com/SerialInterface.html
--! @details Implement block that create a byte from the serial stream of data.
architecture Behavioral of serial_receiver is
signal current_s: rxStates; 
signal filterRx : rxFilterStates; 
signal syncDetected : std_logic;
 
begin
	-- First we need to oversample(8x baud rate) out serial channel to syncronize with the PC (By detecting the start bit)
	process (rst, baudOverSampleClk, serial_in, current_s)
	begin
		if rst = '1' then
			filterRx <= s0;			
			syncDetected <= '0';
		elsif rising_edge(baudOverSampleClk) then
			case filterRx is
				when s0 =>
					syncDetected <= '0';
					-- Spike down detected, verify if it's valid for at least 4 cycles					
					if serial_in = '0' then
						filterRx <= s1;						
					else
						filterRx <= s0;						
					end if;
 
				when s1 =>
					syncDetected <= '0';
					if serial_in = '0' then
						filterRx <= s2;
						syncDetected <= '0';
					else
						filterRx <= s0;
					end if;
 
				when s2 =>
					syncDetected <= '0';
					if serial_in = '0' then
						filterRx <= s3;
						syncDetected <= '0';
					else
						filterRx <= s0;
					end if;
 
				when s3 =>
					syncDetected <= '0';
					if serial_in = '0' then
						filterRx <= s4;
						syncDetected <= '0';
					else
						filterRx <= s0;
					end if;
 
				when s4 =>					
					-- Real Beginning of start bit detected 
					if serial_in = '0' then
						filterRx <= s4;
						syncDetected <= '1';					
					end if; 
 
					-- Reset out sync detector when finished to receive a byte
					if current_s = rx_idle then
						filterRx <= s0;						
					end if;
			end case;
		end if;
	end process;
 
	-- Process to handle the serial receive (On this case our reset is the syncDetected signal
	-- Always include all of your signals on the sensivity list!! (Even if the simulation is already ok)
	process (syncDetected, baudOverSampleClk, serial_in) 
	variable byteReceived : STD_LOGIC_VECTOR ((nBits-1) downto 0);
	variable waitBestPoint : integer range 0 to 10;
	constant numTicks : integer := 7;
	begin
		if syncDetected = '0' then
			current_s <= bit0;			
			data_ready <= '0';
			byteReceived := (others => '0');
			waitBestPoint := 0;			
		elsif rising_edge(baudOverSampleClk) then
			case current_s is				
				when bit0 =>
					data_ready <= '0';				
					if (waitBestPoint < numTicks) then
						waitBestPoint := waitBestPoint + 1;						
					else
						waitBestPoint := 0;
						byteReceived(0) := serial_in;					
						current_s <=  bit1;						
					end if;										
 
				when bit1 =>
					data_ready <= '0';
					if (waitBestPoint < numTicks) then
						waitBestPoint := waitBestPoint + 1;						
					else
						waitBestPoint := 0;
						byteReceived(1) := serial_in;					
						current_s <=  bit2;						
					end if;					
 
				when bit2 =>
					data_ready <= '0';
					if (waitBestPoint < numTicks) then
						waitBestPoint := waitBestPoint + 1;						
					else
						waitBestPoint := 0;
						byteReceived(2) := serial_in;					
						current_s <=  bit3;						
					end if;					
 
				when bit3 =>
					data_ready <= '0';
					if (waitBestPoint < numTicks) then
						waitBestPoint := waitBestPoint + 1;						
					else
						waitBestPoint := 0;
						byteReceived(3) := serial_in;					
						current_s <=  bit4;						
					end if;					
 
				when bit4 =>
					data_ready <= '0';
					if (waitBestPoint < numTicks) then
						waitBestPoint := waitBestPoint + 1;						
					else
						waitBestPoint := 0;
						byteReceived(4) := serial_in;					
						current_s <=  bit5;						
					end if;					
 
				when bit5 =>
					data_ready <= '0';
					if (waitBestPoint < numTicks) then
						waitBestPoint := waitBestPoint + 1;						
					else
						waitBestPoint := 0;
						byteReceived(5) := serial_in;					
						current_s <=  bit6;						
					end if;					
 
				when bit6 =>
					data_ready <= '0';
					if (waitBestPoint < numTicks) then
						waitBestPoint := waitBestPoint + 1;						
					else
						waitBestPoint := 0;
						byteReceived(6) := serial_in;					
						current_s <=  bit7;						
					end if;										
 
				when bit7 =>
					data_ready <= '0';
					if (waitBestPoint < numTicks) then
						waitBestPoint := waitBestPoint + 1;						
					else
						waitBestPoint := 0;
						byteReceived(7) := serial_in;					
						data_byte <= byteReceived;
						current_s <=  rx_stop;						
					end if;									
 
				when rx_stop =>
					data_ready <= '1';			
					data_byte <= byteReceived;				
					current_s <=  rx_idle;	
 
				when rx_idle =>
					data_ready <= '1';			
					data_byte <= byteReceived;				
					current_s <=  rx_idle;											
			end case; 
		end if;
	end process;
 
end Behavioral;
 
 

Go to most recent revision | Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.