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_Tx_8bit.vhd] - Rev 10

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

-----------------------------------------------------------------------------
--	Filename:	gh_uart_Tx_8bit.vhd
--
--	Description:
--		an 8 bit UART Tx Module
--
--	Copyright (c) 2006, 2007 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	add BUSYn output
--	2.0     	06/18/07  	P.Azkarate  Define "range" in T_WCOUNT and x_dCOUNT signals
--	2.1     	07/12/07  	H LeFevre	fix a problem with 5 bit data and 1.5 stop bits
--       		          	         	   as pointed out by Matthias Klemm
--	2.2     	08/17/07  	H LeFevre	add stopB to sensitivity list line 164
--       		          	         	   as suggested by Guillaume Zin 
-----------------------------------------------------------------------------
library ieee ;
use ieee.std_logic_1164.all ;
 
entity gh_uart_Tx_8bit is 
	port(
		clk       : in std_logic; --  clock
		rst       : in std_logic;
		xBRC      : in std_logic; -- x clock enable
		D_RYn     : in std_logic; -- data ready 
		D         : in std_logic_vector(7 downto 0);
		num_bits  : in integer:= 8; -- number of bits in transfer
		Break_CB  : in std_logic;
		stopB     : in std_logic;
		Parity_EN : in std_logic;
		Parity_EV : in std_logic;
		sTX       : out std_logic;
		BUSYn     : out std_logic;
		read      : out std_logic -- data read
		);
end entity;
 
architecture a of gh_uart_Tx_8bit is
 
