📄 rx_uart_m8.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 + -