]> rtime.felk.cvut.cz Git - fpga/uart.git/blob - rx.vhd
Resets changed from asynchronous to synchronous.
[fpga/uart.git] / rx.vhd
1 library ieee;
2 use ieee.std_logic_1164.all;
3 use ieee.std_logic_arith.all;
4 use ieee.std_logic_unsigned.all;
5
6 --------------------------------------------------------------------------------
7 -- Input shift register
8 --
9 -- It is used to receive a serial asynchronous frame. In the steady state, the
10 -- signal 'ready' is set, the 'data' output vector and signals 'bad_start_bit'
11 -- and 'bad_stop_bit' contains valid values of the last received frame.
12 --
13 -- Receiving is done by the following procedure:
14 --      - wait until 'ready' = 1
15 --      - set 'en' and make 'clk' falling edge (1st bit is sampled)
16 --      - 'ready' goes to 0
17 --      - continue generating clock signal until 'ready' = 1 again
18 --      - frame is received
19 --
20 -- All operations, 'rx' sampling, etc. (except for reset) are synchronous to
21 -- 'clk' !!! FALLING !!! egdes. The reason is that sampling should occurs in the
22 -- middle of period where usally clock signal is falling.
23 --
24 -- Invalid start bit is signalized at the begining of the frame, so the
25 -- receiving can be immediately stopped by receiver reset.
26 --------------------------------------------------------------------------------
27
28 entity receiver is
29   port (
30     clk           : in  std_logic;
31     reset         : in  std_logic;
32     en            : in  std_logic;
33     rx            : in  std_logic;
34     ready         : out std_logic;
35     bad_start_bit : out std_logic := '0';
36     bad_stop_bit  : out std_logic := '0';
37     data          : out std_logic_vector (7 downto 0));
38 end entity receiver;
39
40 --------------------------------------------------------------------------------
41
42 architecture behavioral of receiver is
43   
44   signal rx_shift_reg : std_logic_vector (9 downto 0);
45   signal rx_flag      : std_logic_vector (9 downto 0);
46   signal rx_ready     : std_logic := '1';
47   signal rx_running   : std_logic := '0';
48   
49 --------------------------------------------------------------------------------
50   
51 begin
52
53   process (clk, reset) is
54   begin
55     if clk'event and clk = '0' then
56       if reset = '1' then
57         rx_ready   <= '1';
58         rx_running <= '0';
59         
60         bad_stop_bit  <= '0';
61         bad_start_bit <= '0';
62
63       else
64         -- Start receiving a new frame
65         if rx_ready = '1' and en = '1' then
66           rx_shift_reg <= rx & rx_shift_reg (9 downto 1);
67           rx_flag      <= "0100000000";
68           rx_ready     <= '0';
69           rx_running   <= '1';
70
71           bad_start_bit <= rx;
72           bad_stop_bit  <= '0';
73
74         -- Receiving of the 1st data bit and all its consequents
75         elsif rx_running = '1' then
76           rx_shift_reg <= rx & rx_shift_reg (9 downto 1);
77           rx_flag      <= '0' & rx_flag (9 downto 1);
78
79           -- End of the frame is comming
80           if rx_flag (0) = '1' then
81             rx_ready   <= '1';
82             rx_running <= '0';
83
84             bad_stop_bit <= not rx;
85           end if;
86         end if;
87       end if;
88     end if;
89   end process;
90   
91 --------------------------------------------------------------------------------
92
93   data  <= rx_shift_reg (8 downto 1);
94   ready <= rx_ready;
95   
96 end architecture behavioral;
97