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

Subversion Repositories uart_fpga_slow_control_migrated

[/] [uart_fpga_slow_control/] [trunk/] [code/] [gh_uart_Rx_8bit.vhd] - Rev 34

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

-----------------------------------------------------------------------------
--	Filename:	gh_uart_Rx_8bit.vhd
--
--	Description:
--		an 8 bit UART Rx Module
--
--	Copyright (c) 2006 by H LeFevre 
--		A VHDL 16550 UART core
--		an OpenCores.org Project
--		free to use, but see documentation for conditions 
--
--	Revision 	History:
--	Revision 	Date       	Author    	Comment
--	-------- 	---------- 	---------	-----------
--	1.0      	02/18/06  	H LeFevre  	Initial revision
--	1.1      	02/25/06  	H LeFevre  	mod to SM, goes to idle faster
--	        	          	         	   if no break error  
--	2.0     	06/18/07  	P.Azkarate  Define "range" in R_WCOUNT and R_brdCOUNT signals
-----------------------------------------------------------------------------
library ieee ;
use ieee.std_logic_1164.all ;
 
entity gh_uart_Rx_8bit is 
	port(
		clk       : in std_logic; -- clock
		rst       : in std_logic;
		BRCx16    : in std_logic; -- 16x clock enable
		sRX       : in std_logic; 
		num_bits  : in integer;
		Parity_EN : in std_logic;
		Parity_EV : in std_logic;
		Parity_ER : out std_logic;
		Frame_ER  : out std_logic;
		Break_ITR : out std_logic;
		D_RDY     : out std_logic;
		D         : out std_logic_vector(7 downto 0)
		);
end entity;
 
architecture a of gh_uart_Rx_8bit is
 
COMPONENT gh_shift_reg_se_sl is
	GENERIC (size: INTEGER := 16); 
	PORT(
		clk      : IN STD_logic;
		rst      : IN STD_logic;
		srst     : IN STD_logic:='0';
		SE       : IN STD_logic; -- shift enable
		D        : IN STD_LOGIC;
		Q        : OUT STD_LOGIC_VECTOR(size-1 DOWNTO 0)
		);
END COMPONENT;
 
COMPONENT gh_parity_gen_Serial is
	PORT(	
		clk      : IN STD_LOGIC;
		rst      : IN STD_LOGIC; 
		srst     : in STD_LOGIC;
		SD       : in STD_LOGIC; -- sample data pulse
		D        : in STD_LOGIC; -- data
		Q        : out STD_LOGIC
		);
END COMPONENT;
 
COMPONENT gh_counter_integer_down IS	
	generic(max_count : integer := 8);
	PORT(	
		clk      : IN STD_LOGIC;
		rst      : IN STD_LOGIC; 
		LOAD     : in STD_LOGIC; -- load D
		CE       : IN STD_LOGIC; -- count enable
		D        : in integer RANGE 0 TO max_count;
		Q        : out integer RANGE 0 TO max_count
		);
END COMPONENT;
 
COMPONENT gh_jkff is
	PORT(	
		clk  : IN STD_logic;
		rst  : IN STD_logic;
		J,K  : IN STD_logic;
		Q    : OUT STD_LOGIC
		);
END COMPONENT;
 
	type R_StateType is (idle,R_start_bit,shift_data,R_parity,
	                     R_stop_bit,break_err);
	signal R_state, R_nstate : R_StateType; 
 
	signal parity      : std_logic;
	signal parity_Grst : std_logic;
	signal RWC_LD      : std_logic;
	signal R_WCOUNT : integer range 0 to 15;
	signal s_DATA_LD : std_logic;
	signal chk_par : std_logic;
	signal chk_frm : std_logic;
	signal clr_brk : std_logic;
	signal clr_D : std_logic;
	signal s_chk_par : std_logic;
	signal s_chk_frm : std_logic;
	signal R_shift_reg : std_logic_vector(7 downto 0);
	signal iRX : std_logic;
	signal BRC : std_logic;
	signal dCLK_LD : std_logic;
	signal R_brdCOUNT : integer range 0 to 15;
	signal iParity_ER : std_logic;
	signal iFrame_ER : std_logic;
	signal iBreak_ITR : std_logic;
	signal iD_RDY : std_logic;
 
