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