OpenCores
URL https://opencores.org/ocsvn/uart16750/uart16750/trunk

Subversion Repositories uart16750

[/] [uart16750/] [trunk/] [rtl/] [vhdl/] [uart_receiver.vhd] - Diff between revs 11 and 17

Go to most recent revision | Only display areas with differences | Details | Blame | View Log

Rev 11 Rev 17
--
--
-- UART receiver
-- UART receiver
--
--
-- Author:   Sebastian Witt
-- Author:   Sebastian Witt
-- Date:     27.01.2008
-- Date:     27.01.2008
-- Version:  1.1
-- Version:  1.1
--
--
-- 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.
--
--
-- This code is distributed in the hope that it will be useful,
-- This code is distributed in the hope that it will be useful,
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-- Lesser General Public License for more details.
-- Lesser General Public License for more details.
--
--
-- You should have received a copy of the GNU Lesser General Public
-- You should have received a copy of the GNU Lesser General Public
-- License along with this library; if not, write to the
-- License along with this library; if not, write to the
-- Free Software  Foundation, Inc., 59 Temple Place, Suite 330,
-- Free Software  Foundation, Inc., 59 Temple Place, Suite 330,
-- Boston, MA  02111-1307  USA
-- Boston, MA  02111-1307  USA
--
--
 
 
LIBRARY IEEE;
LIBRARY IEEE;
USE IEEE.std_logic_1164.all;
USE IEEE.std_logic_1164.all;
USE IEEE.numeric_std.all;
USE IEEE.numeric_std.all;
 
 
-- Serial UART receiver
-- Serial UART receiver
entity uart_receiver is
entity uart_receiver is
    port (
    port (
        CLK         : in std_logic;                                 -- Clock
        CLK         : in std_logic;                                 -- Clock
        RST         : in std_logic;                                 -- Reset
        RST         : in std_logic;                                 -- Reset
        RXCLK       : in std_logic;                                 -- Receiver clock (16x baudrate)
        RXCLK       : in std_logic;                                 -- Receiver clock (16x baudrate)
        RXCLEAR     : in std_logic;                                 -- Reset receiver state
        RXCLEAR     : in std_logic;                                 -- Reset receiver state
        WLS         : in std_logic_vector(1 downto 0);              -- Word length select
        WLS         : in std_logic_vector(1 downto 0);              -- Word length select
        STB         : in std_logic;                                 -- Number of stop bits
        STB         : in std_logic;                                 -- Number of stop bits
        PEN         : in std_logic;                                 -- Parity enable
        PEN         : in std_logic;                                 -- Parity enable
        EPS         : in std_logic;                                 -- Even parity select
        EPS         : in std_logic;                                 -- Even parity select
        SP          : in std_logic;                                 -- Stick parity
        SP          : in std_logic;                                 -- Stick parity
        SIN         : in std_logic;                                 -- Receiver input
        SIN         : in std_logic;                                 -- Receiver input
        PE          : out std_logic;                                -- Parity error
        PE          : out std_logic;                                -- Parity error
        FE          : out std_logic;                                -- Framing error
        FE          : out std_logic;                                -- Framing error
        BI          : out std_logic;                                -- Break interrupt
        BI          : out std_logic;                                -- Break interrupt
        DOUT        : out std_logic_vector(7 downto 0);             -- Output data
        DOUT        : out std_logic_vector(7 downto 0);             -- Output data
        RXFINISHED  : out std_logic                                 -- Receiver operation finished
        RXFINISHED  : out std_logic                                 -- Receiver operation finished
    );
    );
