library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
---use work.gen_pkg.all;
-
---package int_types is
--- type STATE_UART_TX is (IDLE, STARTBITS, PAYLOAD, PARITY, STOP, DONE);
--- type PARITY_TYPE is (ODD, EVEN, NONE);
---end package int_types;
+use work.gen_pkg.all;
entity uart_tx is
-port(
- sys_clk : in std_logic;
- sys_res : in std_logic;
- --txd : out std_logic;
- --tx_data : in std_logic;
- tx_new : in std_logic;
- tx_done : out std_logic
-);
+ 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
- signal timer : integer range 0 to 65535;
- signal timer_next : integer range 0 to 65535;
- constant timer_max : integer := 35;
- signal counter : integer;
- signal counter_next : integer;
+ 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(0 to 10);
+ signal bitcnt_int, bitcnt_next : integer range 0 to 11;
+ signal baudcnt_int, baudcnt_next : integer range 0 to BAUD;
begin
- process (sys_clk, sys_res)
+ txd <= txd_int;
+ tx_done <= tx_done_int;
+
+ process (sys_clk, sys_res_n)
begin
- if sys_res = '0' then
- counter <= 0;
- timer <= 0;
+ 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
- counter <= counter_next;
- timer <= timer_next;
+ state_int <= state_next;
+ txd_int <= txd_next;
+ tx_done_int <= tx_done_next;
+ bitcnt_int <= bitcnt_next;
+ baudcnt_int <= baudcnt_next;
+ -- HIGHBIT (1) | STARTBIT (1) | DATA (8) | STOPBIT (1)
+ tx_to_send <= '1' & '0' & tx_data & '1';
end if;
end process;
-
- process (timer, counter)
+ process(tx_new, tx_to_send, state_int, bitcnt_int, baudcnt_int,
+ tx_done_int, txd_int)
begin
- if (timer = timer_max) then
- timer_next <= 0;
- counter_next <= counter + 1;
- else
- timer_next <= timer + 1;
- counter_next <= counter;
- end if;
- end process;
-
- tx_done <= '0';
+ 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;