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

📄 gh_uart_tx_8bit.vhd

📁 FPGA开发中常用的串口模块
💻 VHD
字号:
-----------------------------------------------------------------------------
--	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
-----------------------------------------------------------------------------
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)
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;

⌨️ 快捷键说明

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