e36b5c583b5b3e76afc6d924cb821a5ab1329ba7
[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 port(
8         sys_clk : in std_logic;
9         sys_res : in std_logic;
10         txd : in std_logic; -- warning: this is asynchronous input!
11         tx_data : out std_logic_vector(7 downto 0); -- map this to a larger register with containing input
12         tx_new : out std_logic
13 );
14 end entity uart_rx;
15
16 architecture beh of uart_rx is
17         constant timer_max : integer := 35;
18
19         type STATE_UART_RX is (IDLE, BUSY, DONE);
20
21         signal timer, timer_next : integer range 0 to 65535;
22         signal counter, counter_next : integer range 0 to 15;
23         signal state, state_next : STATE_UART_RX;
24         signal tx_data_prev : std_logic_vector(7 downto 0); -- FIXME: this isnt named next so that the interface isn't called tx_data_next ...
25
26         -- these are internal signals that are actually used as in and output
27         signal tx_data_i : std_logic_vector(7 downto 0);
28         signal tx_new_i : std_logic;
29 begin
30 --FIXME:
31
32         tx_new <= tx_new_i;
33         tx_data <= tx_data_i;
34
35         process(sys_clk, sys_res)
36         begin
37                 if (sys_res = '0') then
38                         -- Set reset state
39                         state <= IDLE;
40                         tx_data_prev <= X"00";
41                 elsif rising_edge(sys_clk) then
42                         -- Store next state
43                         state <= state_next;
44                         tx_data_prev <= tx_data_i;
45                 end if;
46         end process;
47
48         process(state, txd, counter)
49         begin
50                 state_next <= state;
51                 case state is
52                         when IDLE =>
53                                 if (txd = '0') then
54                                         state_next <= BUSY;
55                                 else
56                                         state_next <= IDLE;
57                                 end if;
58                         when BUSY =>
59                                 if (counter = 9) then --FIXME: is this true?
60                                         state_next <= DONE;
61                                 else
62                                         state_next <= BUSY;
63                                 end if;
64                         when DONE =>
65                                 state_next <= IDLE;
66                 end case;
67         end process;
68
69         process(state)
70         begin
71                 -- Set default values
72                 -- for the outputs
73                 tx_new_i <= '0';
74
75                 -- Calculate the outputs
76                 -- based on the current
77                 -- state
78                 case state is
79                         when IDLE =>
80                                 tx_new_i <= '0';
81                         when BUSY =>
82                                 tx_new_i <= '0';
83                         when DONE =>
84                                 tx_new_i <= '1';
85                 end case;
86         end process;
87 -- END FIXME: do fill this out CORRECTLY
88
89         process (sys_clk, sys_res)
90         begin
91                 if sys_res = '0' then
92                         counter <= 0;
93                         timer <= 0;
94                 elsif rising_edge(sys_clk) then
95                         counter <= counter_next;
96                         timer <= timer_next;
97                 end if;
98         end process;
99
100         process (timer)
101         begin
102                 if (timer = timer_max) then
103                         timer_next <= 0;
104                 else
105                         timer_next <= timer + 1;
106                 end if;
107         end process;
108
109         process (timer, counter, tx_new_i)
110         begin
111                 if (tx_new_i = '1') then
112                         if (timer = timer_max) then
113                                 if (counter > 10) then
114                                         counter_next <= 0;
115                                 else
116                                         counter_next <= counter + 1;
117                                 end if;
118                         else
119                                         counter_next <= counter;
120                         end if;
121                 else
122                                 counter_next <= 0;
123                 end if;
124         end process;
125
126         process (counter, txd)
127         begin
128                 tx_data_i <= tx_data_prev;
129                 -- TODO: we probably want oversampling and averaging + failure!
130                 -- FIXME: this is per se not synthesisable
131                 case (counter) is
132                         when 0 => --start bit
133                                 assert (txd = '0');
134                         when 1 =>
135                                 tx_data_i(0) <= txd;
136                         when 2 =>
137                                 tx_data_i(1) <= txd;
138                         when 3 =>
139                                 tx_data_i(2) <= txd;
140                         when 4 =>
141                                 tx_data_i(3) <= txd;
142                         when 5 =>
143                                 tx_data_i(4) <= txd;
144                         when 6 =>
145                                 tx_data_i(5) <= txd;
146                         when 7 =>
147                                 tx_data_i(6) <= txd;
148                         when 8 =>
149                                 tx_data_i(7) <= txd;
150                         when 9 => -- stop bit
151                                 assert (txd = '1');
152                         when others => -- idle
153                                 assert (txd = '1');
154                 end case;
155         end process;
156
157 end architecture beh;