f3ccc8f4e584bc4bdfbe0aea7793a77e7200379e
[hwmod.git] / src / uart_tx.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_TX is (IDLE, STARTBITS, PAYLOAD, PARITY, STOP, DONE);
8 --      type PARITY_TYPE is (ODD, EVEN, NONE);
9 --end package int_types;
10
11 entity uart_tx is
12 port(
13         sys_clk : in std_logic;
14         sys_res : in std_logic;
15         txd : out std_logic;
16         tx_data : in std_logic_vector(7 downto 0); -- map this to a larger register with containing input
17         tx_new : in std_logic;
18         tx_done : out std_logic
19 );
20 end entity uart_tx;
21
22 architecture beh of uart_tx is
23         signal timer : integer range 0 to 65535;
24         signal timer_next : integer range 0 to 65535;
25         constant timer_max : integer := 35;
26         signal counter : integer range 0 to 15;
27         signal counter_next : integer range 0 to 15;
28         signal txd_next : std_logic;
29 begin
30         process (sys_clk, sys_res)
31         begin
32                 if sys_res = '0' then
33                         counter <= 0;
34                         timer <= 0;
35                         txd <= '0';
36                         txd_next <= '0';
37                 elsif rising_edge(sys_clk) then
38                         counter <= counter_next;
39                         timer <= timer_next;
40                         txd <= txd_next;
41                 end if;
42         end process;
43
44         process(timer)
45         begin
46                 if (timer = timer_max) then
47                         timer_next <= 0;
48                 else
49                         timer_next <= timer + 1;
50                 end if;
51         end process;
52
53         process (timer, counter, tx_new)
54         begin
55                 if (tx_new = '1') then
56                         if (timer = timer_max) then
57                                 if (counter > 10) then
58                                         counter_next <= 0;
59                                 else
60                                         counter_next <= counter + 1;
61                                 end if;
62                         else
63                                         counter_next <= counter;
64                         end if;
65                 else
66                                 counter_next <= 0;
67                 end if;
68         end process;
69
70         process (counter)
71         begin
72                 -- TODO: this is always 8N1 and anything but optimal
73                 case (counter) is 
74                         when 0 =>
75                                 txd_next <= '1';
76                         when 1 =>
77                                 txd_next <= tx_data(0);
78                         when 2 =>
79                                 txd_next <= tx_data(1);
80                         when 3 =>
81                                 txd_next <= tx_data(2);
82                         when 4 =>
83                                 txd_next <= tx_data(3);
84                         when 5 =>
85                                 txd_next <= tx_data(4);
86                         when 6 =>
87                                 txd_next <= tx_data(5);
88                         when 7 =>
89                                 txd_next <= tx_data(6);
90                         when 8 =>
91                                 txd_next <= tx_data(7);
92                         when 9 =>
93                                 txd_next <= '0';
94                         when 10 =>
95                                 txd_next <= '1';
96                         when others =>
97                                 txd_next <= '1';
98                 end case;
99         end process;
100
101         tx_done <= '0';
102
103 end architecture beh;