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

Subversion Repositories rs232_with_buffer_and_wb

[/] [rs232_with_buffer_and_wb/] [trunk/] [rtl/] [uart_rx.vhd] - Rev 38

Compare with Previous | Blame | View Log

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
 
entity rx_func is
	port(	clk, reset, rx_enable : in std_logic;
			rx : in std_logic;
 
			word_width : in std_logic_vector(3 downto 0);
			baud_period : in std_logic_vector(15 downto 0);
			use_parity_bit, parity_type : in std_logic;
			stop_bits : in std_logic_vector(1 downto 0);
			idle_line_lvl : in std_logic;
 
			start_samples : in std_logic_vector(3 downto 0);	--How many correct samples should give a start bit
			line_samples : in std_logic_vector(3 downto 0);		--How many samples should tip the internal rx value
 
			data 		: out std_logic_vector(7 downto 0);
			data_ready 	: out std_logic;
			parity_error :	out std_logic;
			stop_bit_error : out std_logic);
end entity rx_func;
 
architecture behaviour of rx_func is
	type state_type is (idle, data_bit0, data_bit1, data_bit2, data_bit3, data_bit4, data_bit5, data_bit6, data_bit7, parity_bit, stop_bit1, stop_bit2, data_check, data_rdy);
	signal current_state : state_type := idle;
	signal next_state, next_state_rst : state_type;
	signal next_state_from_data_bit4 : state_type;
	signal next_state_from_data_bit5 : state_type;
	signal next_state_from_data_bit6 : state_type;
	signal next_state_from_data_bit7 : state_type;
	signal next_state_from_stop_bit1 : state_type;
 
	signal sampled_data : std_logic_vector(9 downto 0);-- := "0000000000";
 
	signal period_count_enable : std_logic;
	signal period_count_q : std_logic_vector(15 downto 0);-- := "0000000000000000";
	signal period_count_d : std_logic_vector(15 downto 0);
	signal baud_tick : std_logic;
	signal period16_count_q : std_logic_vector(11 downto 0);-- := "000000000000";
	signal period16_count_d : std_logic_vector(11 downto 0);
	signal sample_tick : std_logic;
	signal sample_reg_q, sample_reg_start_bit_q : std_logic_vector(3 downto 0);-- := "0000";
	signal sample_reg_start_bit_d, sample_reg_d : std_logic_vector(3 downto 0);
	signal rx_sampled_q : std_logic;-- := '0';
	signal rx_sampled_d : std_logic;
	signal xored_sampled_data_bit_q : std_logic;-- := '0';
	signal xored_sampled_data_bit_d : std_logic;
 
begin
-------------------------
-- Combinational logic --
-------------------------
 
--State Logic
	next_state 					<= 	idle when reset = '1' else
									next_state_rst;
	with current_state select
		next_state_rst 			<=	data_bit0 					when idle,		--Identifying start bit
									data_bit1 					when data_bit0,
									data_bit2 					when data_bit1,
									data_bit3 					when data_bit2,
									data_bit4 					when data_bit3,
									next_state_from_data_bit4	when data_bit4,
									next_state_from_data_bit5 	when data_bit5,
									next_state_from_data_bit6 	when data_bit6,
									next_state_from_data_bit7 	when data_bit7,
									stop_bit1 					when parity_bit,
									next_state_from_stop_bit1	when stop_bit1,
									data_check					when stop_bit2,
									data_rdy					when data_check,
									idle						when data_rdy,
									idle 						when others;
 
	next_state_from_data_bit4 <= 	parity_bit 	when word_width = "0101" and use_parity_bit = '1' else
									stop_bit1	when word_width = "0101" and use_parity_bit = '0' else
									data_bit5;
 
	next_state_from_data_bit5 <= 	parity_bit 	when word_width = "0110" and use_parity_bit = '1' else
									stop_bit1	when word_width = "0110" and use_parity_bit = '0' else
									data_bit6;
 
	next_state_from_data_bit6 <= 	parity_bit 	when word_width = "0111" and use_parity_bit = '1' else
									stop_bit1	when word_width = "0111" and use_parity_bit = '0' else
									data_bit7;
 
	next_state_from_data_bit7 <= 	parity_bit 	when use_parity_bit = '1' else
									stop_bit1;
 
	next_state_from_stop_bit1 <= 	stop_bit2 	when stop_bits = "10" else
									data_check;
 
 
--Sample logic
	period16_count_d 		<= 	period16_count_q + 1 when reset = '0' and period16_count_q /= baud_period(15 downto 4) else
								"000000000001";
	sample_tick 			<= 	'1' when period16_count_q = baud_period(15 downto 4) else
								'0';
 
