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 make 'clk' falling 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' !!! FALLING !!! egdes. The reason is that sampling should occurs in the -- middle of period where usally clock signal is falling. -- -- 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 := '0'; bad_stop_bit : out std_logic := '0'; 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 := '1'; signal rx_running : std_logic := '0'; -------------------------------------------------------------------------------- begin process (clk, reset) is begin if clk'event and clk = '0' then if reset = '1' then rx_ready <= '1'; rx_running <= '0'; bad_stop_bit <= '0'; bad_start_bit <= '0'; else -- 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 if; end process; -------------------------------------------------------------------------------- data <= rx_shift_reg (8 downto 1); ready <= rx_ready; end architecture behavioral;