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

Subversion Repositories rs232_interface

[/] [rs232_interface/] [trunk/] [uart.vhd] - Diff between revs 11 and 18

Only display areas with differences | Details | Blame | View Log

Rev 11 Rev 18
----------------------------------------------------------------------------------
----------------------------------------------------------------------------------
-- Creation Date: 21:12:48 05/06/2010 
-- Creation Date: 21:12:48 05/06/2010 
-- Module Name: RS232/UART Interface - Behavioral
-- Module Name: RS232/UART Interface - Behavioral
-- Used TAB of 4 Spaces
-- Used TAB of 4 Spaces
----------------------------------------------------------------------------------
----------------------------------------------------------------------------------
library IEEE;
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
 
 
entity uart is
entity uart is
generic (
generic (
        CLK_FREQ        : integer := 50;                -- Main frequency (MHz)
        CLK_FREQ        : integer := 50;                -- Main frequency (MHz)
        SER_FREQ        : integer := 9600               -- Baud rate (bps)
        SER_FREQ        : integer := 9600               -- Baud rate (bps)
);
);
port (
port (
        -- Control
        -- Control
        clk                     : in    std_logic;              -- Main clock
        clk                     : in    std_logic;              -- Main clock
        rst                     : in    std_logic;              -- Main reset
        rst                     : in    std_logic;              -- Main reset
        -- External Interface
        -- External Interface
        rx                      : in    std_logic;              -- RS232 received serial data
        rx                      : in    std_logic;              -- RS232 received serial data
        tx                      : out   std_logic;              -- RS232 transmitted serial data
        tx                      : out   std_logic;              -- RS232 transmitted serial data
        -- RS232/UART Configuration
        -- RS232/UART Configuration
        par_en          : in    std_logic;              -- Parity bit enable
        par_en          : in    std_logic;              -- Parity bit enable
        -- uPC Interface
        -- uPC Interface
        tx_req          : in    std_logic;                                              -- Request SEND of data
        tx_req          : in    std_logic;                                              -- Request SEND of data
        tx_end          : out   std_logic;                                              -- Data SENDED
        tx_end          : out   std_logic;                                              -- Data SENDED
        tx_data         : in    std_logic_vector(7 downto 0);    -- Data to transmit
        tx_data         : in    std_logic_vector(7 downto 0);    -- Data to transmit
        rx_ready        : out   std_logic;                                              -- Received data ready to uPC read
        rx_ready        : out   std_logic;                                              -- Received data ready to uPC read
        rx_data         : out   std_logic_vector(7 downto 0)     -- Received data 
        rx_data         : out   std_logic_vector(7 downto 0)     -- Received data 
);
);
end uart;
end uart;
 
 
architecture Behavioral of uart is
architecture Behavioral of uart is
 
 
        -- Constants
        -- Constants
        constant UART_IDLE      :       std_logic := '1';
        constant UART_IDLE      :       std_logic := '1';
        constant UART_START     :       std_logic := '0';
        constant UART_START     :       std_logic := '0';
        constant PARITY_EN      :       std_logic := '1';
        constant PARITY_EN      :       std_logic := '1';
        constant RST_LVL        :       std_logic := '1';
        constant RST_LVL        :       std_logic := '1';
 
 
        -- Types
        -- Types
        type state is (idle,data,parity,stop1,stop2);                   -- Stop1 and Stop2 are inter frame gap signals
        type state is (idle,data,parity,stop1,stop2);                   -- Stop1 and Stop2 are inter frame gap signals
 
 
        -- RX Signals
        -- RX Signals
        signal rx_fsm           :       state;                                                  -- Control of reception
        signal rx_fsm           :       state;                                                  -- Control of reception
        signal rx_clk_en        :       std_logic;                                              -- Received clock enable
        signal rx_clk_en        :       std_logic;                                              -- Received clock enable
        signal rx_rcv_init      :       std_logic;                                              -- Start of reception
        signal rx_rcv_init      :       std_logic;                                              -- Start of reception
        signal rx_par_bit       :       std_logic;                                              -- Calculated Parity bit
        signal rx_par_bit       :       std_logic;                                              -- Calculated Parity bit
        signal rx_data_deb      :       std_logic;                                              -- Debounce RX data
        signal rx_data_deb      :       std_logic;                                              -- Debounce RX data
        signal rx_data_tmp      :       std_logic_vector(7 downto 0);    -- Serial to parallel converter
        signal rx_data_tmp      :       std_logic_vector(7 downto 0);    -- Serial to parallel converter
        signal rx_data_cnt      :       std_logic_vector(2 downto 0);    -- Count received bits
        signal rx_data_cnt      :       std_logic_vector(2 downto 0);    -- Count received bits
 
 
        -- TX Signals
        -- TX Signals
        signal tx_fsm           :       state;                                                  -- Control of transmission
        signal tx_fsm           :       state;                                                  -- Control of transmission
        signal tx_clk_en        :       std_logic;                                              -- Transmited clock enable
        signal tx_clk_en        :       std_logic;                                              -- Transmited clock enable
        signal tx_par_bit       :       std_logic;                                              -- Calculated Parity bit
        signal tx_par_bit       :       std_logic;                                              -- Calculated Parity bit
        signal tx_data_tmp      :       std_logic_vector(7 downto 0);    -- Parallel to serial converter
        signal tx_data_tmp      :       std_logic_vector(7 downto 0);    -- Parallel to serial converter
        signal tx_data_cnt      :       std_logic_vector(2 downto 0);    -- Count transmited bits
        signal tx_data_cnt      :       std_logic_vector(2 downto 0);    -- Count transmited bits
 
 
