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

📄 tx_uart_m8.vhd

📁 Lattice 超精简8位软核CPU--Mico8
💻 VHD
字号:
-----------------------------------------------------------------------
-- Tx_UART_M8.vhd
-- --------------------------------------------------------------------
-- >>>>>>>>>>>>>>>>>>>>>>>>> COPYRIGHT NOTICE <<<<<<<<<<<<<<<<<<<<<<<<<
-- --------------------------------------------------------------------
-- Copyright (c) 2005 by Lattice Semiconductor Corporation
-- --------------------------------------------------------------------
--
-- Permission:
--
--   Lattice Semiconductor grants permission to use this code for use
--   in synthesis for any Lattice programmable logic product.  Other
--   use of this code, including the selling or duplication of any
--   portion is strictly prohibited.
--
-- Disclaimer:
--
--   This VHDL or Verilog source code is intended as a design reference
--   which illustrates how these types of functions can be implemented.
--   It is the user's responsibility to verify their design for
--   consistency and functionality through the use of formal
--   verification methods.  Lattice Semiconductor provides no warranty
--   regarding the use or functionality of this code.
--
-- --------------------------------------------------------------------
--           
--                     Lattice Semiconductor Corporation
--                     5555 NE Moore Court
--                     Hillsboro, OR 97214
--                     U.S.A
--
--                     TEL: 1-800-Lattice (USA and Canada)
--                          408-826-6000 (other locations)
--
--                     web: http://www.latticesemi.com/
--                     email: techsupport@latticesemi.com
--
-- --------------------------------------------------------------------
--
-- This is a ultracompact TX UART
-- Address map:
-- 00000110: Data transmit register
-- This will translate the parallel data from a mico8 to 
-- a serial UART output. 
-- The size of the parallel data (generic paramter 8) can be anything 
-- from 5 to 8. 
-- One start and stopbit is provided. 
-- The generic parameter CLK_DIV is used to set the correct baudrate: 
-- baudrate = inputfreq/CLK_DIV
-- This is now fixed to 115200 buad and 40MHz clock. 
-- --------------------------------------------------------------------
--
-- Revision History :
-- --------------------------------------------------------------------
--   Ver  :| Author            :| Mod. Date :| Changes Made:
--   V1.0 :| G.M.              :| 06/03/07  :| Release
-- -------------------------------------------------------------------------------------------------------------------------------------------- 

library ieee; 
use ieee.std_logic_1164.all, ieee.std_logic_arith.all; 


entity TX_UART_M8 is 
generic ( 
	CLKFREQ : in integer := 50000000; -- clock frequency in Hz 
	BAUDRATE : in integer := 9600 
	); 

port 	( 
	Clk : in std_logic; 
	Reset : in std_logic; 
	WR : in std_logic;
	Addr: in std_logic_vector(7 downto 0);
	Mico8_Data : in std_logic_vector (7 downto 0);
	TXD : out std_logic; 
	TX_Ack : out std_logic 
	); 
end TX_UART_M8; 

architecture Behave of TX_UART_M8 is 

	signal zWR : std_logic;
	constant TXaddress: std_logic_vector (7 downto 0) := "00000110";
	signal TxData: std_logic_vector( 7 downto 0);

	signal TX_Req : std_logic; 

	constant TIMECOUNTER_SIZE : integer := CLKFREQ/BAUDRATE-1; 
	constant RTS : std_logic := '0';
	type TxState_type is (E_TxState_Waiting, E_TxState_Start, E_TxState_Data, E_TxState_Stop); 

	signal timecounter : integer range 0 to TIMECOUNTER_SIZE; 
	signal bitcounter : integer range 0 to 8; 
	signal TXShiftRegister : std_logic_vector(1 to 8); 
	signal TxState, nextTxState : TxState_type; 
	signal StartSending : std_logic; 
	signal timecounter_pulse : std_logic; 
	signal sync_RTS : std_logic_vector(3 downto 1); 

attribute pgroup : string;
attribute pgroup of Behave : architecture is "TX_UART";

