OpenCores
URL https://opencores.org/ocsvn/simple_uart_for_fpga/simple_uart_for_fpga/trunk

Subversion Repositories simple_uart_for_fpga

[/] [simple_uart_for_fpga/] [trunk/] [source/] [comp/] [uart_rx.vhd] - Blame information for rev 2

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 jakubcabal
--------------------------------------------------------------------------------
2
-- PROJECT: SIMPLE UART FOR FPGA
3
--------------------------------------------------------------------------------
4
-- MODULE:  UART RECEIVER
5
-- AUTHORS: Jakub Cabal <jakubcabal@gmail.com>
6
-- lICENSE: The MIT License (MIT)
7
-- WEBSITE: https://github.com/jakubcabal/uart_for_fpga
8
--------------------------------------------------------------------------------
9
 
10
library IEEE;
11
use IEEE.STD_LOGIC_1164.ALL;
12
use IEEE.NUMERIC_STD.ALL;
13
 
14
entity UART_RX is
15
    Generic (
16
        PARITY_BIT  : string := "none" -- legal values: "none", "even", "odd", "mark", "space"
17
    );
18
    Port (
19
        CLK         : in  std_logic; -- system clock
20
        RST         : in  std_logic; -- high active synchronous reset
21
        -- UART INTERFACE
22
        UART_CLK_EN : in  std_logic; -- oversampling (16x) UART clock enable
23
        UART_RXD    : in  std_logic;
24
        -- USER DATA OUTPUT INTERFACE
25
        DATA_OUT    : out std_logic_vector(7 downto 0);
26
        DATA_VLD    : out std_logic; -- when DATA_VLD = 1, data on DATA_OUT are valid
27
        FRAME_ERROR : out std_logic  -- when FRAME_ERROR = 1, stop bit was invalid, current and next data may be invalid
28
    );
29
end UART_RX;
30
 
31
architecture FULL of UART_RX is
32
 
33
    signal rx_clk_en          : std_logic;
34
    signal rx_ticks           : unsigned(3 downto 0);
35
    signal rx_clk_divider_en  : std_logic;
36
    signal rx_data            : std_logic_vector(7 downto 0);
37
    signal rx_bit_count       : unsigned(2 downto 0);
38
    signal rx_bit_count_en    : std_logic;
39
    signal rx_data_shreg_en   : std_logic;
40
    signal rx_parity_bit      : std_logic;
41
    signal rx_parity_error    : std_logic;
42
    signal rx_parity_check_en : std_logic;
43
    signal rx_output_reg_en   : std_logic;
44
 
45
    type state is (idle, startbit, databits, paritybit, stopbit);
46
    signal rx_pstate : state;
47
    signal rx_nstate : state;
48
 
49
begin
50
 
51
    -- -------------------------------------------------------------------------
52
    -- UART RECEIVER CLOCK DIVIDER
53
    -- -------------------------------------------------------------------------
54
 
55
    uart_rx_clk_divider : process (CLK)
56
    begin
57
        if (rising_edge(CLK)) then
58
            if (rx_clk_divider_en = '1') then
59
                if (uart_clk_en = '1') then
60
                    if (rx_ticks = "1111") then
61
                        rx_ticks <= (others => '0');
62
                        rx_clk_en <= '0';
63
                    elsif (rx_ticks = "0111") then
64
                        rx_ticks <= rx_ticks + 1;
65
                        rx_clk_en <= '1';
66
                    else
67
                        rx_ticks <= rx_ticks + 1;
68
                        rx_clk_en <= '0';
69
                    end if;
70
                else
71
                    rx_ticks <= rx_ticks;
72
                    rx_clk_en <= '0';
73
                end if;
74
            else
75
                rx_ticks <= (others => '0');
76
                rx_clk_en <= '0';
77
            end if;
78
        end if;
79
    end process;
80
 
81
    -- -------------------------------------------------------------------------
82
    -- UART RECEIVER BIT COUNTER
83
    -- -------------------------------------------------------------------------
84
 
85
    uart_rx_bit_counter : process (CLK)
86
    begin
87
        if (rising_edge(CLK)) then
88
            if (RST = '1') then
89
                rx_bit_count <= (others => '0');
90
            elsif (rx_bit_count_en = '1' AND rx_clk_en = '1') then
91
                if (rx_bit_count = "111") then
92
                    rx_bit_count <= (others => '0');
93
                else
94
                    rx_bit_count <= rx_bit_count + 1;
95
                end if;
96
            end if;
97
        end if;
98
    end process;
99
 
100
    -- -------------------------------------------------------------------------
101
    -- UART RECEIVER DATA SHIFT REGISTER
102
    -- -------------------------------------------------------------------------
103
 
104
    uart_rx_data_shift_reg : process (CLK)
105
    begin
106
        if (rising_edge(CLK)) then
107
            if (RST = '1') then
108
                rx_data <= (others => '0');
109
            elsif (rx_clk_en = '1' AND rx_data_shreg_en = '1') then
110
                rx_data <= UART_RXD & rx_data(7 downto 1);
111
            end if;
112
        end if;
113
    end process;
114
 
115
    DATA_OUT <= rx_data;
116
 
117
    -- -------------------------------------------------------------------------
118
    -- UART RECEIVER PARITY GENERATOR AND CHECK
