--- /dev/null
+library ieee;
+use ieee.std_logic_1164.all;
+use ieee.std_logic_arith.all;
+use ieee.std_logic_unsigned.all;
+
+--------------------------------------------------------------------------------
+-- Input shift register
+--
+-- It is used to receive a serial asynchronous frame. In the steady state, the
+-- signal 'ready' is set, the 'data' output vector and signals 'bad_start_bit'
+-- and 'bad_stop_bit' contains valid values of the last received frame.
+--
+-- Receiving is done by the following procedure:
+-- - wait until 'ready' = 1
+-- - set 'en' and raise 'clk' positive edge (1st bit is sampled)
+-- - 'ready' goes to 0
+-- - continue generating clock signal until 'ready' = 1 again
+-- - frame is received
+--
+-- All operations, 'rx' sampling, etc. (except for reset) are synchronous to
+-- 'clk' rising egdes.
+--
+-- Invalid start bit is signalized at the begining of the frame, so the
+-- receiving can be immediately stopped by receiver reset.
+--------------------------------------------------------------------------------
+
+entity receiver is
+ port (
+ clk : in std_logic;
+ reset : in std_logic;
+ en : in std_logic;
+ rx : in std_logic;
+ ready : out std_logic;
+ bad_start_bit : out std_logic;
+ bad_stop_bit : out std_logic;
+ data : out std_logic_vector (7 downto 0));
+end entity receiver;
+
+--------------------------------------------------------------------------------
+
+architecture behavioral of receiver is
+
+ signal rx_shift_reg : std_logic_vector (9 downto 0);
+ signal rx_flag : std_logic_vector (9 downto 0);
+ signal rx_ready : std_logic;
+ signal rx_running : std_logic;
+
+--------------------------------------------------------------------------------
+
+begin
+
+ process (clk, reset) is
+ begin
+ if reset = '1' then
+ rx_ready <= '1';
+ rx_running <= '0';
+
+ bad_stop_bit <= '0';
+ bad_start_bit <= '0';
+
+ elsif clk'event and clk = '1' then
+ -- Start receiving a new frame
+ if rx_ready = '1' and en = '1' then
+ rx_shift_reg <= rx & rx_shift_reg (9 downto 1);
+ rx_flag <= "0100000000";
+ rx_ready <= '0';
+ rx_running <= '1';
+
+ bad_start_bit <= rx;
+ bad_stop_bit <= '0';
+
+ -- Receiving of the 1st data bit and all its consequents
+ elsif rx_running = '1' then
+ rx_shift_reg <= rx & rx_shift_reg (9 downto 1);
+ rx_flag <= '0' & rx_flag (9 downto 1);
+
+ -- End of the frame is comming
+ if rx_flag (0) = '1' then
+ rx_ready <= '1';
+ rx_running <= '0';
+
+ bad_stop_bit <= not rx;
+ end if;
+ end if;
+
+ end if;
+ end process;
+
+--------------------------------------------------------------------------------
+
+ data <= rx_shift_reg (8 downto 1);
+ ready <= rx_ready;
+
+end architecture behavioral;
+