COMPONENT gh_shift_reg_PL_sl is
	GENERIC (size: INTEGER := 16);
	PORT(
		clk      : IN STD_logic;
		rst      : IN STD_logic;
		LOAD     : IN STD_LOGIC;  -- load data
		SE       : IN STD_LOGIC;  -- shift enable
		D        : IN STD_LOGIC_VECTOR(size-1 DOWNTO 0);
		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;
 
	type T_StateType is (idle,s_start_bit,shift_data,s_parity,
	                     s_stop_bit,s_stop_bit2);
	signal T_state, T_nstate : T_StateType; 
 
	signal parity      : std_logic;
	signal parity_Grst : std_logic;
	signal TWC_LD      : std_logic;
	signal TWC_CE      : std_logic;
	signal T_WCOUNT : integer range 0 to 15;
	signal D_LD_v : integer range 1 to 15;
	signal D_LD : std_logic;
	signal Trans_sr_SE : std_logic;
	signal Trans_shift_reg : std_logic_vector(7 downto 0);
	signal iTX : std_logic;
	signal BRC : std_logic;
	signal dCLK_LD : std_logic;
	signal x_dCOUNT : integer range 0 to 15;
 
begin
 
----------------------------------------------
---- outputs----------------------------------
----------------------------------------------
 
	BUSYn <= '1' when (T_state = idle) else
	         '0';
 
	read <= D_LD; -- read a data word
 
----------------------------------------------
 
	dCLK_LD <= '1' when ((num_bits = 5) and (stopB = '1') 
	               and (T_state = s_stop_bit2) and (x_dCOUNT = 7)) else
	           '0' when (D_RYn = '0') else
	           '0' when (T_state /= idle) else
	           '1';
 
	D_LD_v <= 15 when (T_state = s_stop_bit2) else
	           1;
 
	BRC <= '0' when (xBRC = '0') else
	       '1' when (x_dCOUNT = 0) else
	       '0';
 
 
u1 : gh_counter_integer_down -- baud rate divider
	generic map (15)
	port map(
		clk => clk,  
		rst  => rst, 
		LOAD => dCLK_LD,
		CE => xBRC,
		D => D_LD_v,
		Q => x_dCOUNT);
 
U2 : gh_shift_reg_PL_sl 
	Generic Map(8)
	PORT MAP (
		clk => clk,
		rst => rst,
		LOAD => D_LD,
		SE => Trans_sr_SE,
		D => D,
		Q => Trans_shift_reg);
 
--------------------------------------------------------------
--------------------------------------------------------------
 
process (clk,rst)
begin
	if (rst = '1') then
		sTX <= '1';
	elsif (rising_edge(clk)) then
		sTX <= iTX and (not Break_CB);
	end if;
end process ;
 
	iTX <= '0' when (T_state = s_start_bit) else -- send start bit
	        Trans_shift_reg(0) when (T_state = shift_data) else -- send data
	        parity when ((Parity_EV = '1') and (T_state = s_parity)) else
	        (not parity) when (T_state = s_parity) else
	        '1'; -- idle, stop bit
 
process(T_state,D_RYn,BRC,T_WCOUNT,Parity_EN,num_bits,x_dCOUNT,stopB)
begin
	case T_state is
		when idle => -- idle  
			TWC_CE <= '0';
			if ((D_RYn = '0') and (BRC = '1')) then
				D_LD <= '1'; Trans_sr_SE <= '0'; 
				TWC_LD <= '0'; 
				T_nstate <= s_start_bit;
			else 
				D_LD <= '0'; Trans_sr_SE <= '0'; TWC_LD <= '0';
				T_nstate <= idle;
			end if;
		when s_start_bit => -- fifo is read, send start bit
			TWC_CE <= '0';
			if (BRC = '1') then
				D_LD <= '0'; Trans_sr_SE <= '0'; TWC_LD <= '1';
				T_nstate <= shift_data;
			else
				D_LD <= '0'; Trans_sr_SE <= '0'; TWC_LD <= '0';
				T_nstate <= s_start_bit;
			end if;
		when shift_data => -- send data bit
			if (BRC = '0') then
				D_LD <= '0'; Trans_sr_SE <= '0'; 
				TWC_LD <= '0'; TWC_CE <= '0';
				T_nstate <= shift_data;
			elsif ((T_WCOUNT = 1) and (Parity_EN = '1')) then
				D_LD <= '0'; Trans_sr_SE <= '0'; 
				TWC_LD <= '0'; TWC_CE <= '1';
				T_nstate <= s_parity;
			elsif (T_WCOUNT = 1) then
				D_LD <= '0'; Trans_sr_SE <= '0'; 
				TWC_LD <= '0'; TWC_CE <= '1';
				T_nstate <= s_stop_bit;
			else
				D_LD <= '0'; Trans_sr_SE <= '1'; 
				TWC_LD <= '0'; TWC_CE <= '1';
				T_nstate <= shift_data;
			end if;
		when s_parity => -- send parity bit
			TWC_CE <= '0';
			if (BRC = '1') then
				D_LD <= '0'; Trans_sr_SE <= '0'; TWC_LD <= '0';
				T_nstate <= s_stop_bit;
			else 
				D_LD <= '0'; Trans_sr_SE <= '0'; TWC_LD <= '0';
				T_nstate <= s_parity;
			end if;	 
		when s_stop_bit => -- send stop bit
			TWC_CE <= '0';
			if (BRC = '0') then
				D_LD <= '0'; Trans_sr_SE <= '0'; TWC_LD <= '0';
				T_nstate <= s_stop_bit;
			elsif (stopB = '1') then
				D_LD <= '0'; Trans_sr_SE <= '0'; TWC_LD <= '0';
				T_nstate <= s_stop_bit2;
			elsif (D_RYn = '0') then
				D_LD <= '1'; Trans_sr_SE <= '0'; TWC_LD <= '0';
				T_nstate <= s_start_bit;
			else 
				D_LD <= '0'; Trans_sr_SE <= '0'; TWC_LD <= '0';
				T_nstate <= idle;
			end if;
		when s_stop_bit2 => -- send stop bit 
			TWC_CE <= '0';
			if ((D_RYn = '0') and (BRC = '1')) then
				D_LD <= '1'; Trans_sr_SE <= '0'; TWC_LD <= '0';
				T_nstate <= s_start_bit; 
			elsif (BRC = '1') then
				D_LD <= '0'; Trans_sr_SE <= '0'; TWC_LD <= '0';
				T_nstate <= idle;
			elsif ((num_bits = 5) and (x_dCOUNT = 7) and (D_RYn = '0')) then
				D_LD <= '1'; Trans_sr_SE <= '0'; TWC_LD <= '0';
				T_nstate <= s_start_bit;
			elsif ((num_bits = 5) and (x_dCOUNT = 7)) then
				D_LD <= '1'; Trans_sr_SE <= '0'; TWC_LD <= '0';
				T_nstate <= idle;
			else 
				D_LD <= '0'; Trans_sr_SE <= '0'; TWC_LD <= '0';
				T_nstate <= s_stop_bit2;
			end if;
		when others => 
			D_LD <= '0'; Trans_sr_SE <= '0'; 
			TWC_LD <= '0'; TWC_CE <= '0';
			T_nstate <= idle;
	end case;
end process;
 
--
-- registers for SM
process(CLK,rst)
begin
	if (rst = '1') then
		T_state <= idle;
	elsif (rising_edge(CLK)) then
		T_state <= T_nstate;
	end if;
end process;
 
u3 : gh_counter_integer_down -- word counter
	generic map (8)
	port map(
		clk => clk,  
		rst  => rst, 
		LOAD => TWC_LD,
		CE => TWC_CE,
		D => num_bits,
		Q => T_WCOUNT
		);
 
--------------------------------------------------------
--------------------------------------------------------
 
	parity_Grst <= '1' when (T_state = s_start_bit) else
	               '0';
 
U4 : gh_parity_gen_Serial 
	PORT MAP (
		clk => clk,
		rst => rst,
		srst => parity_Grst,
		SD => BRC,
		D => Trans_shift_reg(0),
		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.