uart_rx: ein prozessmodell. spart weitere 3 logic elements :P
[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 entity uart_tx 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                 txd : out std_logic;
15                 tx_data : in std_logic_vector(7 downto 0);
16                 tx_new : in std_logic;
17                 tx_done : out std_logic
18         );
19 end entity uart_tx;
20
21 architecture beh of uart_tx is
22         constant BAUD : integer := CLK_FREQ/BAUDRATE;
23
24         type STATE_UART_TX is (IDLE, SENDBITS, DONE);
25         signal state_int, state_next : STATE_UART_TX;
26
27         signal txd_next, txd_int : std_logic;
28         signal tx_done_next, tx_done_int : std_logic;
29         signal tx_to_send : std_logic_vector(10 downto 0);
30         signal bitcnt_int, bitcnt_next : integer range 0 to 11;
31         signal baudcnt_int, baudcnt_next : integer range 0 to BAUD;
32 begin
33         txd <= txd_int;
34         tx_done <= tx_done_int;
35
36         process (sys_clk, sys_res_n)
37         begin
38                 if sys_res_n = '0' then
39                         state_int <= IDLE;
40                         txd_int <= '1';
41                         tx_done_int <= '0';
42                         bitcnt_int <= 0;
43                         baudcnt_int <= 0;
44                         tx_to_send <= (others => '0');
45                 elsif rising_edge(sys_clk) then
46                         state_int <= state_next;
47                         txd_int <= txd_next;
48                         tx_done_int <= tx_done_next;
49                         bitcnt_int <= bitcnt_next;
50                         baudcnt_int <= baudcnt_next;
51                         -- STOPBIT (1) | DATA (8) | STARTBIT (1) | HIGHBIT (1)
52                         tx_to_send <= '1' & tx_data & '0' & '1';
53                 end if;
54         end process;
55
56         process(tx_new, tx_to_send, state_int, bitcnt_int, baudcnt_int,
57                 tx_done_int, txd_int)
58         begin
59                 state_next <= state_int;
60                 tx_done_next <= tx_done_int;
61                 txd_next <= txd_int;
62                 bitcnt_next <= bitcnt_int;
63                 baudcnt_next <= baudcnt_int;
64
65                 case state_int is
66                         when IDLE =>
67                                 tx_done_next <= '0';
68                                 txd_next <= '1';
69                                 bitcnt_next <= 0;
70                                 -- das highbyte sofort anlegen
71                                 baudcnt_next <= BAUD;
72                                 if tx_new = '1' then
73                                         state_next <= SENDBITS;
74                                 end if;
75                         when SENDBITS =>
76                                 if bitcnt_int <= 10 then
77                                         if baudcnt_int < BAUD then
78                                                 baudcnt_next <= baudcnt_int + 1;
79                                         else
80                                                 txd_next <= tx_to_send(bitcnt_int);
81                                                 bitcnt_next <= bitcnt_int + 1;
82                                                 baudcnt_next <= 0;
83                                         end if;
84                                 else
85                                         -- fuer das stopbit auch noch warten
86                                         if baudcnt_int < BAUD then
87                                                 baudcnt_next <= baudcnt_int + 1;
88                                         else
89                                                 state_next <= DONE;
90                                         end if;
91                                 end if;
92                         when DONE =>
93                                 tx_done_next <= '1';
94                                 if tx_new = '0' then
95                                         state_next <= IDLE;
96                                 end if;
97                 end case;
98         end process;
99 end architecture beh;