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