119
    -- -------------------------------------------------------------------------
120
 
121
    uart_rx_parity_g : if (PARITY_BIT /= "none") generate
122
        uart_rx_parity_gen_i: entity work.UART_PARITY
123
        generic map (
124
            DATA_WIDTH  => 8,
125
            PARITY_TYPE => PARITY_BIT
126
        )
127
        port map (
128
            DATA_IN     => rx_data,
129
            PARITY_OUT  => rx_parity_bit
130
        );
131
 
132
        uart_rx_parity_check_reg : process (CLK)
133
        begin
134
            if (rising_edge(CLK)) then
135
                if (RST = '1') then
136
                    rx_parity_error <= '0';
137
                elsif (rx_parity_check_en = '1') then
138
                    rx_parity_error <= rx_parity_bit XOR UART_RXD;
139
                end if;
140
            end if;
141
        end process;
142
    end generate;
143
 
144
    uart_rx_noparity_g : if (PARITY_BIT = "none") generate
145
        rx_parity_error <= '0';
146
    end generate;
147
 
148
    -- -------------------------------------------------------------------------
149
    -- UART RECEIVER OUTPUT REGISTER
150
    -- -------------------------------------------------------------------------
151
 
152
    uart_rx_output_reg : process (CLK)
153
    begin
154
        if (rising_edge(CLK)) then
155
            if (RST = '1') then
156
                DATA_VLD <= '0';
157
                FRAME_ERROR <= '0';
158
            else
159
                if (rx_output_reg_en = '1') then
160
                    DATA_VLD <= NOT rx_parity_error AND UART_RXD;
161
                    FRAME_ERROR <= NOT UART_RXD;
162
                else
163
                    DATA_VLD <= '0';
164
                    FRAME_ERROR <= '0';
165
                end if;
166
            end if;
167
        end if;
168
    end process;
169
 
170
    -- -------------------------------------------------------------------------
171
    -- UART RECEIVER FSM
172
    -- -------------------------------------------------------------------------
173
 
174
    -- PRESENT STATE REGISTER
175
    process (CLK)
176
    begin
177
        if (rising_edge(CLK)) then
178
            if (RST = '1') then
179
                rx_pstate <= idle;
180
            else
181
                rx_pstate <= rx_nstate;
182
            end if;
183
        end if;
184
    end process;
185
 
186
    -- NEXT STATE AND OUTPUTS LOGIC
187
    process (rx_pstate, UART_RXD, rx_clk_en, rx_bit_count)
188
    begin
189
        case rx_pstate is
190
 
191
            when idle =>
192
                rx_output_reg_en <= '0';
193
                rx_bit_count_en <= '0';
194
                rx_data_shreg_en <= '0';
195
                rx_clk_divider_en <= '0';
196
                rx_parity_check_en <= '0';
197
 
198
                if (UART_RXD = '0') then
199
                    rx_nstate <= startbit;
200
                else
201
                    rx_nstate <= idle;
202
                end if;
203
 
204
            when startbit =>
205
                rx_output_reg_en <= '0';
206
                rx_bit_count_en <= '0';
207
                rx_data_shreg_en <= '0';
208
                rx_clk_divider_en <= '1';
209
                rx_parity_check_en <= '0';
210
 
211
                if (rx_clk_en = '1') then
212
                    rx_nstate <= databits;
213
                else
214
                    rx_nstate <= startbit;
215
                end if;
216
 
217
            when databits =>
218
                rx_output_reg_en <= '0';
219
                rx_bit_count_en <= '1';
220
                rx_data_shreg_en <= '1';
221
                rx_clk_divider_en <= '1';
222
                rx_parity_check_en <= '0';
223
 
224
                if ((rx_clk_en = '1') AND (rx_bit_count = "111")) then
225
                    if (PARITY_BIT = "none") then
226
                        rx_nstate <= stopbit;
227
                    else
228
                        rx_nstate <= paritybit;
229
                    end if ;
230
                else
231
                    rx_nstate <= databits;
232
                end if;
233
 
234
            when paritybit =>
235
                rx_output_reg_en <= '0';
236
                rx_bit_count_en <= '0';
237
                rx_data_shreg_en <= '0';
238
                rx_clk_divider_en <= '1';
239
                rx_parity_check_en <= '1';
240
 
241
                if (rx_clk_en = '1') then
242
                    rx_nstate <= stopbit;
243
                else
244
                    rx_nstate <= paritybit;
245
                end if;
246
 
247
            when stopbit =>
248
                rx_bit_count_en <= '0';
249
                rx_data_shreg_en <= '0';
250
                rx_clk_divider_en <= '1';
251
                rx_parity_check_en <= '0';
252
 
253
                if (rx_clk_en = '1') then
254
                    rx_nstate <= idle;
255
                    rx_output_reg_en <= '1';
256
                else
257
                    rx_nstate <= stopbit;
258
                    rx_output_reg_en <= '0';
259
                end if;
260
 
261
            when others =>
262
                rx_output_reg_en <= '0';
263
                rx_bit_count_en <= '0';
264
                rx_data_shreg_en <= '0';
265
                rx_clk_divider_en <= '0';
266
                rx_parity_check_en <= '0';
267
                rx_nstate <= idle;
268
 
269
        end case;
270
    end process;
271
 
272
end FULL;

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.