1 ---------------------------------------------------------------------------------
2 -- Filename : rs232_rx_arc.vhd
5 -- Beschreibung : Empfang von Daten ueber die RS232 Schnittstelle
8 -- Autoren : Martin Perner, Schwarz Manfred
10 ----------------------------------------------------------------------------------
13 use IEEE.std_logic_1164.all;
14 use IEEE.numeric_std.all;
16 use work.extension_uart_pkg.all;
18 use work.common_pkg.all;
19 use work.core_pkg.all;
21 architecture beh of rs232_rx is
22 -- definierern der intern verwendeten Signale
23 type STATE_TYPE is (IDLE, READ_START, READ_BIT, READ_STOP, POST_STOP);
24 signal state, state_next : STATE_TYPE;
25 signal bus_rx_last, bus_rx_int, new_rx_data_nxt : std_logic := '0';
26 signal cnt, cnt_next : integer := 0;
27 signal baud_cnt, baud_cnt_next : std_logic_vector(BAUD_RATE_WIDTH-1 downto 0);
28 signal rx_data_int, rx_data_nxt, rx_data_res_int, rx_data_res_nxt : uart_data;
29 signal sync : std_logic_vector(1 to SYNC_STAGES);
30 signal bus_rx : std_logic;
33 -- syncronisierungs Prozess
34 rs232_rx_syn : process(sys_clk, sys_res_n)
36 if (sys_res_n = RESET_VALUE) then
40 rx_data_res_int <= x"00";
41 rx_data_int <= (others => '0');
42 baud_cnt <= (others => '0');
43 sync <= (others => '1');
45 elsif rising_edge(sys_clk) then
46 -- sync Zustand, uebernehmen der next-Signale
49 baud_cnt <= baud_cnt_next;
50 bus_rx_int <= bus_rx_last;
51 rx_data_int <= rx_data_nxt;
52 rx_data_res_int <= rx_data_res_nxt;
53 new_rx_data <= new_rx_data_nxt;
55 sync(1) <= bus_rx_unsync;
56 for i in 2 to SYNC_STAGES loop
57 sync(i) <= sync(i - 1);
63 -- setzen des Ausgangsignals, Rxt-Daten
64 rx_data <= rx_data_res_int;
65 bus_rx <= sync(SYNC_STAGES);
67 -- Zustandsmaschienen Prozess
68 rs232_states : process(sys_clk,state,cnt, bus_rx, bus_rx_last, baud_cnt,bus_rx_int,bd_rate)
70 state_next <= state; -- mal schauen ob des so geht
71 bus_rx_last <= bus_rx; -- mal schauen ob des so geht
74 -- nach einem Wechsel der rxt-Leitung von 1 auf 0 wird der einlese Vorgang
75 -- getriggert mithilfe eines Zustandsuebergangs von IDLE auf READ_START
76 if (bus_rx_last = '0' and bus_rx_int = '1') then
77 state_next <= READ_START;
80 -- im READ_START Zustand wird eine halbe Bitzeit gewartet. Liegt auf der rxt-Leitung
81 -- immer noch die 0 an so wird mit deim Lesebvorgang mit einem Zustandswechsel von
82 -- READ_START nach READ_BIT vorgefahren, wenn eine 1 anliegt wird abgebrochen und
83 -- wieder nach IDLE gewechselt
85 if (bus_rx = '0' and baud_cnt(BAUD_RATE_WIDTH-2 downto 0) = bd_rate(BAUD_RATE_WIDTH-1 downto 1)) then
86 state_next <= READ_BIT;
87 elsif (bus_rx = '1' and baud_cnt(BAUD_RATE_WIDTH-2 downto 0) = bd_rate(BAUD_RATE_WIDTH-1 downto 1)) then
91 -- hier werden mit Hilfe eines Countersignals 8 Datenbits im Abstand der eingestellten
92 -- Bitzeit eingelesen und gespeichert.
93 -- Nach beendigung wird in den Zustand READ_STOP gewechselt.
94 if (cnt = 7 and baud_cnt = bd_rate) then
95 state_next <= READ_STOP;
97 state_next <= READ_BIT;
100 -- hier wird nur noch auf das Stopbit abgewartet und gelesen um den
101 -- Lesevorgang koerrekt zu beenden
102 if baud_cnt = bd_rate and bus_rx = '1' then
104 elsif baud_cnt = bd_rate and bus_rx = '0' then
108 -- hier wird nur noch eine halbe Bitzeit gewartet
109 if baud_cnt(BAUD_RATE_WIDTH-2 downto 0) = bd_rate(BAUD_RATE_WIDTH-1 downto 1) then
116 rs232_rx_baud : process(state, cnt, bus_rx, baud_cnt, rx_data_int, rx_data_res_int, bd_rate)
118 -- Signale halten um Latches zu vermeiden
120 new_rx_data_nxt <= '0';
121 baud_cnt_next <= baud_cnt;
122 rx_data_nxt <= rx_data_int;
123 rx_data_res_nxt <= rx_data_res_int;
124 -- Statewechesel wie obenbeschrieben
128 baud_cnt_next <= (others =>'0'); --0;
130 -- baut_cnt zyklenweise erhoehen bis es einer halben Bitzeit entspricht
131 -- anschliessend zuruecksetzten
132 baud_cnt_next <= std_logic_vector(unsigned(baud_cnt) + 1);
133 if baud_cnt(BAUD_RATE_WIDTH-2 downto 0) = bd_rate(BAUD_RATE_WIDTH-1 downto 1) then
134 baud_cnt_next <= (others => '0');
135 rx_data_nxt <= x"00";
138 -- baut_cnt zyklenweise erhoehen bis es einer Bitzeit entspricht
139 -- anschliessend zuruecksetzen
140 -- Zustand der rxt-Leitung im rx_data_nxt abspeichern
141 baud_cnt_next <= std_logic_vector(unsigned(baud_cnt) + 1);
142 if baud_cnt = bd_rate then
143 baud_cnt_next <= (others => '0');
145 rx_data_nxt(cnt) <= bus_rx;
148 -- baut_cnt zyklenweise erhoehen bis es einer Bitzeit entspricht
149 -- anschliessend zuruecksetzen
151 -- Signal fuer neue rx-Daten setzen um die send_logic zu aktivieren
153 baud_cnt_next <= std_logic_vector(unsigned(baud_cnt) + 1);
154 if baud_cnt = bd_rate then
155 baud_cnt_next <= (others => '0');
156 new_rx_data_nxt <= '1';
157 rx_data_res_nxt <= rx_data_int;
160 --halbe bitzeit wartenr auf counter warten
161 baud_cnt_next <= baud_cnt + 1;
162 if baud_cnt(BAUD_RATE_WIDTH-2 downto 0) = bd_rate(BAUD_RATE_WIDTH-1 downto 1) then
163 new_rx_data_nxt <= '1';
164 rx_data_res_nxt <= rx_data_int;
165 baud_cnt_next <= (others => '0');
170 end architecture beh;