copyleft: gplv3 added and set repo to public
[calu.git] / cpu / src / rs232_rx_arc.vhd
index 1bdc472806753a562cbf6c9c933d4f3969bcb9dc..fbd06416741a95f8c134c906c6712b4626050744 100755 (executable)
@@ -1,13 +1,23 @@
----------------------------------------------------------------------------------
--- Filename : rs232_rx_arc.vhd
--- ========== 
--- 
--- Beschreibung : Empfang von Daten ueber die RS232 Schnittstelle
--- ==============
+--   `Deep Thought', a softcore CPU implemented on a FPGA
 --
--- Autoren : Martin Perner, Schwarz Manfred
--- =========
-----------------------------------------------------------------------------------
+--  Copyright (C) 2010 Markus Hofstaetter <markus.manrow@gmx.at>
+--  Copyright (C) 2010 Martin Perner <e0725782@student.tuwien.ac.at>
+--  Copyright (C) 2010 Stefan Rebernig <stefan.rebernig@gmail.com>
+--  Copyright (C) 2010 Manfred Schwarz <e0725898@student.tuwien.ac.at>
+--  Copyright (C) 2010 Bernhard Urban <lewurm@gmail.com>
+--
+--  This program is free software: you can redistribute it and/or modify
+--  it under the terms of the GNU General Public License as published by
+--  the Free Software Foundation, either version 3 of the License, or
+--  (at your option) any later version.
+--
+--  This program is distributed in the hope that it will be useful,
+--  but WITHOUT ANY WARRANTY; without even the implied warranty of
+--  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+--  GNU General Public License for more details.
+--
+--  You should have received a copy of the GNU General Public License
+--  along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
 library IEEE;
 use IEEE.std_logic_1164.all;
@@ -20,12 +30,14 @@ use work.core_pkg.all;
 
 architecture beh of rs232_rx is
        -- definierern der intern verwendeten Signale
-       type STATE_TYPE is (IDLE, READ_START, READ_BIT, READ_STOP, POST_STOP);
+       type STATE_TYPE is (IDLE, READ_START, READ_BIT, READ_STOP);
        signal state, state_next : STATE_TYPE;
        signal bus_rx_last, bus_rx_int, new_rx_data_nxt : std_logic := '0';
        signal cnt, cnt_next : integer := 0;
        signal baud_cnt, baud_cnt_next : std_logic_vector(BAUD_RATE_WIDTH-1 downto 0);
        signal rx_data_int, rx_data_nxt, rx_data_res_int, rx_data_res_nxt : uart_data;
+       signal sync : std_logic_vector(1 to SYNC_STAGES);
+       signal bus_rx : std_logic;
        
 begin
        -- syncronisierungs Prozess
@@ -36,7 +48,9 @@ begin
                        state <= IDLE;
                        cnt <= 0;
                        rx_data_res_int <= x"00";
+                       rx_data_int <= (others => '0');
                        baud_cnt <= (others => '0');
+                       sync <= (others => '1');
 
                elsif rising_edge(sys_clk) then
                        -- sync Zustand, uebernehmen der next-Signale
@@ -48,11 +62,17 @@ begin
                        rx_data_res_int <= rx_data_res_nxt;
                        new_rx_data <= new_rx_data_nxt;
 
+                       sync(1) <= bus_rx_unsync;
+                       for i in 2 to SYNC_STAGES loop
+                               sync(i) <= sync(i - 1);
+                       end loop;
+                       
                end if;
        end process;
 
        -- setzen des Ausgangsignals, Rxt-Daten
        rx_data <= rx_data_res_int;
+       bus_rx <= sync(SYNC_STAGES);
 
        -- Zustandsmaschienen Prozess
        rs232_states : process(sys_clk,state,cnt, bus_rx, bus_rx_last, baud_cnt,bus_rx_int,bd_rate)
@@ -89,14 +109,7 @@ begin
                        when READ_STOP =>
                                -- hier wird nur noch auf das Stopbit abgewartet und gelesen um den
                                -- Lesevorgang koerrekt zu beenden
-                               if baud_cnt = bd_rate and bus_rx = '1' then
-                                       state_next <= POST_STOP;
-                               elsif baud_cnt = bd_rate and bus_rx = '0' then
-                                       state_next <= IDLE;
-                               end if;
-                       when POST_STOP =>
-                               -- hier wird nur noch eine halbe Bitzeit gewartet
-                               if baud_cnt(BAUD_RATE_WIDTH-2 downto 0) = bd_rate(BAUD_RATE_WIDTH-1 downto 1) then
+                               if baud_cnt = bd_rate then
                                        state_next <= IDLE;
                                end if;
                end case;
@@ -114,6 +127,7 @@ begin
                -- Statewechesel wie obenbeschrieben
                case state is
                        when IDLE =>
+                               cnt_next <= 0;
                                baud_cnt_next <= (others =>'0'); --0;
                        when READ_START =>
                                -- baut_cnt zyklenweise erhoehen bis es einer halben Bitzeit entspricht
@@ -142,14 +156,8 @@ begin
                                baud_cnt_next <= std_logic_vector(unsigned(baud_cnt) + 1);
                                if baud_cnt = bd_rate then 
                                        baud_cnt_next <= (others => '0');
-                               end if;
-                       when POST_STOP =>
-                               --halbe bitzeit wartenr auf counter warten
-                               baud_cnt_next <= baud_cnt + 1;
-                               if baud_cnt(BAUD_RATE_WIDTH-2 downto 0) = bd_rate(BAUD_RATE_WIDTH-1 downto 1) then 
-                                       new_rx_data_nxt <= '1'; 
+                                       new_rx_data_nxt <= bus_rx;
                                        rx_data_res_nxt <= rx_data_int;
-                                       baud_cnt_next <= (others => '0');
                                end if;
                end case;
        end process;