begin
 
----------------------------------------------
---- outputs----------------------------------
----------------------------------------------
process(CLK,rst)
begin
	if (rst = '1') then	
		Parity_ER <= '0';
		Frame_ER <= '0';
		Break_ITR <= '0';
		D_RDY <= '0';
	elsif (rising_edge(CLK)) then
		if (BRCx16 = '1') then
			D_RDY <= iD_RDY;
			if (iD_RDY = '1') then
				Parity_ER <= iParity_ER;
				Frame_ER <= iFrame_ER;
				Break_ITR <= iBreak_ITR;
			end if;
		end if;
	end if;
end process;
 
	D <= R_shift_reg when (num_bits = 8) else
	    ('0' & R_shift_reg(7 downto 1)) when (num_bits = 7) else
	    ("00" & R_shift_reg(7 downto 2)) when (num_bits = 6) else
	    ("000" & R_shift_reg(7 downto 3)); -- when (bits_word = 5) else
 
 
----------------------------------------------
 
	dCLK_LD <= '1' when (R_state = idle) else
	           '0';
 
	BRC <= '0' when (BRCx16 = '0') else
	       '1' when (R_brdCOUNT = 0) else
	       '0';
 
u1 : gh_counter_integer_down -- baud rate divider
	generic map (15)
	port map(
		clk => clk,  
		rst  => rst, 
		LOAD => dCLK_LD,
		CE => BRCx16,
		D => 14,
		Q => R_brdCOUNT);
 
----------------------------------------------------------
 
U2 : gh_shift_reg_se_sl 
	Generic Map(8)
	PORT MAP (
		clk => clk,
		rst => rst,
		srst => clr_D,
		SE => s_DATA_LD,
		D => sRX,
		Q => R_shift_reg);
 
-----------------------------------------------------------
 
	chk_par <= s_chk_par and (((parity xor iRX) and Parity_EV) 
	                 or (((not parity) xor iRX) and (not Parity_EV)));
 
U2c : gh_jkff 
	PORT MAP (
		clk => clk,
		rst => rst,
		j => chk_par,
		k => dCLK_LD,
		Q => iParity_ER);
 
	chk_frm <= s_chk_frm and (not iRX);
 
U2d : gh_jkff 
	PORT MAP (
		clk => clk,
		rst => rst,
		j => chk_frm,
		k => dCLK_LD,
		Q => iFrame_ER);
 
U2e : gh_jkff 
	PORT MAP (
		clk => clk,
		rst => rst,
		j => clr_d,
		k => clr_brk,
		Q => iBreak_ITR);
 
