library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; use work.gen_pkg.all; entity uart_tx is generic ( CLK_FREQ : integer := 33000000; BAUDRATE : integer := 115200 ); port( sys_clk : in std_logic; sys_res_n : in std_logic; txd : out std_logic; tx_data : in std_logic_vector(7 downto 0); tx_new : in std_logic; tx_done : out std_logic ); end entity uart_tx; architecture beh of uart_tx is constant BAUD : integer := CLK_FREQ/BAUDRATE; type STATE_UART_TX is (IDLE, SENDBITS, DONE); signal state_int, state_next : STATE_UART_TX; signal txd_next, txd_int : std_logic; signal tx_done_next, tx_done_int : std_logic; signal tx_to_send : std_logic_vector(10 downto 0); signal bitcnt_int, bitcnt_next : integer range 0 to 11; signal baudcnt_int, baudcnt_next : integer range 0 to BAUD; begin txd <= txd_int; tx_done <= tx_done_int; process (sys_clk, sys_res_n) begin if sys_res_n = '0' then state_int <= IDLE; txd_int <= '1'; tx_done_int <= '0'; bitcnt_int <= 0; baudcnt_int <= 0; tx_to_send <= (others => '0'); elsif rising_edge(sys_clk) then state_int <= state_next; txd_int <= txd_next; tx_done_int <= tx_done_next; bitcnt_int <= bitcnt_next; baudcnt_int <= baudcnt_next; -- STOPBIT (1) | DATA (8) | STARTBIT (1) | HIGHBIT (1) tx_to_send <= '1' & tx_data & '0' & '1'; end if; end process; process(tx_new, tx_to_send, state_int, bitcnt_int, baudcnt_int, tx_done_int, txd_int) begin state_next <= state_int; tx_done_next <= tx_done_int; txd_next <= txd_int; bitcnt_next <= bitcnt_int; baudcnt_next <= baudcnt_int; case state_int is when IDLE => tx_done_next <= '0'; txd_next <= '1'; bitcnt_next <= 0; -- das highbyte sofort anlegen baudcnt_next <= BAUD; if tx_new = '1' then state_next <= SENDBITS; end if; when SENDBITS => if bitcnt_int <= 10 then if baudcnt_int < BAUD then baudcnt_next <= baudcnt_int + 1; else txd_next <= tx_to_send(bitcnt_int); bitcnt_next <= bitcnt_int + 1; baudcnt_next <= 0; end if; else -- fuer das stopbit auch noch warten if baudcnt_int < BAUD then baudcnt_next <= baudcnt_int + 1; else state_next <= DONE; end if; end if; when DONE => tx_done_next <= '1'; if tx_new = '0' then state_next <= IDLE; end if; end case; end process; end architecture beh;