library IEEE; use IEEE.STD_LOGIC_1164.ALL; entity rx is Port ( rx_line : in STD_LOGIC; clk : in STD_LOGIC; err : out STD_LOGIC := '1'; data : out STD_LOGIC_VECTOR (7 downto 0) := "00000000"; ready : out STD_LOGIC); end rx; architecture Behavioral of rx is component clk_sampler is Port ( reset : in STD_LOGIC; clk :in STD_LOGIC; full : out STD_LOGIC); end component; signal sampler_full, sampler_reset : STD_LOGIC; type state is (idle, start_bit, bit_0, bit_1, bit_2, bit_3, bit_4, bit_5, bit_6, bit_7, stop_bit); signal f : state; signal p : state := idle; begin cs_0 : clk_sampler port map( clk => clk, reset => sampler_reset, full => sampler_full); process (clk) begin if rising_edge(clk) then p <= f; end if; end process; process(rx_line, sampler_full, p) begin case p is when idle => if rx_line = '0' then --falling edge of start bit detected, --reset the clock divider to 1/2 period sampler_reset <= '1'; f <= start_bit; else sampler_reset <= '0'; f <= idle; end if; ready <= '1'; when start_bit => ready <= '0'; sampler_reset <= '0'; if sampler_full = '1' then if rx_line = '0' then f <= bit_0; else f <= idle; end if; else f <= start_bit; end if; when bit_0 => data(7) <= rx_line; sampler_reset <= '0'; ready <= '0'; if sampler_full = '1' then f <= bit_1; else f <= bit_0; end if; when bit_1 => data(6) <= rx_line; sampler_reset <= '0'; ready <= '0'; if sampler_full = '1' then f <= bit_2; else f <= bit_1; end if; when bit_2 => data(5) <= rx_line; sampler_reset <= '0'; ready <= '0'; if sampler_full = '1' then f <= bit_3; else f <= bit_2; end if; when bit_3 => data(4) <= rx_line; sampler_reset <= '0'; ready <= '0'; if sampler_full = '1' then f <= bit_4; else f <= bit_3; end if; when bit_4 => data(3) <= rx_line; sampler_reset <= '0'; ready <= '0'; if sampler_full = '1' then f <= bit_5; else f <= bit_4; end if; when bit_5 => data(2) <= rx_line; sampler_reset <= '0'; ready <= '0'; if sampler_full = '1' then f <= bit_6; else f <= bit_5; end if; when bit_6 => data(1) <= rx_line; sampler_reset <= '0'; ready <= '0'; if sampler_full = '1' then f <= bit_7; else f <= bit_6; end if; when bit_7 => data(0) <= rx_line; sampler_reset <= '0'; ready <= '0'; if sampler_full = '1' then f <= stop_bit; else f <= bit_7; end if; when stop_bit => sampler_reset <= '0'; ready <= '0'; if sampler_full = '1' then if rx_line = '1' then err <= '0'; else err <= '1'; end if; f <= idle; else f <= stop_bit; end if; when others => f <= idle; ready <= '0'; err <= '1'; data <= "00000000"; sampler_reset <= '0'; end case; end process; end Behavioral;