library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; entity async_8n1_tx is port ( clk : in std_logic; rst : in std_logic; en : in std_logic; wr : in std_logic; data_in : in unsigned (7 downto 0); rdy : out std_logic; data_out : out std_logic ); end entity; architecture beh of async_8n1_tx is component generic_counter is generic ( counter_bits : integer := 4 ); port( clk : in std_logic; rst : in std_logic; en : in std_logic; cnt : out unsigned (counter_bits -1 downto 0) ); end component; type t_tx_state is (idle, send_start, send_data, send_stop); signal i_data_out : std_logic; signal i_rdy : std_logic; signal i_data_reg : unsigned(7 downto 0) := (others => '0'); signal i_current_state : t_tx_state := idle; signal i_next_state : t_tx_state; signal i_cnt : unsigned(3 downto 0); signal i_clear_counter : std_logic; signal tmp_current_state : integer; signal tmp_next_state : integer; begin tmp_current_state <= t_tx_state'pos(i_current_state); tmp_next_state <= t_tx_state'pos(i_next_state); data_out <= i_data_out; rdy <= i_rdy; i_counter : generic_counter port map( clk => clk, rst => i_clear_counter, en => en, cnt => i_cnt); -- Concurrent process, determine output process(i_current_state, i_data_reg(0)) is begin case i_current_state is when idle => i_data_out <= '1'; i_rdy <= '1'; i_clear_counter <= '1'; when send_start => i_data_out <= '0'; i_rdy <= '0'; i_clear_counter <= '1'; when send_data => i_data_out <= i_data_reg(0); i_rdy <= '0'; i_clear_counter <= '0'; when send_stop => i_data_out <= '1'; i_rdy <= '1'; i_clear_counter <= '1'; end case; end process; -- Concurrent process, determine next state process(i_current_state, wr, i_cnt) is begin case i_current_state is when idle => if wr = '1' then i_next_state <= send_start; else i_next_state <= i_current_state; end if; when send_start => i_next_state <= send_data; when send_data => if i_cnt = to_unsigned(7, 4) then i_next_state <= send_stop; else i_next_state <= i_current_state; end if; when send_stop => if wr = '1' then i_next_state <= send_start; else i_next_state <= idle; end if; end case; end process; -- Shift register process(clk) is begin if rising_edge(clk) then if rst = '1' then i_data_reg <= (others => '0'); elsif en = '1' and i_current_state = send_data then i_data_reg <= '1' & i_data_reg(7 downto 1); elsif en = '1' and wr = '1' and (i_current_state = idle or i_current_state = send_stop) then i_data_reg <= data_in; else i_data_reg <= i_data_reg; end if; end if; end process; -- State machine process(clk) is begin if rising_edge(clk) then if rst = '1' then i_current_state <= idle; elsif en = '1' then i_current_state <= i_next_state; end if; end if; end process; end architecture;