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

📄 rx_uart_m8.vhd

📁 Lattice 超精简8位软核CPU--Mico8
💻 VHD
字号:
-----------------------------------------------------------------------
-- RX_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 RX UART
-- This will translate the incoming serial datastream to parallel data for a mico8. 
-- This peripheral also generates a Data_Ready signal when data has been received.
-- This peripheral can be used in combination with the mico8 Interrupt handler peripheral.
-- The generic parameter CLK_DIV is used to set the correct baudrate: 
-- baudrate = inputfreq/CLK_DIV
-- This is now fixed to 115200 buad and 50MHz clock. 
-- --------------------------------------------------------------------
--
-- Revision History :
-- --------------------------------------------------------------------
--   Ver  :| Author            :| Mod. Date :| Changes Made:
--   V1.0 :| G.M.              :| 14/01/08  :| 
-- ------------------------------------------------------------------------------------------- 

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


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

port 	( 
	Clk: 		in std_logic; 						-- System clock
	Reset: 		in std_logic; 						-- active low Reset
	RXD: 		in std_logic; 						-- Serial Receive data
	Data_Ready: 	out std_logic; 						-- RX data_Ready PULSE, indicates data has been receieved
	Data_Out: 	out std_logic_vector(7 downto 0)		   	-- RX parallel data out 
	); 
end RX_UART_M8; 


architecture behave of RX_UART_M8 is 
	constant BITCOUNTER_SIZE : integer := 7; 
	constant TIMECOUNTER_SIZE : integer := CLKFREQ/BAUDRATE-1; 
	constant HALF_TIMECOUNTER_SIZE : integer := TIMECOUNTER_SIZE/2 - 1; 
	type UARTState_type is (E_UARTState_Waiting, E_UARTState_Start, E_UARTState_Data, E_UARTState_Stop); 
	signal timecounter : integer range 0 to TIMECOUNTER_SIZE; 
	signal bitcounter : integer range 0 to 7; 
	signal Data_Out_reg : std_logic_vector(1 to 8); 
	signal UARTState, nextUARTState : UARTState_type; 
	signal timecounter_pulse : std_logic; 
	signal StartReceive : std_logic; 
	signal sync_RXD : std_logic_vector(2 downto 1); 
	signal faling_edge_RXD : boolean; 
	signal buffer_empty : boolean; 
	constant RX_Req : std_logic:= '1'; 				-- RX activate


attribute pgroup : string;
attribute pgroup of behave : architecture is "RX_UART";

	
begin 

process (UARTState, StartReceive, bitcounter) 
begin 
	nextUARTState <= UARTState; 
	case UARTState is 
		when E_UARTState_Waiting => 
			if StartReceive = '1' then 
				nextUARTState <= E_UARTState_Start; 
			end if; 
		when E_UARTState_Start => 
			nextUARTState <= E_UARTState_Data; 
		when E_UARTState_Data => 
			if bitcounter = 0 then 
				nextUARTState <= E_UARTState_Stop; 
			end if; 
		when E_UARTState_Stop => 
			nextUARTState <= E_UARTState_Waiting; 
		when others => 
			nextUARTState <= E_UARTState_Waiting; 
	end case; 
end process; 

-- sample signal into flipflops 
process (clk) 
begin 
	if rising_edge(clk) then 
		sync_RXD(sync_RXD'low) <= RXD; 
		sync_RXD(sync_RXD'high downto sync_RXD'low+1) <= sync_RXD(sync_RXD'high-1 downto sync_RXD'low); 
		
	end if; 
end process; 

faling_edge_RXD <= sync_RXD(sync_RXD'high-1) = '0' and sync_RXD(sync_RXD'high) = '1'; 
timecounter_pulse <= '1' when timecounter = 0 else '0'; 

process (clk, Reset) 
begin 
	if Reset = '1' then 
		timecounter <= TIMECOUNTER_SIZE; 
		StartReceive <= '0'; 
	elsif rising_edge(clk) then 
		-- endless timer with conditional preload (when detecting a startbit) 
		-- StartReceive indicates the detection of the startbit 
		if faling_edge_RXD and nextUARTState = E_UARTState_Waiting then
			 -- detect start bit 
			timecounter <= HALF_TIMECOUNTER_SIZE; 
			StartReceive <= '1'; 
		elsif timecounter = 0 then -- counter reset 
			timecounter <= TIMECOUNTER_SIZE; 
			StartReceive <= '0'; 
		else 
			timecounter <= timecounter - 1; -- count down 
		end if; 
	end if; 
end process; 

process (clk, Reset) 
begin 
	if Reset = '1' then 
		UARTState <= E_UARTState_Waiting; 
		Data_Out_reg <= (others => '0'); 
		bitcounter <= BITCOUNTER_SIZE; 
	elsif rising_edge(clk) then 
		if timecounter_pulse = '1' then 
			UARTState <= nextUARTState; 
			bitcounter <= BITCOUNTER_SIZE; 
			-- shift register 			
			Data_Out_reg(Data_Out_reg'low) <= sync_RXD(sync_RXD'high); 
			Data_Out_reg(Data_Out_reg'low+1 to Data_Out_reg'high) <= Data_Out_reg(Data_Out_reg'low to Data_Out_reg'high-1); 
			
			
			if UARTState = E_UARTState_Start or UARTState = E_UARTState_Data then 
				-- counter for the shiftregister 
				if bitcounter = 0 then 
					bitcounter <= BITCOUNTER_SIZE; 
				else 
					bitcounter <= bitcounter - 1; 
				end if; 
			end if; 
		end if; 
	end if; 
end process; 

process (clk, Reset) 
begin 
	if Reset = '1' then 
		buffer_empty <= TRUE; 
		Data_Ready <= '0'; 
		Data_Out <= (others => '0');
	elsif rising_edge(clk) then 
	if UARTState = E_UARTState_Data then 
		buffer_empty <= FALSE; 
	end if; 
	-- Output the shiftregister directly. 
	if timecounter_pulse = '1' and UARTState = E_UARTState_Stop then 
		Data_Out <= Data_Out_reg; 
	end if; 
	-- The shiftregister now contains the received byte. 
	-- => give an ack for 1 clock cycle (done with timecounter_pulse) 
	if RX_Req = '1' and not buffer_empty and UARTState = E_UARTState_Waiting then 
		Data_Ready <= '1'; 
		buffer_empty <= TRUE; 
	else 
		Data_Ready <= '0'; 
	end if; 
end if; 
end process; 

end Behave; 


⌨️ 快捷键说明

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