library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.NUMERIC_STD.ALL; entity uart_transmit is Port ( clk : in STD_LOGIC; chip_enable : in std_logic; to_send : in std_logic_vector(7 downto 0); send_enable : in std_logic; ser_in : in std_logic; ser_out : out STD_LOGIC; transmit_finished : out std_logic; received_uart : out unsigned(7 downto 0); received_uart_valid : out std_logic ); end uart_transmit; architecture Behavioral of uart_transmit is signal send_slow : unsigned (5 downto 0) := (others=>'0'); signal send_counter : unsigned (3 downto 0) := "1011"; -- "1011" -> idle signal ser_out_vector : std_logic_vector (8 downto 0) := (others=>'1'); signal enabled : std_logic := '0'; signal direction : std_logic := '0'; begin uart_transmit: PROCESS (clk) BEGIN IF RISING_EDGE(clk) THEN if send_slow = "110110" then -- 115200 baud send_slow <= (others=>'0'); else send_slow <= send_slow + 1; end if; if ser_in='0' and direction='0' then -- incoming byte enabled <= '1'; direction<='1'; send_slow <= "011010"; -- middle of bit send_counter<="1011"; else if send_counter="1011" and direction='0' and send_enable='1' then -- send when idle and request enabled <= '1'; ser_out_vector <= to_send & '1' ; end if; end if; if direction = '0' and chip_enable='1' then if send_slow = "110101" then if send_counter="1011" and enabled='1' then -- start transmit send_counter <= "0001"; enabled <= '0'; else if not(send_counter="1011") then -- transmitted all bits if send_counter="0001" then -- transmit start bit ser_out_vector <= ser_out_vector(8 downto 1) & '0'; else ser_out_vector <= '1' & ser_out_vector(8 downto 1); -- transmit next bit end if; send_counter <= send_counter + 1; end if; end if; end if; else if send_slow = "110101" then ser_out_vector(7 downto 0) <= ser_in & ser_out_vector(7 downto 1); if send_counter="1011" and enabled='1' then -- start receive send_counter <= "0001"; enabled <= '0'; else if not(send_counter="1010") then -- all bits received send_counter <= send_counter + 1; else send_counter <= "1011"; direction <= '0'; end if; end if; end if; end if; END IF; END PROCESS uart_transmit; ser_out <= ser_out_vector(0) when direction='0' and (not(send_counter="1011")) else '1'; transmit_finished <= '1' when send_counter="1011" and enabled='0' else '0'; received_uart <= unsigned(ser_out_vector(7 downto 0)); received_uart_valid <= '1' when send_slow = "011010" and send_counter="1001" and direction='1' else '0'; end Behavioral;