begin 
-- The TxState statemachine controls the correct flow for the start, data 
-- and stop bit(s). 

process (TxState, StartSending, bitcounter) 
begin 

nextTxState <= TxState; 

case TxState is 
	when E_TxState_Waiting => 
		-- Req for sending data received. 
		if StartSending = '1' then 
			nextTxState <= E_TxState_Start; 
		end if; 
	when E_TxState_Start => 
		nextTxState <= E_TxState_Data; 
	when E_TxState_Data => 
		-- Last databit send. 
		if bitcounter = 8 and StartSending = '0' then 
			nextTxState <= E_TxState_Waiting; 
		end if; 
	when others => 
		nextTxState <= E_TxState_Waiting; 
end case; 
end process; 

-- Generate a pulse when timecounter is 0. 
timecounter_pulse <= '1' when timecounter = 0 else '0'; 

-- Sample the inputsignal from physical EIA232 interface into a flipflop. 
process (sync_RTS) 
begin 
	sync_RTS(sync_RTS'low) <= RTS; 
	sync_RTS(sync_RTS'high downto sync_RTS'low+1) <= sync_RTS(sync_RTS'high-1 downto sync_RTS'low); 
end process; 


process (clk,Reset, WR) 
begin 
if Reset = '1' then 
	timecounter <= TIMECOUNTER_SIZE; 
	TX_Ack <= '0'; 
	StartSending <= '0'; 
	TXShiftRegister <= (others => '1'); 
	TxData <= (others => '0'); 
	zWR <= WR;
	TX_Req <= '0';
elsif rising_edge(clk) then 
	-- Mico8 interface
	zWR <= WR;
	if ((zWR /= WR) and (WR = '0') and (Addr = TXaddress)) then
		TxData(7 downto 0) <= Mico8_Data(7 downto 0);
		TX_Req <= '1';
	else
		TxData(7 downto 0) <= TxData(7 downto 0);
		TX_Req <= '0';
	end if;
	TX_Ack <= '0'; 
	-- Counter to devide the clk input. 
	if timecounter_pulse = '1' then 
		timecounter <= TIMECOUNTER_SIZE; 
	else 
		timecounter <= timecounter - 1; 
	end if; 
	case TxState is 
		when E_TxState_Waiting => 
			-- Req received and ready to transmit data. 
			if StartSending = '0' and TX_Req = '1' and sync_RTS(sync_RTS'high) = '0' then 
				-- Load the shiftregister 
				TXShiftRegister(1 to 8) <= TxData; 
				TX_Ack <= '1'; 
				StartSending <= '1'; 
			end if; 
		when E_TxState_Start | E_TxState_Data => 
			StartSending <= '0'; 
			-- The shiftregister can shift every timecounter_pulse. 
			-- This register runs on clk because it must be possible to load 
			-- external data assynchronous to timecounter_pulse. 
			if timecounter_pulse = '1' then 
				TXShiftRegister(TXShiftRegister'low) <= '1'; 
				TXShiftRegister(TXShiftRegister'low+1 to TXShiftRegister'high) <= TXShiftRegister(TXShiftRegister'low to TXShiftRegister'high-1); 
			end if; 
		when others => 
			StartSending <= '0'; 
	end case; 
end if; 
end process; 


process (clk,Reset) 
begin 
if Reset = '1' then 
	TXD <= '1'; 
	TxState <= E_TxState_Waiting; 
	bitcounter <= 0; 
elsif rising_edge(clk) then 
	if timecounter_pulse = '1' then 
		TxState <= nextTxState; 
		case nextTxState is 
			when E_TxState_Waiting => 
				TXD <= '1'; 
			when E_TxState_Start => 
				TXD <= '0'; 
			when E_TxState_Data => 
				TXD <= TXShiftRegister(8); 
				if bitcounter = 8 then 
					bitcounter <= 0; 
				else 
					bitcounter <= bitcounter + 1; 
				end if; 
			when others => 
				TXD <= '1'; 
		end case; 
	end if; 
end if; 
end process; 
end Behave; 

⌨️ 快捷键说明

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