924a3ce9a6be8bc8aba7bed482f87ccfb622d05b
[calu.git] / cpu / src / rs232_rx_arc.vhd
1 ---------------------------------------------------------------------------------
2 -- Filename : rs232_rx_arc.vhd
3 -- ========== 
4 -- 
5 -- Beschreibung : Empfang von Daten ueber die RS232 Schnittstelle
6 -- ==============
7 --
8 -- Autoren : Martin Perner, Schwarz Manfred
9 -- =========
10 ----------------------------------------------------------------------------------
11
12 library IEEE;
13 use IEEE.std_logic_1164.all;
14 use IEEE.numeric_std.all;
15
16 use work.extension_uart_pkg.all;
17
18 use work.common_pkg.all;
19 use work.core_pkg.all;
20
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;
31         
32 begin
33         -- syncronisierungs Prozess
34         rs232_rx_syn : process(sys_clk, sys_res_n)
35         begin
36                 if (sys_res_n = RESET_VALUE) then
37                         -- reset Zustand
38                         state <= IDLE;
39                         cnt <= 0;
40                         rx_data_res_int <= x"00";
41                         baud_cnt <= (others => '0');
42                         sync <= (others => '1');
43
44                 elsif rising_edge(sys_clk) then
45                         -- sync Zustand, uebernehmen der next-Signale
46                         state <= state_next;
47                         cnt <= cnt_next;
48                         baud_cnt <= baud_cnt_next;
49                         bus_rx_int <= bus_rx_last;
50                         rx_data_int <= rx_data_nxt;
51                         rx_data_res_int <= rx_data_res_nxt;
52                         new_rx_data <= new_rx_data_nxt;
53
54                         sync(1) <= bus_rx_unsync;
55                         for i in 2 to SYNC_STAGES loop
56                                 sync(i) <= sync(i - 1);
57                         end loop;
58                         
59                 end if;
60         end process;
61
62         -- setzen des Ausgangsignals, Rxt-Daten
63         rx_data <= rx_data_res_int;
64         bus_rx <= sync(SYNC_STAGES);
65
66         -- Zustandsmaschienen Prozess
67         rs232_states : process(sys_clk,state,cnt, bus_rx, bus_rx_last, baud_cnt,bus_rx_int,bd_rate)
68         begin
69                 state_next <= state;    -- mal schauen ob des so geht
70                 bus_rx_last <= bus_rx; -- mal schauen ob des so geht
71                 case state is
72                         when IDLE =>
73                                 -- nach einem Wechsel der rxt-Leitung von 1 auf 0 wird der einlese Vorgang
74                                 -- getriggert mithilfe eines Zustandsuebergangs von IDLE auf READ_START
75                                 if (bus_rx_last = '0' and bus_rx_int = '1') then
76                                         state_next <= READ_START;
77                                 end if;
78                         when READ_START =>
79                                 -- im READ_START Zustand wird eine halbe Bitzeit gewartet. Liegt auf der rxt-Leitung
80                                 -- immer noch die 0 an so wird mit deim Lesebvorgang mit einem Zustandswechsel von
81                                 -- READ_START nach READ_BIT vorgefahren, wenn eine 1 anliegt wird abgebrochen und
82                                 -- wieder nach IDLE gewechselt
83                                 
84                                 if (bus_rx = '0' and baud_cnt(BAUD_RATE_WIDTH-2 downto 0) = bd_rate(BAUD_RATE_WIDTH-1 downto 1)) then
85                                         state_next <= READ_BIT;
86                                 elsif (bus_rx = '1' and baud_cnt(BAUD_RATE_WIDTH-2 downto 0) = bd_rate(BAUD_RATE_WIDTH-1 downto 1)) then
87                                         state_next <= IDLE;
88                                 end if;
89                         when READ_BIT =>
90                                 -- hier werden mit Hilfe eines Countersignals 8 Datenbits im Abstand der eingestellten
91                                 -- Bitzeit eingelesen und gespeichert.
92                                 -- Nach beendigung wird in den Zustand READ_STOP gewechselt.
93                                 if (cnt = 7 and  baud_cnt = bd_rate) then
94                                         state_next <= READ_STOP;
95                                 else
96                                         state_next <= READ_BIT;
97                                 end if;
98                         when READ_STOP =>
99                                 -- hier wird nur noch auf das Stopbit abgewartet und gelesen um den
100                                 -- Lesevorgang koerrekt zu beenden
101                                 if baud_cnt = bd_rate and bus_rx = '1' then
102                                         state_next <= POST_STOP;
103                                 elsif baud_cnt = bd_rate and bus_rx = '0' then
104                                         state_next <= IDLE;
105                                 end if;
106                         when POST_STOP =>
107                                 -- hier wird nur noch eine halbe Bitzeit gewartet
108                                 if baud_cnt(BAUD_RATE_WIDTH-2 downto 0) = bd_rate(BAUD_RATE_WIDTH-1 downto 1) then
109                                         state_next <= IDLE;
110                                 end if;
111                 end case;
112         end process;
113
114         -- Ausgabe Logik
115         rs232_rx_baud : process(state, cnt, bus_rx, baud_cnt, rx_data_int, rx_data_res_int, bd_rate)
116         begin
117                 -- Signale halten um Latches zu vermeiden
118                 cnt_next <= cnt;
119                 new_rx_data_nxt <= '0';
120                 baud_cnt_next <= baud_cnt;
121                 rx_data_nxt <= rx_data_int;
122                 rx_data_res_nxt <= rx_data_res_int;
123                 -- Statewechesel wie obenbeschrieben
124                 case state is
125                         when IDLE =>
126                                 baud_cnt_next <= (others =>'0'); --0;
127                         when READ_START =>
128                                 -- baut_cnt zyklenweise erhoehen bis es einer halben Bitzeit entspricht
129                                 -- anschliessend zuruecksetzten
130                                 baud_cnt_next <= std_logic_vector(unsigned(baud_cnt) + 1);
131                                 if baud_cnt(BAUD_RATE_WIDTH-2 downto 0) = bd_rate(BAUD_RATE_WIDTH-1 downto 1) then 
132                                         baud_cnt_next <= (others => '0');
133                                         rx_data_nxt <= x"00";
134                                 end if;
135                         when READ_BIT =>
136                                 -- baut_cnt zyklenweise erhoehen bis es einer Bitzeit entspricht
137                                 -- anschliessend zuruecksetzen
138                                 -- Zustand der rxt-Leitung im rx_data_nxt abspeichern
139                                 baud_cnt_next <= std_logic_vector(unsigned(baud_cnt) + 1);
140                                 if baud_cnt = bd_rate then 
141                                         baud_cnt_next <= (others => '0');
142                                         cnt_next <= cnt+1;
143                                         rx_data_nxt(cnt) <= bus_rx;
144                                 end if;
145                         when READ_STOP =>
146                                 -- baut_cnt zyklenweise erhoehen bis es einer Bitzeit entspricht
147                                 -- anschliessend zuruecksetzen
148                                 -- Counter reseten
149                                 -- Signal fuer neue rx-Daten setzen um die send_logic zu aktivieren
150                                 cnt_next <= 0;
151                                 baud_cnt_next <= std_logic_vector(unsigned(baud_cnt) + 1);
152                                 if baud_cnt = bd_rate then 
153                                         baud_cnt_next <= (others => '0');
154                                 end if;
155                         when POST_STOP =>
156                                 --halbe bitzeit wartenr auf counter warten
157                                 baud_cnt_next <= baud_cnt + 1;
158                                 if baud_cnt(BAUD_RATE_WIDTH-2 downto 0) = bd_rate(BAUD_RATE_WIDTH-1 downto 1) then 
159                                         new_rx_data_nxt <= '1'; 
160                                         rx_data_res_nxt <= rx_data_int;
161                                         baud_cnt_next <= (others => '0');
162                                 end if;
163                 end case;
164         end process;
165
166 end architecture beh;
167