Line 1... |
Line 1... |
--
|
--
|
-- UART receiver
|
-- UART receiver
|
--
|
--
|
-- Author: Sebastian Witt
|
-- Author: Sebastian Witt
|
-- Date: 27.01.2008
|
-- Date: 27.01.2008
|
-- Version: 1.1
|
-- Version: 1.2
|
--
|
--
|
-- This code is free software; you can redistribute it and/or
|
-- This code is free software; you can redistribute it and/or
|
-- modify it under the terms of the GNU Lesser General Public
|
-- modify it under the terms of the GNU Lesser General Public
|
-- License as published by the Free Software Foundation; either
|
-- License as published by the Free Software Foundation; either
|
-- version 2.1 of the License, or (at your option) any later version.
|
-- version 2.1 of the License, or (at your option) any later version.
|
Line 60... |
Line 60... |
CLEAR : in std_logic; -- Reset process
|
CLEAR : in std_logic; -- Reset process
|
D : in std_logic; -- Signal input
|
D : in std_logic; -- Signal input
|
Q : out std_logic -- Signal D was at least THRESHOLD samples high
|
Q : out std_logic -- Signal D was at least THRESHOLD samples high
|
);
|
);
|
end component;
|
end component;
|
|
component slib_input_filter is
|
|
generic (
|
|
SIZE : natural := 4 -- Filter counter size
|
|
);
|
|
port (
|
|
CLK : in std_logic; -- Clock
|
|
RST : in std_logic; -- Reset
|
|
CE : in std_logic; -- Clock enable
|
|
D : in std_logic; -- Signal input
|
|
Q : out std_logic -- Signal output
|
|
);
|
|
end component;
|
|
|
-- Counter
|
-- Counter
|
component slib_counter is
|
component slib_counter is
|
generic (
|
generic (
|
WIDTH : natural := 4 -- Counter width
|
WIDTH : natural := 4 -- Counter width
|
);
|
);
|
Line 83... |
Line 96... |
-- FSM
|
-- FSM
|
type state_type is (IDLE, START, DATA, PAR, STOP, MWAIT);
|
type state_type is (IDLE, START, DATA, PAR, STOP, MWAIT);
|
signal CState, NState : state_type;
|
signal CState, NState : state_type;
|
|
|
-- Signals
|
-- Signals
|
|
signal iBaudCount : std_logic_vector(3 downto 0); -- Baud counter output
|
signal iBaudCountClear : std_logic; -- Baud counter clear
|
signal iBaudCountClear : std_logic; -- Baud counter clear
|
signal iBaudStep : std_logic; -- Next symbol pulse
|
signal iBaudStep : std_logic; -- Next symbol pulse
|
signal iBaudStepD : std_logic; -- Next symbol pulse delayed by one clock
|
signal iBaudStepD : std_logic; -- Next symbol pulse delayed by one clock
|
signal iFilterClear : std_logic; -- Reset input filter
|
signal iFilterClear : std_logic; -- Reset input filter
|
signal iFSIN : std_logic; -- Filtered SIN
|
signal iFSIN : std_logic; -- Filtered SIN
|
|
signal iFStopBit : std_logic; -- Filtered SIN for stop bit detection
|
signal iParity : std_logic; -- Data parity
|
signal iParity : std_logic; -- Data parity
|
signal iParityReceived : std_logic; -- Parity received
|
signal iParityReceived : std_logic; -- Parity received
|
signal iDataCount : integer range 0 to 8; -- Data bit counter
|
signal iDataCount : integer range 0 to 8; -- Data bit counter
|
signal iDataCountInit : std_logic; -- Initialize data bit counter to word length
|
signal iDataCountInit : std_logic; -- Initialize data bit counter to word length
|
signal iDataCountFinish : std_logic; -- Data bit counter finished
|
signal iDataCountFinish : std_logic; -- Data bit counter finished
|
Line 112... |
Line 127... |
CLEAR => iBaudCountClear,
|
CLEAR => iBaudCountClear,
|
LOAD => '0',
|
LOAD => '0',
|
ENABLE => RXCLK,
|
ENABLE => RXCLK,
|
DOWN => '0',
|
DOWN => '0',
|
D => x"0",
|
D => x"0",
|
|
Q => iBaudCount,
|
OVERFLOW => iBaudStep
|
OVERFLOW => iBaudStep
|
);
|
);
|
|
|
-- Input filter
|
-- Input filter
|
RX_MVF: slib_mv_filter generic map (
|
RX_MVF: slib_mv_filter generic map (
|
Line 128... |
Line 144... |
CLEAR => iFilterClear,
|
CLEAR => iFilterClear,
|
D => SIN,
|
D => SIN,
|
Q => iFSIN
|
Q => iFSIN
|
);
|
);
|
|
|
|
-- Input filter for the stop bit
|
|
RX_IFSB: slib_input_filter generic map (
|
|
SIZE => 4
|
|
) port map (
|
|
CLK => CLK,
|
|
RST => RST,
|
|
CE => RXCLK,
|
|
D => SIN,
|
|
Q => iFStopBit
|
|
);
|
|
|
-- iBaudStepD
|
-- iBaudStepD
|
RX_IFC: process (CLK, RST)
|
RX_IFC: process (CLK, RST)
|
begin
|
begin
|
if (RST = '1') then
|
if (RST = '1') then
|
iBaudStepD <= '0';
|
iBaudStepD <= '0';
|
Line 181... |
Line 208... |
CState <= NState;
|
CState <= NState;
|
end if;
|
end if;
|
end process;
|
end process;
|
|
|
-- RX FSM
|
-- RX FSM
|
RX_FSM: process (CState, SIN, iFSIN, iBaudStep, iDataCountFinish, PEN, WLS, STB)
|
RX_FSM: process (CState, SIN, iFSIN, iFStopBit, iBaudStep, iBaudCount, iDataCountFinish, PEN, WLS, STB)
|
begin
|
begin
|
-- Defaults
|
-- Defaults
|
NState <= IDLE;
|
NState <= IDLE;
|
iBaudCountClear <= '0';
|
iBaudCountClear <= '0';
|
iDataCountInit <= '0';
|
iDataCountInit <= '0';
|
Line 217... |
Line 244... |
when PAR => if (iBaudStep = '1') then -- Wait for parity bit
|
when PAR => if (iBaudStep = '1') then -- Wait for parity bit
|
NState <= STOP;
|
NState <= STOP;
|
else
|
else
|
NState <= PAR;
|
NState <= PAR;
|
end if;
|
end if;
|
when STOP => if (iBaudStep = '1') then -- Wait for stop bit
|
when STOP => if (iBaudCount(3) = '1') then -- Wait for stop bit
|
if (iFSIN = '0') then -- No stop bit received
|
if (iFStopBit = '0') then -- No stop bit received
|
iRXFinished <= '1';
|
iRXFinished <= '1';
|
NState <= MWAIT;
|
NState <= MWAIT;
|
else
|
else
|
iRXFinished <= '1';
|
iRXFinished <= '1';
|
NState <= IDLE; -- Stop bit end
|
NState <= IDLE; -- Stop bit end
|
Line 266... |
Line 293... |
end if;
|
end if;
|
end if;
|
end if;
|
end process;
|
end process;
|
|
|
-- Framing error and break interrupt
|
-- Framing error and break interrupt
|
iNoStopReceived <= '1' when iFSIN = '0' and (CState = STOP) else '0';
|
iNoStopReceived <= '1' when iFStopBit = '0' and (CState = STOP) else '0';
|
iBI <= '1' when iDOUT = "00000000" and
|
iBI <= '1' when iDOUT = "00000000" and
|
iParityReceived = '0' and
|
iParityReceived = '0' and
|
iNoStopReceived = '1' else '0';
|
iNoStopReceived = '1' else '0';
|
iFE <= '1' when iNoStopReceived = '1' else '0';
|
iFE <= '1' when iNoStopReceived = '1' else '0';
|
|
|