end uart_receiver;
end uart_receiver;
 
 
architecture rtl of uart_receiver is
architecture rtl of uart_receiver is
    -- Majority voting logic
    -- Majority voting logic
    component slib_mv_filter is
    component slib_mv_filter is
        generic (
        generic (
            WIDTH       : natural := 4;
            WIDTH       : natural := 4;
            THRESHOLD   : natural := 10
            THRESHOLD   : natural := 10
        );
        );
        port (
        port (
            CLK         : in std_logic;                             -- Clock
            CLK         : in std_logic;                             -- Clock
            RST         : in std_logic;                             -- Reset
            RST         : in std_logic;                             -- Reset
            SAMPLE      : in std_logic;                             -- Clock enable for sample process
            SAMPLE      : in std_logic;                             -- Clock enable for sample process
            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;
    -- Counter
    -- Counter
    component slib_counter is
    component slib_counter is
        generic (
        generic (
            WIDTH       : natural := 4       -- Counter width
            WIDTH       : natural := 4       -- Counter width
        );
        );
        port (
        port (
            CLK         : in std_logic;      -- Clock
            CLK         : in std_logic;      -- Clock
            RST         : in std_logic;      -- Reset
            RST         : in std_logic;      -- Reset
            CLEAR       : in std_logic;      -- Clear counter register
            CLEAR       : in std_logic;      -- Clear counter register
            LOAD        : in std_logic;      -- Load counter register
            LOAD        : in std_logic;      -- Load counter register
            ENABLE      : in std_logic;      -- Enable count operation
            ENABLE      : in std_logic;      -- Enable count operation
            DOWN        : in std_logic;      -- Count direction down
            DOWN        : in std_logic;      -- Count direction down
            D           : in std_logic_vector(WIDTH-1 downto 0);    -- Load counter register input
            D           : in std_logic_vector(WIDTH-1 downto 0);    -- Load counter register input
            Q           : out std_logic_vector(WIDTH-1 downto 0);   -- Shift register output
            Q           : out std_logic_vector(WIDTH-1 downto 0);   -- Shift register output
            OVERFLOW    : out std_logic      -- Counter overflow
            OVERFLOW    : out std_logic      -- Counter overflow
        );
        );
    end component;
    end component;
 
 
    -- 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 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 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
    signal iRXFinished         : std_logic;                         -- Word received, output data valid
    signal iRXFinished         : std_logic;                         -- Word received, output data valid
    signal iFE                 : std_logic;                         -- Internal frame error
    signal iFE                 : std_logic;                         -- Internal frame error
    signal iBI                 : std_logic;                         -- Internal break interrupt
    signal iBI                 : std_logic;                         -- Internal break interrupt
    signal iNoStopReceived     : std_logic;                         -- No valid stop bit received
    signal iNoStopReceived     : std_logic;                         -- No valid stop bit received
    signal iDOUT               : std_logic_vector(7 downto 0);      -- Data output
    signal iDOUT               : std_logic_vector(7 downto 0);      -- Data output
 
 
begin
begin
 
 
    -- Baudrate counter: RXCLK/16
    -- Baudrate counter: RXCLK/16
    RX_BRC: slib_counter generic map (
    RX_BRC: slib_counter generic map (
                                WIDTH       => 4
                                WIDTH       => 4
                         ) port map (
                         ) port map (
                                CLK         => CLK,
                                CLK         => CLK,
                                RST         => RST,
                                RST         => RST,
                                CLEAR       => iBaudCountClear,
                                CLEAR       => iBaudCountClear,
                                LOAD        => '0',
                                LOAD        => '0',
                                ENABLE      => RXCLK,
                                ENABLE      => RXCLK,
                                DOWN        => '0',
                                DOWN        => '0',
                                D           => x"0",
                                D           => x"0",
                                OVERFLOW    => iBaudStep
                                OVERFLOW    => iBaudStep
                         );
                         );
 
 
    -- Input filter
    -- Input filter
    RX_MVF: slib_mv_filter generic map (
    RX_MVF: slib_mv_filter generic map (
                                WIDTH       => 4,
                                WIDTH       => 4,
                                THRESHOLD   => 10
                                THRESHOLD   => 10
                           ) port map (
                           ) port map (
                                CLK         => CLK,
                                CLK         => CLK,
                                RST         => RST,
                                RST         => RST,
                                SAMPLE      => RXCLK,
                                SAMPLE      => RXCLK,
                                CLEAR       => iFilterClear,
                                CLEAR       => iFilterClear,
                                D           => SIN,
                                D           => SIN,
                                Q           => iFSIN
                                Q           => iFSIN
                            );
                            );
 
 
    -- 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';
        elsif (CLK'event and CLK = '1') then
        elsif (CLK'event and CLK = '1') then
            iBaudStepD <= iBaudStep;
            iBaudStepD <= iBaudStep;
        end if;
        end if;
    end process;
    end process;
 
 
    iFilterClear <= iBaudStepD or iBaudCountClear;
    iFilterClear <= iBaudStepD or iBaudCountClear;
 
 
    -- Parity generation
    -- Parity generation
    RX_PAR: process (iDOUT, EPS)
    RX_PAR: process (iDOUT, EPS)
    begin
    begin
        iParity <= iDOUT(7) xor iDOUT(6) xor iDOUT(5) xor iDOUT(4) xor iDOUT(3) xor iDOUT(2) xor iDOUT(1) xor iDOUT(0) xor not EPS;
        iParity <= iDOUT(7) xor iDOUT(6) xor iDOUT(5) xor iDOUT(4) xor iDOUT(3) xor iDOUT(2) xor iDOUT(1) xor iDOUT(0) xor not EPS;
    end process;
    end process;
 
 
    -- Data bit capture
    -- Data bit capture
    RX_DATACOUNT: process (CLK, RST)
    RX_DATACOUNT: process (CLK, RST)
    begin
    begin
        if (RST = '1') then
        if (RST = '1') then
            iDataCount <= 0;
            iDataCount <= 0;
            iDOUT <= (others => '0');
            iDOUT <= (others => '0');
        elsif (CLK'event and CLK = '1') then
        elsif (CLK'event and CLK = '1') then
            if (iDataCountInit = '1') then
            if (iDataCountInit = '1') then
                iDataCount <= 0;
                iDataCount <= 0;
                iDOUT <= (others => '0');
                iDOUT <= (others => '0');
            else
            else
                if (iBaudStep = '1' and iDataCountFinish = '0') then
                if (iBaudStep = '1' and iDataCountFinish = '0') then
                    iDOUT(iDataCount) <= iFSIN;
                    iDOUT(iDataCount) <= iFSIN;
                    iDataCount <= iDataCount + 1;
                    iDataCount <= iDataCount + 1;
                end if;
                end if;
            end if;
            end if;
        end if;
        end if;
    end process;
    end process;
 
 
    iDataCountFinish <= '1' when (WLS = "00" and iDataCount = 5) or
    iDataCountFinish <= '1' when (WLS = "00" and iDataCount = 5) or
                                 (WLS = "01" and iDataCount = 6) or
                                 (WLS = "01" and iDataCount = 6) or
                                 (WLS = "10" and iDataCount = 7) or
                                 (WLS = "10" and iDataCount = 7) or
                                 (WLS = "11" and iDataCount = 8) else '0';
                                 (WLS = "11" and iDataCount = 8) else '0';
 
 
    -- FSM update process
    -- FSM update process
    RX_FSMUPDATE: process (CLK, RST)
    RX_FSMUPDATE: process (CLK, RST)
    begin
    begin
        if (RST = '1') then
        if (RST = '1') then
            CState <= IDLE;
            CState <= IDLE;
        elsif (CLK'event and CLK = '1') then
        elsif (CLK'event and CLK = '1') then
            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, iBaudStep, iDataCountFinish, PEN, WLS, STB)
    begin
    begin
        -- Defaults
        -- Defaults
        NState          <= IDLE;
        NState          <= IDLE;
        iBaudCountClear <= '0';
        iBaudCountClear <= '0';
        iDataCountInit  <= '0';
        iDataCountInit  <= '0';
        iRXFinished     <= '0';
        iRXFinished     <= '0';
 
 
        case CState is
        case CState is
            when IDLE   =>  if (SIN = '0') then                 -- Start detected
            when IDLE   =>  if (SIN = '0') then                 -- Start detected
                                NState <= START;
                                NState <= START;
                            end if;
                            end if;
                            iBaudCountClear <= '1';
                            iBaudCountClear <= '1';
                            iDataCountInit  <= '1';
                            iDataCountInit  <= '1';
            when START  =>  iDataCountInit  <= '1';
            when START  =>  iDataCountInit  <= '1';
                            if (iBaudStep = '1') then           -- Wait for start bit end
                            if (iBaudStep = '1') then           -- Wait for start bit end
                                if (iFSIN = '0') then
                                if (iFSIN = '0') then
                                    NState <= DATA;
                                    NState <= DATA;
                                end if;
                                end if;
                            else
                            else
                                NState <= START;
                                NState <= START;
                            end if;
                            end if;
            when DATA   =>  if (iDataCountFinish = '1') then    -- Received all data bits
            when DATA   =>  if (iDataCountFinish = '1') then    -- Received all data bits
                                if (PEN = '1') then
                                if (PEN = '1') then
                                    NState <= PAR;              -- Parity enabled
                                    NState <= PAR;              -- Parity enabled
                                else
                                else
                                    NState <= STOP;             -- No parity
                                    NState <= STOP;             -- No parity
                                end if;
                                end if;
                            else
                            else
                                NState <= DATA;
                                NState <= DATA;
                            end if;
                            end if;
            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 (iBaudStep = '1') then           -- Wait for stop bit
                                if (iFSIN = '0') then           -- No stop bit received
                                if (iFSIN = '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
                                end if;
                                end if;
                            else
                            else
                                NState <= STOP;
                                NState <= STOP;
                            end if;
                            end if;
            when MWAIT  =>  if (SIN = '0') then                 -- Wait for mark
            when MWAIT  =>  if (SIN = '0') then                 -- Wait for mark
                                NState <= MWAIT;
                                NState <= MWAIT;
                            end if;
                            end if;
            when others =>  null;
            when others =>  null;
        end case;
        end case;
    end process;
    end process;
 
 
    -- Check parity
    -- Check parity
    RX_PARCHECK: process (CLK, RST)
    RX_PARCHECK: process (CLK, RST)
    begin
    begin
        if (RST = '1') then
        if (RST = '1') then
            PE <= '0';
            PE <= '0';
            iParityReceived <= '0';
            iParityReceived <= '0';
        elsif (CLK'event and CLK = '1') then
        elsif (CLK'event and CLK = '1') then
            if (CState = PAR and iBaudStep = '1') then
            if (CState = PAR and iBaudStep = '1') then
                iParityReceived <= iFSIN;                       -- Received parity bit
                iParityReceived <= iFSIN;                       -- Received parity bit
            end if;
            end if;
 
 
            -- Check parity
            -- Check parity
            if (PEN = '1') then                                 -- Parity enabled
            if (PEN = '1') then                                 -- Parity enabled
                PE <= '0';
                PE <= '0';
                if (SP = '1') then                              -- Sticky parity
                if (SP = '1') then                              -- Sticky parity
                    if ((EPS xor iParityReceived) = '0') then
                    if ((EPS xor iParityReceived) = '0') then
                        PE <= '1';                              -- Parity error
                        PE <= '1';                              -- Parity error
                    end if;
                    end if;
                else
                else
                    if (iParity /= iParityReceived) then
                    if (iParity /= iParityReceived) then
                        PE <= '1';                              -- Parity error
                        PE <= '1';                              -- Parity error
                    end if;
                    end if;
                end if;
                end if;
            else
            else
                PE <= '0';                                      -- Parity disabled
                PE <= '0';                                      -- Parity disabled
                iParityReceived <= '0';
                iParityReceived <= '0';
            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 iFSIN = '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';
 
 
    -- Output signals
    -- Output signals
    DOUT <= iDOUT;
    DOUT <= iDOUT;
    BI   <= iBI;
    BI   <= iBI;
    FE   <= iFE;
    FE   <= iFE;
    RXFINISHED <= iRXFinished;
    RXFINISHED <= iRXFinished;
 
 
end rtl;
end rtl;
 
 
 
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.