library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; entity async_8n1_tx_v2 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_v2 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; signal i_rdy : std_logic; signal i_data_reg : unsigned(8 downto 0); signal i_cnt : unsigned(3 downto 0); signal i_clear_counter : std_logic; begin data_out <= i_data_reg(0); rdy <= i_rdy; i_counter : generic_counter port map( clk => clk, rst => i_clear_counter, en => en, cnt => i_cnt); i_clear_counter <= i_rdy; -- Shift register -- Affects registers i_data_reg and i_rdy process(clk) is begin if rising_edge(clk) then if rst = '1' then -- Reset registers i_data_reg <= (others => '1'); i_rdy <= '1'; elsif en = '1' then -- Take a step if i_rdy = '1' then if wr = '1' then -- Load data with start bit i_data_reg <= data_in & '0'; -- and start transfer i_rdy <= '0'; else -- Remain idle i_data_reg <= i_data_reg; i_rdy <= i_rdy; end if; else -- In transmission -- Shift one step, add fill with stop bits i_data_reg <= '1' & i_data_reg(8 downto 1); -- Did transfer finish? if i_cnt = to_unsigned(8, 4) then -- Yes, next bit will be stop bit and we're ready for next transfer i_rdy <= '1'; else -- No, keep transmitting i_rdy <= i_rdy; end if; end if; else -- don't take a step i_data_reg <= i_data_reg; i_rdy <= i_rdy; end if; end if; end process; end architecture;