----------------------------------------------------------------------------------
--- 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;
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
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
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)
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;
-- 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
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;