begin
begin
 
 
        tx_clk_gen:process(clk)
        tx_clk_gen:process(clk)
                variable counter        :       integer range 0 to conv_integer((CLK_FREQ*1_000_000)/SER_FREQ-1);
                variable counter        :       integer range 0 to conv_integer((CLK_FREQ*1_000_000)/SER_FREQ-1);
        begin
        begin
                if clk'event and clk = '1' then
                if clk'event and clk = '1' then
                        -- Normal Operation
                        -- Normal Operation
                        if counter = (CLK_FREQ*1_000_000)/SER_FREQ-1 then
                        if counter = (CLK_FREQ*1_000_000)/SER_FREQ-1 then
                                tx_clk_en       <=      '1';
                                tx_clk_en       <=      '1';
                                counter         :=      0;
                                counter         :=      0;
                        else
                        else
                                tx_clk_en       <=      '0';
                                tx_clk_en       <=      '0';
                                counter         :=      counter + 1;
                                counter         :=      counter + 1;
                        end if;
                        end if;
                        -- Reset condition
                        -- Reset condition
                        if rst = RST_LVL then
                        if rst = RST_LVL then
                                tx_clk_en       <=      '0';
                                tx_clk_en       <=      '0';
                                counter         :=      0;
                                counter         :=      0;
                        end if;
                        end if;
                end if;
                end if;
        end process;
        end process;
 
 
        tx_proc:process(clk)
        tx_proc:process(clk)
                variable data_cnt       : std_logic_vector(2 downto 0);
                variable data_cnt       : std_logic_vector(2 downto 0);
        begin
        begin
                if clk'event and clk = '1' then
                if clk'event and clk = '1' then
                        if tx_clk_en = '1' then
                        if tx_clk_en = '1' then
                                -- Default values
                                -- Default values
                                tx_end                                  <=      '0';
                                tx_end                                  <=      '0';
                                tx                                              <=      UART_IDLE;
                                tx                                              <=      UART_IDLE;
                                -- FSM description
                                -- FSM description
                                case tx_fsm is
                                case tx_fsm is
                                        -- Wait to transfer data
                                        -- Wait to transfer data
                                        when idle =>
                                        when idle =>
                                                -- Send Init Bit
                                                -- Send Init Bit
                                                if tx_req = '1' then
                                                if tx_req = '1' then
                                                        tx                      <=      UART_START;
                                                        tx                      <=      UART_START;
                                                        tx_data_tmp     <=      tx_data;
                                                        tx_data_tmp     <=      tx_data;
                                                        tx_fsm          <=      data;
                                                        tx_fsm          <=      data;
                                                        tx_data_cnt     <=      (others=>'1');
                                                        tx_data_cnt     <=      (others=>'1');
                                                        tx_par_bit      <=      '0';
                                                        tx_par_bit      <=      '0';
                                                end if;
                                                end if;
                                        -- Data receive
                                        -- Data receive
                                        when data =>
                                        when data =>
                                                tx                              <=      tx_data_tmp(0);
                                                tx                              <=      tx_data_tmp(0);
                                                tx_par_bit              <=      tx_par_bit xor tx_data_tmp(0);
                                                tx_par_bit              <=      tx_par_bit xor tx_data_tmp(0);
                                                if tx_data_cnt = 0 then
                                                if tx_data_cnt = 0 then
                                                        if par_en = PARITY_EN then
                                                        if par_en = PARITY_EN then
                                                                tx_fsm  <=      parity;
                                                                tx_fsm  <=      parity;
                                                        else
                                                        else
                                                                tx_fsm  <=      stop1;
                                                                tx_fsm  <=      stop1;
                                                        end if;
                                                        end if;
                                                        tx_data_cnt     <=      (others=>'1');
                                                        tx_data_cnt     <=      (others=>'1');
                                                else
                                                else
                                                        tx_data_tmp     <=      '0' & tx_data_tmp(7 downto 1);
                                                        tx_data_tmp     <=      '0' & tx_data_tmp(7 downto 1);
                                                        tx_data_cnt     <=      tx_data_cnt - 1;
                                                        tx_data_cnt     <=      tx_data_cnt - 1;
                                                end if;
                                                end if;
                                        when parity =>
                                        when parity =>
                                                tx                              <=      tx_par_bit;
                                                tx                              <=      tx_par_bit;
                                                tx_fsm                  <=      stop1;
                                                tx_fsm                  <=      stop1;
                                        -- End of communication
                                        -- End of communication
                                        when stop1 =>
                                        when stop1 =>
                                                -- Send Stop Bit
                                                -- Send Stop Bit
                                                tx                              <=      UART_IDLE;
                                                tx                              <=      UART_IDLE;
                                                tx_fsm                  <=      stop2;
                                                tx_fsm                  <=      stop2;
                                        when stop2 =>
                                        when stop2 =>
                                                -- Send Stop Bit
                                                -- Send Stop Bit
                                                tx_end                  <=      '1';
                                                tx_end                  <=      '1';
                                                tx                              <=      UART_IDLE;
                                                tx                              <=      UART_IDLE;
                                                tx_fsm                  <=      idle;
                                                tx_fsm                  <=      idle;
                                        -- Invalid States
                                        -- Invalid States
                                        when others => null;
                                        when others => null;
                                end case;
                                end case;
                                -- Reset condition
                                -- Reset condition
                                if rst = RST_LVL then
                                if rst = RST_LVL then
                                        tx_fsm                          <=      idle;
                                        tx_fsm                          <=      idle;
                                        tx_par_bit                      <=      '0';
                                        tx_par_bit                      <=      '0';
                                        tx_data_tmp                     <=      (others=>'0');
                                        tx_data_tmp                     <=      (others=>'0');
                                        tx_data_cnt                     <=      (others=>'0');
                                        tx_data_cnt                     <=      (others=>'0');
                                end if;
                                end if;
                        end if;
                        end if;
                end if;
                end if;
        end process;
        end process;
 
 
        rx_debounceer:process(clk)
        rx_debounceer:process(clk)
                variable deb_buf        :       std_logic_vector(3 downto 0);
                variable deb_buf        :       std_logic_vector(3 downto 0);
        begin
        begin
                if clk'event and clk = '1' then
                if clk'event and clk = '1' then
                        -- Debounce logic
                        -- Debounce logic
                        if deb_buf = "0000" then
                        if deb_buf = "0000" then
                                rx_data_deb             <=      '0';
                                rx_data_deb             <=      '0';
                        elsif deb_buf = "1111" then
                        elsif deb_buf = "1111" then
                                rx_data_deb             <=      '1';
                                rx_data_deb             <=      '1';
                        end if;
                        end if;
                        -- Data storage to debounce
                        -- Data storage to debounce
                        deb_buf                         :=      deb_buf(2 downto 0) & rx;
                        deb_buf                         :=      deb_buf(2 downto 0) & rx;
                end if;
                end if;
        end process;
        end process;
 
 
        rx_start_detect:process(clk)
        rx_start_detect:process(clk)
                variable rx_data_old    :       std_logic;
                variable rx_data_old    :       std_logic;
        begin
        begin
                if clk'event and clk = '1' then
                if clk'event and clk = '1' then
                        -- Falling edge detection
                        -- Falling edge detection
                        if rx_data_old = '1' and rx_data_deb = '0' then
                        if rx_data_old = '1' and rx_data_deb = '0' and rx_fsm = idle then
                                rx_rcv_init             <=      '1';
                                rx_rcv_init             <=      '1';
                        else
                        else
                                rx_rcv_init             <=      '0';
                                rx_rcv_init             <=      '0';
                        end if;
                        end if;
                        -- Default assignments
                        -- Default assignments
                        rx_data_old                     :=      rx_data_deb;
                        rx_data_old                     :=      rx_data_deb;
                        -- Reset condition
                        -- Reset condition
                        if rst = RST_LVL then
                        if rst = RST_LVL then
                                rx_data_old             :=      '0';
                                rx_data_old             :=      '0';
                                rx_rcv_init             <=      '0';
                                rx_rcv_init             <=      '0';
                        end if;
                        end if;
                end if;
                end if;
        end process;
        end process;
 
 
 
 
        rx_clk_gen:process(clk)
        rx_clk_gen:process(clk)
                variable counter        :       integer range 0 to conv_integer((CLK_FREQ*1_000_000)/SER_FREQ-1);
                variable counter        :       integer range 0 to conv_integer((CLK_FREQ*1_000_000)/SER_FREQ-1);
        begin
        begin
                if clk'event and clk = '1' then
                if clk'event and clk = '1' then
                        -- Normal Operation
                        -- Normal Operation
                        if counter = (CLK_FREQ*1_000_000)/SER_FREQ-1 or rx_rcv_init = '1' then
                        if counter = (CLK_FREQ*1_000_000)/SER_FREQ-1 or rx_rcv_init = '1' then
                                rx_clk_en       <=      '1';
                                rx_clk_en       <=      '1';
                                counter         :=      0;
                                counter         :=      0;
                        else
                        else
                                rx_clk_en       <=      '0';
                                rx_clk_en       <=      '0';
                                counter         :=      counter + 1;
                                counter         :=      counter + 1;
                        end if;
                        end if;
                        -- Reset condition
                        -- Reset condition
                        if rst = RST_LVL then
                        if rst = RST_LVL then
                                rx_clk_en       <=      '0';
                                rx_clk_en       <=      '0';
                                counter         :=      0;
                                counter         :=      0;
                        end if;
                        end if;
                end if;
                end if;
        end process;
        end process;
 
 
        rx_proc:process(clk)
        rx_proc:process(clk)
        begin
        begin
                if clk'event and clk = '1' then
                if clk'event and clk = '1' then
                        -- Default values
                        -- Default values
                        rx_ready                <=      '0';
                        rx_ready                <=      '0';
                        -- Enable on UART rate
                        -- Enable on UART rate
                        if rx_clk_en = '1' then
                        if rx_clk_en = '1' then
                                -- FSM description
                                -- FSM description
                                case rx_fsm is
                                case rx_fsm is
                                        -- Wait to transfer data
                                        -- Wait to transfer data
                                        when idle =>
                                        when idle =>
                                                if rx_data_deb = UART_START then
                                                if rx_data_deb = UART_START then
                                                        rx_fsm          <=      data;
                                                        rx_fsm          <=      data;
                                                end if;
                                                end if;
                                                rx_par_bit              <=      '0';
                                                rx_par_bit              <=      '0';
                                                rx_data_cnt             <=      (others=>'0');
                                                rx_data_cnt             <=      (others=>'0');
                                        -- Data receive
                                        -- Data receive
                                        when data =>
                                        when data =>
                                                -- Check data to generate parity
                                                -- Check data to generate parity
                                                if par_en = PARITY_EN then
                                                if par_en = PARITY_EN then
                                                        rx_par_bit              <=      rx_par_bit xor rx;
                                                        rx_par_bit              <=      rx_par_bit xor rx;
                                                end if;
                                                end if;
 
 
                                                if rx_data_cnt = 7 then
                                                if rx_data_cnt = 7 then
                                                        -- Data path
                                                        -- Data path
                                                        rx_data(7)              <=      rx;
                                                        rx_data(7)              <=      rx;
                                                        for i in 0 to 6 loop
                                                        for i in 0 to 6 loop
                                                                rx_data(i)      <=      rx_data_tmp(6-i);
                                                                rx_data(i)      <=      rx_data_tmp(6-i);
                                                        end loop;
                                                        end loop;
 
 
                                                        -- With parity verification
                                                        -- With parity verification
                                                        if par_en = PARITY_EN then
                                                        if par_en = PARITY_EN then
                                                                rx_fsm          <=      parity;
                                                                rx_fsm          <=      parity;
                                                        -- Without parity verification
                                                        -- Without parity verification
                                                        else
                                                        else
                                                                rx_ready        <=      '1';
                                                                rx_ready        <=      '1';
                                                                rx_fsm          <=      idle;
                                                                rx_fsm          <=      idle;
                                                        end if;
                                                        end if;
                                                else
                                                else
                                                        rx_data_tmp             <=      rx_data_tmp(6 downto 0) & rx;
                                                        rx_data_tmp             <=      rx_data_tmp(6 downto 0) & rx;
                                                        rx_data_cnt             <=      rx_data_cnt + 1;
                                                        rx_data_cnt             <=      rx_data_cnt + 1;
                                                end if;
                                                end if;
                                        when parity =>
                                        when parity =>
                                                -- Check received parity
                                                -- Check received parity
                                                rx_fsm                          <=      idle;
                                                rx_fsm                          <=      idle;
                                                if rx_par_bit = rx then
                                                if rx_par_bit = rx then
                                                        rx_ready                <=      '1';
                                                        rx_ready                <=      '1';
                                                end if;
                                                end if;
                                        when others => null;
                                        when others => null;
                                end case;
                                end case;
                                -- Reset condition
                                -- Reset condition
                                if rst = RST_LVL then
                                if rst = RST_LVL then
                                        rx_fsm                  <=      idle;
                                        rx_fsm                  <=      idle;
                                        rx_ready                <=      '0';
                                        rx_ready                <=      '0';
                                        rx_data                 <=      (others=>'0');
                                        rx_data                 <=      (others=>'0');
                                        rx_data_tmp             <=      (others=>'0');
                                        rx_data_tmp             <=      (others=>'0');
                                        rx_data_cnt             <=      (others=>'0');
                                        rx_data_cnt             <=      (others=>'0');
                                end if;
                                end if;
                        end if;
                        end if;
                end if;
                end if;
        end process;
        end process;
 
 
end Behavioral;
end Behavioral;
 
 
 
 

powered by: WebSVN 2.1.0

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