--Baud logic
	with current_state select
		period_count_enable		<= 	'0' when idle,
									'0' when data_check,
									'0' when data_rdy,
									'1' when others;
	period_count_d 			<= 	period_count_q + 1 when reset = '0' and period_count_q /= baud_period else
								"0000000000000001";
	baud_tick				<=	'1' when period_count_q = baud_period else
								'0';
 
--RX sampled, by saturation counter
	sample_reg_d			<=	sample_reg_q + 1 	when reset = '0' and rx = '1' and sample_reg_q /= line_samples else
								sample_reg_q - 1 	when reset = '0' and rx = '0' and sample_reg_q /= "0000" else
								sample_reg_q		when reset = '0' else
								"0000";
 
	rx_sampled_d			<=  '1' when reset = '0' and sample_reg_q = line_samples else
								'0' when reset = '0' and sample_reg_q = "0000" else
								rx_sampled_q;
 
	sample_reg_start_bit_d	<=	sample_reg_start_bit_q + 1	when reset = '0' and rx /= idle_line_lvl and sample_reg_start_bit_q /= start_samples else
								sample_reg_start_bit_q - 1	when reset = '0' and rx  = idle_line_lvl and sample_reg_start_bit_q /= "0000" else
								sample_reg_start_bit_q		when reset = '0' else
								"0000";
 
--Parity bit
	with current_state select
		xored_sampled_data_bit_d	<= 	'0' when idle,
										xored_sampled_data_bit_q when stop_bit1,
										xored_sampled_data_bit_q when stop_bit2,
										xored_sampled_data_bit_q when data_check,
										xored_sampled_data_bit_q xor rx_sampled_q when others;
 
--Reciving status signals
	data_ready <= 		'1' when current_state = data_rdy else
						'0';
	parity_error 	<= 	'1' when xored_sampled_data_bit_q /= parity_type and current_state = data_check else
						'0';
	stop_bit_error 	<= 	'1' when current_state = data_check and (sampled_data(8) /= idle_line_lvl or (sampled_data(9) /= idle_line_lvl and stop_bits = "10")) else
						'0';
 
 
--------------------
-- Register logic --
--------------------
	register_logic : process(clk, reset, rx_enable, period_count_enable, sample_tick, baud_tick, current_state, use_parity_bit)
	begin
		if rising_edge(clk) then
			--sample counter
			if rx_enable = '1' or reset = '1' then
				period16_count_q	<= period16_count_d;
			end if;
 
			--baud counter
			if period_count_enable = '1' or reset = '1' then
				period_count_q 		<= period_count_d;
			end if;
 
			if sample_tick = '1' then
				sample_reg_q			<= sample_reg_d;
				rx_sampled_q 			<= rx_sampled_d;
				sample_reg_start_bit_q	<= sample_reg_start_bit_d;
			end if;
 
			if baud_tick = '1' or (current_state = idle and sample_reg_start_bit_q = start_samples) or current_state = data_check or current_state = data_rdy then
				current_state <= next_state;
			end if;
 
			if baud_tick = '1' and current_state = data_bit0 then
				sampled_data(0) <= rx_sampled_q;
			end if;
			if baud_tick = '1' and current_state = data_bit1 then
				sampled_data(1) <= rx_sampled_q;
			end if;
			if baud_tick = '1' and current_state = data_bit2 then
				sampled_data(2) <= rx_sampled_q;
			end if;
			if baud_tick = '1' and current_state = data_bit3 then
				sampled_data(3) <= rx_sampled_q;
			end if;
			if baud_tick = '1' and current_state = data_bit4 then
				sampled_data(4) <= rx_sampled_q;
			end if;
			if baud_tick = '1' and current_state = data_bit5 then
				sampled_data(5) <= rx_sampled_q;
			end if;
			if baud_tick = '1' and current_state = data_bit6 then
				sampled_data(6) <= rx_sampled_q;
			end if;
			if baud_tick = '1' and current_state = data_bit7 then
				sampled_data(7) <= rx_sampled_q;
			end if;
			if baud_tick = '1' and current_state = stop_bit1 then
				sampled_data(8) <= rx_sampled_q;
			end if;
			if baud_tick = '1' and current_state = stop_bit2 then
				sampled_data(9) <= rx_sampled_q;
			end if;	
 
			if current_state = data_check then
				data <= sampled_data(7 downto 0);
			end if;
 
			if baud_tick = '1' and use_parity_bit = '1' then
				xored_sampled_data_bit_q <= xored_sampled_data_bit_d;
			end if;
		end if;
	end process register_logic;
 
end architecture behaviour;

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.