--------------------------------------------------------------
--------------------------------------------------------------
 
 
process(R_state,BRCx16,BRC,iRX,R_WCOUNT,Parity_EN,R_brdCOUNT,iBreak_ITR)
begin
	case R_state is
		when idle => -- idle  
			iD_RDY <= '0'; s_DATA_LD <= '0'; RWC_LD <= '1'; 
			s_chk_par <= '0'; s_chk_frm <= '0'; clr_brk <= '0';
			clr_D <= '0';
			if (iRX = '0') then	
				R_nstate <= R_start_bit;
			else 
				R_nstate <= idle;
			end if;
		when R_start_bit => -- 
			iD_RDY <= '0'; s_DATA_LD <= '0'; RWC_LD <= '1'; 
			s_chk_par <= '0'; s_chk_frm <= '0'; clr_brk <= '0';
			if (BRC = '1') then
				clr_D <= '1';
				R_nstate <= shift_data;
			elsif ((R_brdCOUNT = 8) and (iRX = '1')) then -- false start bit detection
				clr_D <= '0';
				R_nstate <= idle;
			else
				clr_D <= '0';
				R_nstate <= R_start_bit;
			end if;
		when shift_data => -- send data bit	
			iD_RDY <= '0'; RWC_LD <= '0';
			s_chk_par <= '0'; s_chk_frm <= '0';
			clr_D <= '0';
			if (BRCx16 = '0') then
				s_DATA_LD <= '0'; clr_brk <= '0';
				R_nstate <= shift_data;	
			elsif (R_brdCOUNT = 8) then
				s_DATA_LD <= '1'; clr_brk <= iRX; 
				R_nstate <= shift_data;	
			elsif ((R_WCOUNT = 1) and (R_brdCOUNT = 0) and (Parity_EN = '1')) then
				s_DATA_LD <= '0'; clr_brk <= '0';
				R_nstate <= R_parity;	
			elsif ((R_WCOUNT = 1) and (R_brdCOUNT = 0)) then
				s_DATA_LD <= '0'; clr_brk <= '0';
				R_nstate <= R_stop_bit;
			else
				s_DATA_LD <= '0'; clr_brk <= '0'; 
				R_nstate <= shift_data;
			end if;
		when R_parity => -- check parity bit
			iD_RDY <= '0'; s_DATA_LD <= '0'; 
			RWC_LD <= '0'; s_chk_frm <= '0';
			clr_D <= '0';
			if (BRCx16 = '0') then
				s_chk_par <= '0';  clr_brk <= '0';
				R_nstate <= R_parity;
			elsif (R_brdCOUNT = 8) then
				s_chk_par <= '1'; clr_brk <= iRX; 
				R_nstate <= R_parity;
			elsif (BRC = '1') then
				s_chk_par <= '0'; clr_brk <= '0';
				R_nstate <= R_stop_bit;
			else 
				s_chk_par <= '0'; clr_brk <= '0';
				R_nstate <= R_parity;
			end if;	 
		when R_stop_bit => -- check stop bit
			s_DATA_LD <= '0'; RWC_LD <= '0'; 
			s_chk_par <= '0'; clr_brk <= iRX;
			clr_D <= '0';
			if ((BRC = '1') and (iBreak_ITR = '1')) then
				iD_RDY <= '1'; s_chk_frm <= '0';
				R_nstate <= break_err; 
			elsif (BRC = '1') then
				iD_RDY <= '1'; s_chk_frm <= '0';
				R_nstate <=	idle;
			elsif (R_brdCOUNT = 8) then
				iD_RDY <= '0'; s_chk_frm <= '1';
				R_nstate <= R_stop_bit;	
			elsif ((R_brdCOUNT = 7) and (iBreak_ITR = '0')) then -- added 02/20/06
				iD_RDY <= '1'; s_chk_frm <= '0';
				R_nstate <=	idle;
			else 
				iD_RDY <= '0'; s_chk_frm <= '0';
				R_nstate <= R_stop_bit;
			end if;	
		when break_err => 
			iD_RDY <= '0'; s_DATA_LD <= '0'; RWC_LD <= '0'; 
			s_chk_par <= '0'; s_chk_frm <= '0'; clr_brk <= '0';
			clr_D <= '0';
			if (iRX = '1') then
				R_nstate <= idle;
			else
				R_nstate <= break_err;
			end if;
		when others => 
			iD_RDY <= '0'; s_DATA_LD <= '0'; RWC_LD <= '0'; 
			s_chk_par <= '0'; s_chk_frm <= '0'; clr_brk <= '0';
			clr_D <= '0';
			R_nstate <= idle;
	end case;
end process;
 
--
-- registers for SM
process(CLK,rst)
begin
	if (rst = '1') then	
		iRX <= '1';
		R_state <= idle;
	elsif (rising_edge(CLK)) then
		if (BRCx16 = '1') then
			iRX <= sRX;
			R_state <= R_nstate;
		else 
			iRX <= iRX;
			R_state <= R_state;
		end if;
	end if;
end process;
 
u3 : gh_counter_integer_down -- word counter
	generic map (8)
	port map(
		clk => clk,  
		rst  => rst, 
		LOAD => RWC_LD,
		CE => BRC,
		D => num_bits,
		Q => R_WCOUNT
		);
 
--------------------------------------------------------
--------------------------------------------------------
 
	parity_Grst <= '1' when (R_state = R_start_bit) else
	               '0';
 
U4 : gh_parity_gen_Serial 
	PORT MAP (
		clk => clk,
		rst => rst,
		srst => parity_Grst,
		SD => BRC,
		D => R_shift_reg(7),
		Q => parity);
 
 
end a;
 
 

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.