uart_rx: ein prozessmodell. spart weitere 3 logic elements :P
[hwmod.git] / src / uart_rx.vhd
1 library ieee;
2 use ieee.std_logic_1164.all;
3 use ieee.numeric_std.all;
4 use work.gen_pkg.all;
5
6 entity uart_rx is
7         generic (
8                 CLK_FREQ : integer := 33000000;
9                 BAUDRATE : integer := 115200
10         );
11         port(
12                 sys_clk : in std_logic;
13                 sys_res_n : in std_logic;
14                 rxd : in std_logic;
15                 rx_data : out std_logic_vector(7 downto 0);
16                 rx_new : out std_logic
17         );
18 end entity uart_rx;
19
20 architecture beh of uart_rx is
21         constant BAUD : integer := CLK_FREQ/BAUDRATE;
22
23         type STATE_UART_RX is (IDLE, STARTBIT, DBITS, STOPBIT);
24         signal state : STATE_UART_RX;
25
26         signal startbitdetection : std_logic_vector(1 downto 0);
27         signal bitcnt : integer range 0 to 7;
28         signal baudcnt : integer range 0 to BAUD + 2;
29         signal rx_data_int : std_logic_vector(7 downto 0);
30 begin
31         rx_data <= rx_data_int;
32         process(sys_clk, sys_res_n)
33         begin
34                 if (sys_res_n = '0') then
35                         state <= IDLE;
36                         rx_data_int <= (others => '0');
37                         rx_new <= '0';
38                         bitcnt <= 0;
39                         baudcnt <= 0;
40                         startbitdetection <= b"11";
41                 elsif rising_edge(sys_clk) then
42                         startbitdetection <= startbitdetection(0) & rxd;
43                         rx_new <= '0';
44                         baudcnt <= baudcnt + 1;
45                         case state is
46                                 when IDLE =>
47                                         baudcnt <= 0;
48                                         -- bei fallender flanke koennte starbit folgen
49                                         if startbitdetection = b"10" then
50                                                 state <= STARTBIT;
51                                         end if;
52                                 when STARTBIT =>
53                                         rx_data_int <= (others => '0');
54
55                                         -- halbe BAUDTIME warten, um immer in der mitte abzutasten
56                                         -- vgl. http://upload.wikimedia.org/wikipedia/de/d/de/RS-232_timing.png
57                                         if baudcnt = BAUD/2 then
58                                                 baudcnt <= 0;
59                                                 if rxd = '0' then
60                                                         -- starbit (= '0')? dann kommen daten
61                                                         state <= DBITS;
62                                                         bitcnt <= 0;
63                                                         baudcnt <= 0;
64                                                 else
65                                                         -- sonst war das nix...
66                                                         state <= IDLE;
67                                                 end if;
68                                         end if;
69                                 when DBITS =>
70                                         if baudcnt = BAUD then
71                                                 baudcnt <= 0;
72                                                 -- bitorder beachten
73                                                 rx_data_int <= rxd & rx_data_int(7 downto 1);
74
75                                                 if bitcnt = 7 then
76                                                         state <= STOPBIT;
77                                                 else
78                                                         bitcnt <= bitcnt + 1;
79                                                 end if;
80                                         end if;
81                                 when STOPBIT =>
82                                         if baudcnt = BAUD then
83                                                 state <= IDLE;
84                                                 if rxd = '1' then
85                                                         rx_new <= '1';
86                                                 end if;
87                                         end if;
88                         end case;
89                 end if;
90         end process;
91 end architecture beh;