lustiger modelsim fix...
[calu.git] / cpu / src / rs232_rx_arc.vhd
index 6cc94305f175e9c985bc31f48276a5772615aa5b..0a9df83efd043ea824540ad389a46121539673e5 100755 (executable)
----------------------------------------------------------------------------------\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)\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 = CLK_PER_BAUD/2) then\r
-                                       state_next <= READ_BIT;\r
-                               elsif (bus_rx = '1' and baud_cnt = CLK_PER_BAUD/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 = CLK_PER_BAUD) 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 = CLK_PER_BAUD and bus_rx = '1' then\r
-                                       state_next <= POST_STOP;\r
-                               elsif baud_cnt = CLK_PER_BAUD 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 = CLK_PER_BAUD/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)\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 = CLK_PER_BAUD/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 = CLK_PER_BAUD 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 = CLK_PER_BAUD 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 =  CLK_PER_BAUD/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, POST_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 and bus_rx = '1' then
+                                       state_next <= POST_STOP;
+                               elsif baud_cnt = bd_rate and bus_rx = '0' then
+                                       state_next <= IDLE;
+                               end if;
+                       when POST_STOP =>
+                               -- hier wird nur noch eine halbe Bitzeit gewartet
+                               if baud_cnt(BAUD_RATE_WIDTH-2 downto 0) = bd_rate(BAUD_RATE_WIDTH-1 downto 1) 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 =>
+                               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');
+                               end if;
+                       when POST_STOP =>
+                               --halbe bitzeit wartenr auf counter warten
+                               baud_cnt_next <= baud_cnt + 1;
+                               if baud_cnt(BAUD_RATE_WIDTH-2 downto 0) = bd_rate(BAUD_RATE_WIDTH-1 downto 1) then 
+                                       new_rx_data_nxt <= '1'; 
+                                       rx_data_res_nxt <= rx_data_int;
+                                       baud_cnt_next <= (others => '0');
+                               end if;
+               end case;
+       end process;
+
+end architecture beh;
+