-- C16 System On Chip Architecture -- Copyright (C) 2003 by Cole Design and Development all rights reserved -- -- TODO: Rx capability, interrupts, Tx fifo, Rx fifo, 16550-compatible registers library ieee; use ieee.std_logic_1164.ALL; use ieee.numeric_std.all; entity uart is Port ( enable : in std_logic; -- rtc enable clock : in std_logic; -- clock signal reset : in std_logic; -- reset input cs : in std_logic; -- chip select read : in std_logic; -- read data write : in std_logic; -- write data interrupt : out std_logic; -- uart interrupt line txd : out std_logic; -- serial data output rxd : in std_logic; -- serial data input address : in std_logic_vector(3 downto 0); -- address within uart data_in : in std_logic_vector (15 downto 0); -- byte written to uart data_out : out std_logic_vector (15 downto 0)); -- byte read from uart end uart; architecture Behavioral of uart is signal state : std_logic_vector (1 downto 0); constant cpu_clock_rate : integer := 50_000_000; constant baud_rate : integer := 115200; signal busy : std_logic; signal data_in_fifo : std_logic_vector (15 downto 0); -- fifo for bytes written to uart begin busy <= '0' when state = "00" or state = "01" else '1'; interrupt <= '0'; process(read) begin if read = '1' then if enable = '1' then case address is when "0000" => data_out <= "0000000001000001"; -- rx data when "0001" => data_out <= "000000000000000" & busy; -- status when others => data_out <= "0000000000000000"; end case; data_out <= "000000000000000" & busy; -- status else data_out <= "ZZZZZZZZZZZZZZZZ"; end if; end if; end process; process(clock) variable bit_count : integer; variable clock_count : integer; begin if rising_edge(clock) then if reset = '1' then state <= "00"; elsif enable = '1' then clock_count := clock_count + 1; case state is when "00" => txd <= '1'; if write = '0' then state <= "01"; else state <= "00"; end if; when "01" => if write = '1' and cs = '1' then clock_count := 0; state <= "10"; data_in_fifo <= data_in; end if; when "10" => if clock_count > (cpu_clock_rate/baud_rate) then clock_count := 0; bit_count := 0; state <= "11"; else txd <= '0'; -- start bit end if; when "11" => case bit_count is when 10 => state <= "00"; when 9 => txd <= '1'; -- stop bit when 8 => txd <= '1'; -- stop bit when others => txd <= data_in_fifo(bit_count); end case; if clock_count > (cpu_clock_rate/baud_rate) then clock_count := 0; bit_count := bit_count + 1; end if; when others => txd <= '1'; end case; end if; end if; end process; end Behavioral;