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

Subversion Repositories signed_unsigned_multiplier_and_divider

[/] [signed_unsigned_multiplier_and_divider/] [trunk/] [uart-for-fpga-master/] [source/] [comp/] [uart_rx.vhd] - Blame information for rev 2

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 zpekic
--------------------------------------------------------------------------------
2
-- PROJECT: SIMPLE UART FOR FPGA
3
--------------------------------------------------------------------------------
4
-- MODULE:  UART RECEIVER
5
-- AUTHORS: Jakub Cabal <jakubcabal@gmail.com>
6
-- LICENSE: The MIT License (MIT), please read LICENSE file
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" -- type of parity: "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; -- serial receive data
24
        -- USER DATA OUTPUT INTERFACE
25
        DATA_OUT    : out std_logic_vector(7 downto 0); -- output data
26
        DATA_VLD    : out std_logic; -- when DATA_VLD = 1, output data are valid
27
        FRAME_ERROR : out std_logic  -- when FRAME_ERROR = 1, stop bit was 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_receiving_data  : std_logic;
39
    signal rx_parity_bit      : std_logic;
40
    signal rx_parity_error    : std_logic;
41
    signal rx_parity_check_en : std_logic;
42
    signal rx_output_reg_en   : std_logic;
43
 
44
    type state is (idle, startbit, databits, paritybit, stopbit);
45
    signal rx_pstate : state;
46
    signal rx_nstate : state;
47
 
48
begin
49
 
50
    -- -------------------------------------------------------------------------
51
    -- UART RECEIVER CLOCK DIVIDER AND CLOCK ENABLE FLAG
52
    -- -------------------------------------------------------------------------
53
 
54
    uart_rx_clk_divider_p : process (CLK)
55
    begin
56
        if (rising_edge(CLK)) then
57
            if (rx_clk_divider_en = '1') then
58
                if (uart_clk_en = '1') then
59
                    if (rx_ticks = "1111") then
60
                        rx_ticks <= (others => '0');
61
                    else
62
                        rx_ticks <= rx_ticks + 1;
63
                    end if;
64
                else
65
                    rx_ticks <= rx_ticks;
66
                end if;
67
            else
68
                rx_ticks <= (others => '0');
69
            end if;
70
        end if;
71
    end process;
72
 
73
    uart_rx_clk_en_p : process (CLK)
74
    begin
75
        if (rising_edge(CLK)) then
76
            if (RST = '1') then
77
                rx_clk_en <= '0';
78
            elsif (uart_clk_en = '1' AND rx_ticks = "0111") then
79
                rx_clk_en <= '1';
80
            else
81
                rx_clk_en <= '0';
82
            end if;
83
        end if;
84
    end process;
85
 
86
    -- -------------------------------------------------------------------------
87
    -- UART RECEIVER BIT COUNTER
88
    -- -------------------------------------------------------------------------
89
 
90
    uart_rx_bit_counter_p : process (CLK)
91
    begin
92
        if (rising_edge(CLK)) then
93
            if (RST = '1') then
94
                rx_bit_count <= (others => '0');
95
            elsif (rx_clk_en = '1' AND rx_receiving_data = '1') then
96
                if (rx_bit_count = "111") then
97
                    rx_bit_count <= (others => '0');
98
                else
99
                    rx_bit_count <= rx_bit_count + 1;
100
                end if;
101
            end if;
102
        end if;
103
    end process;
104
 
105
    -- -------------------------------------------------------------------------
106
    -- UART RECEIVER DATA SHIFT REGISTER
107
    -- -------------------------------------------------------------------------
108
 
109
    uart_rx_data_shift_reg_p : process (CLK)
110
    begin
111
        if (rising_edge(CLK)) then
112
            if (RST = '1') then
113
                rx_data <= (others => '0');
114
            elsif (rx_clk_en = '1' AND rx_receiving_data = '1') then
115
                rx_data <= UART_RXD & rx_data(7 downto 1);
116
            end if;
117
        end if;
118
    end process;
119
 
120
    DATA_OUT <= rx_data;
121
 
122
    -- -------------------------------------------------------------------------
123
    -- UART RECEIVER PARITY GENERATOR AND CHECK
124
    -- -------------------------------------------------------------------------
125
 
126
    uart_rx_parity_g : if (PARITY_BIT /= "none") generate
127
        uart_rx_parity_gen_i: entity work.UART_PARITY
128
        generic map (
129
            DATA_WIDTH  => 8,
130
            PARITY_TYPE => PARITY_BIT
131
        )
132
        port map (
133
            DATA_IN     => rx_data,
134
            PARITY_OUT  => rx_parity_bit
135
        );
