----------------------------------------------------------------------------------\r
--- Filename : rs232_rx_arc.vhd\r
--- ========== \r
--- \r
--- Beschreibung : Empfang von Daten ueber die RS232 Schnittstelle\r
--- ==============\r
---\r
--- Autoren : Martin Perner, Schwarz Manfred\r
--- =========\r
-----------------------------------------------------------------------------------\r
-\r
-library IEEE;\r
-use IEEE.std_logic_1164.all;\r
-use IEEE.numeric_std.all;\r
-\r
-use work.common_pkg.all;\r
-use work.core_pkg.all;\r
-use work.extension_uart_pkg.all;\r
-\r
-architecture beh of rs232_rx is\r
- -- definierern der intern verwendeten Signale\r
- type STATE_TYPE is (IDLE, READ_START, READ_BIT, READ_STOP, POST_STOP);\r
- signal state, state_next : STATE_TYPE;\r
- signal bus_rx_last, bus_rx_int, new_rx_data_nxt : std_logic := '0';\r
- signal cnt, cnt_next : integer := 0;\r
- signal baud_cnt, baud_cnt_next : integer := 0;\r
- signal rx_data_int, rx_data_nxt, rx_data_res_int, rx_data_res_nxt : uart_data;\r
- \r
-begin\r
- -- syncronisierungs Prozess\r
- rs232_rx_syn : process(sys_clk, sys_res_n)\r
- begin\r
- if (sys_res_n = RESET_VALUE) then\r
- -- reset Zustand\r
- state <= IDLE;\r
- cnt <= 0;\r
- rx_data_res_int <= x"00";\r
-\r
- elsif rising_edge(sys_clk) then\r
- -- sync Zustand, uebernehmen der next-Signale\r
- state <= state_next;\r
- cnt <= cnt_next;\r
- baud_cnt <= baud_cnt_next;\r
- bus_rx_int <= bus_rx_last;\r
- rx_data_int <= rx_data_nxt;\r
- rx_data_res_int <= rx_data_res_nxt;\r
- new_rx_data <= new_rx_data_nxt;\r
-\r
- end if;\r
- end process;\r
-\r
- -- setzen des Ausgangsignals, Rxt-Daten\r
- rx_data <= rx_data_res_int;\r
-\r
- -- Zustandsmaschienen Prozess\r
- rs232_states : process(sys_clk,state,cnt, bus_rx, bus_rx_last, baud_cnt,bus_rx_int,bd_rate)\r
- begin\r
- state_next <= state; -- mal schauen ob des so geht\r
- bus_rx_last <= bus_rx; -- mal schauen ob des so geht\r
- case state is\r
- when IDLE =>\r
- -- nach einem Wechsel der rxt-Leitung von 1 auf 0 wird der einlese Vorgang\r
- -- getriggert mithilfe eines Zustandsuebergangs von IDLE auf READ_START\r
- if (bus_rx_last = '0' and bus_rx_int = '1') then\r
- state_next <= READ_START;\r
- end if;\r
- when READ_START =>\r
- -- im READ_START Zustand wird eine halbe Bitzeit gewartet. Liegt auf der rxt-Leitung\r
- -- immer noch die 0 an so wird mit deim Lesebvorgang mit einem Zustandswechsel von\r
- -- READ_START nach READ_BIT vorgefahren, wenn eine 1 anliegt wird abgebrochen und\r
- -- wieder nach IDLE gewechselt\r
- if (bus_rx = '0' and baud_cnt = bd_rate/2) then\r
- state_next <= READ_BIT;\r
- elsif (bus_rx = '1' and baud_cnt = bd_rate/2) then\r
- state_next <= IDLE;\r
- end if;\r
- when READ_BIT =>\r
- -- hier werden mit Hilfe eines Countersignals 8 Datenbits im Abstand der eingestellten\r
- -- Bitzeit eingelesen und gespeichert.\r
- -- Nach beendigung wird in den Zustand READ_STOP gewechselt.\r
- if (cnt = 7 and baud_cnt = bd_rate) then\r
- state_next <= READ_STOP;\r
- else\r
- state_next <= READ_BIT;\r
- end if;\r
- when READ_STOP =>\r
- -- hier wird nur noch auf das Stopbit abgewartet und gelesen um den\r
- -- Lesevorgang koerrekt zu beenden\r
- if baud_cnt = bd_rate and bus_rx = '1' then\r
- state_next <= POST_STOP;\r
- elsif baud_cnt = bd_rate and bus_rx = '0' then\r
- state_next <= IDLE;\r
- end if;\r
- when POST_STOP =>\r
- -- hier wird nur noch eine halbe Bitzeit gewartet\r
- if baud_cnt = bd_rate/2 then\r
- state_next <= IDLE;\r
- end if;\r
- end case;\r
- end process;\r
-\r
- -- Ausgabe Logik\r
- rs232_tx_baud : process(state, cnt, bus_rx, baud_cnt, rx_data_int, rx_data_res_int,bad_rate)\r
- begin\r
- -- Signale halten um Latches zu vermeiden\r
- cnt_next <= cnt;\r
- new_rx_data_nxt <= '0';\r
- baud_cnt_next <= baud_cnt;\r
- rx_data_nxt <= rx_data_int;\r
- rx_data_res_nxt <= rx_data_res_int;\r
- -- Statewechesel wie obenbeschrieben\r
- case state is\r
- when IDLE =>\r
- baud_cnt_next <= 0;\r
- when READ_START =>\r
- -- baut_cnt zyklenweise erhoehen bis es einer halben Bitzeit entspricht\r
- -- anschliessend zuruecksetzten\r
- baud_cnt_next <= baud_cnt + 1;\r
- if baud_cnt = bd_rate/2 then \r
- baud_cnt_next <= 0;\r
- rx_data_nxt <= x"00";\r
- end if;\r
- when READ_BIT =>\r
- -- baut_cnt zyklenweise erhoehen bis es einer Bitzeit entspricht\r
- -- anschliessend zuruecksetzen\r
- -- Zustand der rxt-Leitung im rx_data_nxt abspeichern\r
- baud_cnt_next <= baud_cnt + 1;\r
- if baud_cnt = bd_rate then \r
- baud_cnt_next <= 0;\r
- cnt_next <= cnt+1;\r
- rx_data_nxt(cnt) <= bus_rx;\r
- end if;\r
- when READ_STOP =>\r
- -- baut_cnt zyklenweise erhoehen bis es einer Bitzeit entspricht\r
- -- anschliessend zuruecksetzen\r
- -- Counter reseten\r
- -- Signal fuer neue rx-Daten setzen um die send_logic zu aktivieren\r
- cnt_next <= 0;\r
- baud_cnt_next <= baud_cnt + 1;\r
- if baud_cnt = bd_rate then \r
- baud_cnt_next <= 0;\r
- end if;\r
- when POST_STOP =>\r
- --halbe bitzeit wartenr auf counter warten\r
- baud_cnt_next <= baud_cnt + 1;\r
- if baud_cnt = bd_rate/2 then \r
- new_rx_data_nxt <= '1'; \r
- rx_data_res_nxt <= rx_data_int;\r
- baud_cnt_next <= 0;\r
- end if;\r
- end case;\r
- end process;\r
-\r
-end architecture beh;\r
-\r
+---------------------------------------------------------------------------------
+-- Filename : rs232_rx_arc.vhd
+-- ==========
+--
+-- Beschreibung : Empfang von Daten ueber die RS232 Schnittstelle
+-- ==============
+--
+-- Autoren : Martin Perner, Schwarz Manfred
+-- =========
+----------------------------------------------------------------------------------
+
+library IEEE;
+use IEEE.std_logic_1164.all;
+use IEEE.numeric_std.all;
+
+use work.extension_uart_pkg.all;
+
+use work.common_pkg.all;
+use work.core_pkg.all;
+
+architecture beh of rs232_rx is
+ -- definierern der intern verwendeten Signale
+ 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
+ rs232_rx_syn : process(sys_clk, sys_res_n)
+ begin
+ if (sys_res_n = RESET_VALUE) then
+ -- reset Zustand
+ 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
+ state <= state_next;
+ cnt <= cnt_next;
+ baud_cnt <= baud_cnt_next;
+ bus_rx_int <= bus_rx_last;
+ rx_data_int <= rx_data_nxt;
+ 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)
+ begin
+ state_next <= state; -- mal schauen ob des so geht
+ bus_rx_last <= bus_rx; -- mal schauen ob des so geht
+ case state is
+ when IDLE =>
+ -- nach einem Wechsel der rxt-Leitung von 1 auf 0 wird der einlese Vorgang
+ -- getriggert mithilfe eines Zustandsuebergangs von IDLE auf READ_START
+ if (bus_rx_last = '0' and bus_rx_int = '1') then
+ state_next <= READ_START;
+ end if;
+ when READ_START =>
+ -- im READ_START Zustand wird eine halbe Bitzeit gewartet. Liegt auf der rxt-Leitung
+ -- immer noch die 0 an so wird mit deim Lesebvorgang mit einem Zustandswechsel von
+ -- READ_START nach READ_BIT vorgefahren, wenn eine 1 anliegt wird abgebrochen und
+ -- wieder nach IDLE gewechselt
+
+ if (bus_rx = '0' and baud_cnt(BAUD_RATE_WIDTH-2 downto 0) = bd_rate(BAUD_RATE_WIDTH-1 downto 1)) then
+ state_next <= READ_BIT;
+ elsif (bus_rx = '1' and baud_cnt(BAUD_RATE_WIDTH-2 downto 0) = bd_rate(BAUD_RATE_WIDTH-1 downto 1)) then
+ state_next <= IDLE;
+ end if;
+ when READ_BIT =>
+ -- hier werden mit Hilfe eines Countersignals 8 Datenbits im Abstand der eingestellten
+ -- Bitzeit eingelesen und gespeichert.
+ -- Nach beendigung wird in den Zustand READ_STOP gewechselt.
+ if (cnt = 7 and baud_cnt = bd_rate) then
+ state_next <= READ_STOP;
+ else
+ state_next <= READ_BIT;
+ end if;
+ when READ_STOP =>
+ -- hier wird nur noch auf das Stopbit abgewartet und gelesen um den
+ -- Lesevorgang koerrekt zu beenden
+ if baud_cnt = bd_rate then
+ state_next <= IDLE;
+ end if;
+ end case;
+ end process;
+
+ -- Ausgabe Logik
+ rs232_rx_baud : process(state, cnt, bus_rx, baud_cnt, rx_data_int, rx_data_res_int, bd_rate)
+ begin
+ -- Signale halten um Latches zu vermeiden
+ cnt_next <= cnt;
+ new_rx_data_nxt <= '0';
+ baud_cnt_next <= baud_cnt;
+ rx_data_nxt <= rx_data_int;
+ rx_data_res_nxt <= rx_data_res_int;
+ -- 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
+ -- anschliessend zuruecksetzten
+ baud_cnt_next <= std_logic_vector(unsigned(baud_cnt) + 1);
+ if baud_cnt(BAUD_RATE_WIDTH-2 downto 0) = bd_rate(BAUD_RATE_WIDTH-1 downto 1) then
+ baud_cnt_next <= (others => '0');
+ rx_data_nxt <= x"00";
+ end if;
+ when READ_BIT =>
+ -- baut_cnt zyklenweise erhoehen bis es einer Bitzeit entspricht
+ -- anschliessend zuruecksetzen
+ -- Zustand der rxt-Leitung im rx_data_nxt abspeichern
+ baud_cnt_next <= std_logic_vector(unsigned(baud_cnt) + 1);
+ if baud_cnt = bd_rate then
+ baud_cnt_next <= (others => '0');
+ cnt_next <= cnt+1;
+ rx_data_nxt(cnt) <= bus_rx;
+ end if;
+ when READ_STOP =>
+ -- baut_cnt zyklenweise erhoehen bis es einer Bitzeit entspricht
+ -- anschliessend zuruecksetzen
+ -- Counter reseten
+ -- Signal fuer neue rx-Daten setzen um die send_logic zu aktivieren
+ cnt_next <= 0;
+ baud_cnt_next <= std_logic_vector(unsigned(baud_cnt) + 1);
+ if baud_cnt = bd_rate then
+ baud_cnt_next <= (others => '0');
+ new_rx_data_nxt <= bus_rx;
+ rx_data_res_nxt <= rx_data_int;
+ end if;
+ end case;
+ end process;
+
+end architecture beh;
+