1 -- `Deep Thought', a softcore CPU implemented on a FPGA
3 -- Copyright (C) 2010 Markus Hofstaetter <markus.manrow@gmx.at>
4 -- Copyright (C) 2010 Martin Perner <e0725782@student.tuwien.ac.at>
5 -- Copyright (C) 2010 Stefan Rebernig <stefan.rebernig@gmail.com>
6 -- Copyright (C) 2010 Manfred Schwarz <e0725898@student.tuwien.ac.at>
7 -- Copyright (C) 2010 Bernhard Urban <lewurm@gmail.com>
9 -- This program is free software: you can redistribute it and/or modify
10 -- it under the terms of the GNU General Public License as published by
11 -- the Free Software Foundation, either version 3 of the License, or
12 -- (at your option) any later version.
14 -- This program is distributed in the hope that it will be useful,
15 -- but WITHOUT ANY WARRANTY; without even the implied warranty of
16 -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 -- GNU General Public License for more details.
19 -- You should have received a copy of the GNU General Public License
20 -- along with this program. If not, see <http://www.gnu.org/licenses/>.
23 use IEEE.std_logic_1164.all;
24 use IEEE.numeric_std.all;
26 use work.extension_uart_pkg.all;
28 use work.common_pkg.all;
29 use work.core_pkg.all;
31 architecture beh of rs232_rx is
32 -- definierern der intern verwendeten Signale
33 type STATE_TYPE is (IDLE, READ_START, READ_BIT, READ_STOP);
34 signal state, state_next : STATE_TYPE;
35 signal bus_rx_last, bus_rx_int, new_rx_data_nxt : std_logic := '0';
36 signal cnt, cnt_next : integer := 0;
37 signal baud_cnt, baud_cnt_next : std_logic_vector(BAUD_RATE_WIDTH-1 downto 0);
38 signal rx_data_int, rx_data_nxt, rx_data_res_int, rx_data_res_nxt : uart_data;
39 signal sync : std_logic_vector(1 to SYNC_STAGES);
40 signal bus_rx : std_logic;
43 -- syncronisierungs Prozess
44 rs232_rx_syn : process(sys_clk, sys_res_n)
46 if (sys_res_n = RESET_VALUE) then
50 rx_data_res_int <= x"00";
51 rx_data_int <= (others => '0');
52 baud_cnt <= (others => '0');
53 sync <= (others => '1');
55 elsif rising_edge(sys_clk) then
56 -- sync Zustand, uebernehmen der next-Signale
59 baud_cnt <= baud_cnt_next;
60 bus_rx_int <= bus_rx_last;
61 rx_data_int <= rx_data_nxt;
62 rx_data_res_int <= rx_data_res_nxt;
63 new_rx_data <= new_rx_data_nxt;
65 sync(1) <= bus_rx_unsync;
66 for i in 2 to SYNC_STAGES loop
67 sync(i) <= sync(i - 1);
73 -- setzen des Ausgangsignals, Rxt-Daten
74 rx_data <= rx_data_res_int;
75 bus_rx <= sync(SYNC_STAGES);
77 -- Zustandsmaschienen Prozess
78 rs232_states : process(sys_clk,state,cnt, bus_rx, bus_rx_last, baud_cnt,bus_rx_int,bd_rate)
80 state_next <= state; -- mal schauen ob des so geht
81 bus_rx_last <= bus_rx; -- mal schauen ob des so geht
84 -- nach einem Wechsel der rxt-Leitung von 1 auf 0 wird der einlese Vorgang
85 -- getriggert mithilfe eines Zustandsuebergangs von IDLE auf READ_START
86 if (bus_rx_last = '0' and bus_rx_int = '1') then
87 state_next <= READ_START;
90 -- im READ_START Zustand wird eine halbe Bitzeit gewartet. Liegt auf der rxt-Leitung
91 -- immer noch die 0 an so wird mit deim Lesebvorgang mit einem Zustandswechsel von
92 -- READ_START nach READ_BIT vorgefahren, wenn eine 1 anliegt wird abgebrochen und
93 -- wieder nach IDLE gewechselt
95 if (bus_rx = '0' and baud_cnt(BAUD_RATE_WIDTH-2 downto 0) = bd_rate(BAUD_RATE_WIDTH-1 downto 1)) then
96 state_next <= READ_BIT;
97 elsif (bus_rx = '1' and baud_cnt(BAUD_RATE_WIDTH-2 downto 0) = bd_rate(BAUD_RATE_WIDTH-1 downto 1)) then
101 -- hier werden mit Hilfe eines Countersignals 8 Datenbits im Abstand der eingestellten
102 -- Bitzeit eingelesen und gespeichert.
103 -- Nach beendigung wird in den Zustand READ_STOP gewechselt.
104 if (cnt = 7 and baud_cnt = bd_rate) then
105 state_next <= READ_STOP;
107 state_next <= READ_BIT;
110 -- hier wird nur noch auf das Stopbit abgewartet und gelesen um den
111 -- Lesevorgang koerrekt zu beenden
112 if baud_cnt = bd_rate then
119 rs232_rx_baud : process(state, cnt, bus_rx, baud_cnt, rx_data_int, rx_data_res_int, bd_rate)
121 -- Signale halten um Latches zu vermeiden
123 new_rx_data_nxt <= '0';
124 baud_cnt_next <= baud_cnt;
125 rx_data_nxt <= rx_data_int;
126 rx_data_res_nxt <= rx_data_res_int;
127 -- Statewechesel wie obenbeschrieben
131 baud_cnt_next <= (others =>'0'); --0;
133 -- baut_cnt zyklenweise erhoehen bis es einer halben Bitzeit entspricht
134 -- anschliessend zuruecksetzten
135 baud_cnt_next <= std_logic_vector(unsigned(baud_cnt) + 1);
136 if baud_cnt(BAUD_RATE_WIDTH-2 downto 0) = bd_rate(BAUD_RATE_WIDTH-1 downto 1) then
137 baud_cnt_next <= (others => '0');
138 rx_data_nxt <= x"00";
141 -- baut_cnt zyklenweise erhoehen bis es einer Bitzeit entspricht
142 -- anschliessend zuruecksetzen
143 -- Zustand der rxt-Leitung im rx_data_nxt abspeichern
144 baud_cnt_next <= std_logic_vector(unsigned(baud_cnt) + 1);
145 if baud_cnt = bd_rate then
146 baud_cnt_next <= (others => '0');
148 rx_data_nxt(cnt) <= bus_rx;
151 -- baut_cnt zyklenweise erhoehen bis es einer Bitzeit entspricht
152 -- anschliessend zuruecksetzen
154 -- Signal fuer neue rx-Daten setzen um die send_logic zu aktivieren
156 baud_cnt_next <= std_logic_vector(unsigned(baud_cnt) + 1);
157 if baud_cnt = bd_rate then
158 baud_cnt_next <= (others => '0');
159 new_rx_data_nxt <= bus_rx;
160 rx_data_res_nxt <= rx_data_int;
165 end architecture beh;