136
 
137
        uart_rx_parity_check_reg_p : process (CLK)
138
        begin
139
            if (rising_edge(CLK)) then
140
                if (RST = '1') then
141
                    rx_parity_error <= '0';
142
                elsif (rx_parity_check_en = '1') then
143
                    rx_parity_error <= rx_parity_bit XOR UART_RXD;
144
                end if;
145
            end if;
146
        end process;
147
    end generate;
148
 
149
    uart_rx_noparity_g : if (PARITY_BIT = "none") generate
150
        rx_parity_error <= '0';
151
    end generate;
152
 
153
    -- -------------------------------------------------------------------------
154
    -- UART RECEIVER OUTPUT REGISTER
155
    -- -------------------------------------------------------------------------
156
 
157
    uart_rx_output_reg_p : process (CLK)
158
    begin
159
        if (rising_edge(CLK)) then
160
            if (RST = '1') then
161
                DATA_VLD <= '0';
162
                FRAME_ERROR <= '0';
163
            else
164
                if (rx_clk_en = '1' AND rx_output_reg_en = '1') then
165
                    DATA_VLD <= NOT rx_parity_error AND UART_RXD;
166
                    FRAME_ERROR <= NOT UART_RXD;
167
                else
168
                    DATA_VLD <= '0';
169
                    FRAME_ERROR <= '0';
170
                end if;
171
            end if;
172
        end if;
173
    end process;
174
 
175
    -- -------------------------------------------------------------------------
176
    -- UART RECEIVER FSM
177
    -- -------------------------------------------------------------------------
178
 
179
    -- PRESENT STATE REGISTER
180
    process (CLK)
181
    begin
182
        if (rising_edge(CLK)) then
183
            if (RST = '1') then
184
                rx_pstate <= idle;
185
            else
186
                rx_pstate <= rx_nstate;
187
            end if;
188
        end if;
189
    end process;
190
 
191
    -- NEXT STATE AND OUTPUTS LOGIC
192
    process (rx_pstate, UART_RXD, rx_clk_en, rx_bit_count)
193
    begin
194
        case rx_pstate is
195
 
196
            when idle =>
197
                rx_output_reg_en <= '0';
198
                rx_receiving_data <= '0';
199
                rx_clk_divider_en <= '0';
200
                rx_parity_check_en <= '0';
201
 
202
                if (UART_RXD = '0') then
203
                    rx_nstate <= startbit;
204
                else
205
                    rx_nstate <= idle;
206
                end if;
207
 
208
            when startbit =>
209
                rx_output_reg_en <= '0';
210
                rx_receiving_data <= '0';
211
                rx_clk_divider_en <= '1';
212
                rx_parity_check_en <= '0';
213
 
214
                if (rx_clk_en = '1') then
215
                    rx_nstate <= databits;
216
                else
217
                    rx_nstate <= startbit;
218
                end if;
219
 
220
            when databits =>
221
                rx_output_reg_en <= '0';
222
                rx_receiving_data <= '1';
223
                rx_clk_divider_en <= '1';
224
                rx_parity_check_en <= '0';
225
 
226
                if ((rx_clk_en = '1') AND (rx_bit_count = "111")) then
227
                    if (PARITY_BIT = "none") then
228
                        rx_nstate <= stopbit;
229
                    else
230
                        rx_nstate <= paritybit;
231
                    end if ;
232
                else
233
                    rx_nstate <= databits;
234
                end if;
235
 
236
            when paritybit =>
237
                rx_output_reg_en <= '0';
238
                rx_receiving_data <= '0';
239
                rx_clk_divider_en <= '1';
240
                rx_parity_check_en <= '1';
241
 
242
                if (rx_clk_en = '1') then
243
                    rx_nstate <= stopbit;
244
                else
245
                    rx_nstate <= paritybit;
246
                end if;
247
 
248
            when stopbit =>
249
                rx_receiving_data <= '0';
250
                rx_clk_divider_en <= '1';
251
                rx_parity_check_en <= '0';
252
                rx_output_reg_en <= '1';
253
 
254
                if (rx_clk_en = '1') then
255
                    rx_nstate <= idle;
256
                else
257
                    rx_nstate <= stopbit;
258
                end if;
259
 
260
            when others =>
261
                rx_output_reg_en <= '0';
262
                rx_receiving_data <= '0';
263
                rx_clk_divider_en <= '0';
264
                rx_parity_check_en <= '0';
265
                rx_nstate <= idle;
266
 
267
        end case;
268
    end process;
269
 
270
end FULL;

powered by: WebSVN 2.1.0

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