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

Subversion Repositories uart16750

[/] [uart16750/] [trunk/] [rtl/] [vhdl/] [uart_receiver.vhd] - Blame information for rev 20

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 hasw
--
2
-- UART receiver
3
--
4
-- Author:   Sebastian Witt
5
-- Date:     27.01.2008
6 20 hasw
-- Version:  1.2
7 2 hasw
--
8
-- This code is free software; you can redistribute it and/or
9
-- modify it under the terms of the GNU Lesser General Public
10
-- License as published by the Free Software Foundation; either
11
-- version 2.1 of the License, or (at your option) any later version.
12
--
13
-- This code is distributed in the hope that it will be useful,
14
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
15
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16
-- Lesser General Public License for more details.
17
--
18
-- You should have received a copy of the GNU Lesser General Public
19
-- License along with this library; if not, write to the
20
-- Free Software  Foundation, Inc., 59 Temple Place, Suite 330,
21
-- Boston, MA  02111-1307  USA
22
--
23
 
24
LIBRARY IEEE;
25
USE IEEE.std_logic_1164.all;
26
USE IEEE.numeric_std.all;
27
 
28
-- Serial UART receiver
29
entity uart_receiver is
30
    port (
31
        CLK         : in std_logic;                                 -- Clock
32
        RST         : in std_logic;                                 -- Reset
33
        RXCLK       : in std_logic;                                 -- Receiver clock (16x baudrate)
34
        RXCLEAR     : in std_logic;                                 -- Reset receiver state
35
        WLS         : in std_logic_vector(1 downto 0);              -- Word length select
36
        STB         : in std_logic;                                 -- Number of stop bits
37
        PEN         : in std_logic;                                 -- Parity enable
38
        EPS         : in std_logic;                                 -- Even parity select
39
        SP          : in std_logic;                                 -- Stick parity
40
        SIN         : in std_logic;                                 -- Receiver input
41
        PE          : out std_logic;                                -- Parity error
42
        FE          : out std_logic;                                -- Framing error
43
        BI          : out std_logic;                                -- Break interrupt
44
        DOUT        : out std_logic_vector(7 downto 0);             -- Output data
45
        RXFINISHED  : out std_logic                                 -- Receiver operation finished
46
    );
47
end uart_receiver;
48
 
49
architecture rtl of uart_receiver is
50
    -- Majority voting logic
51
    component slib_mv_filter is
52
        generic (
53
            WIDTH       : natural := 4;
54
            THRESHOLD   : natural := 10
55
        );
56
        port (
57
            CLK         : in std_logic;                             -- Clock
58
            RST         : in std_logic;                             -- Reset
59
            SAMPLE      : in std_logic;                             -- Clock enable for sample process
60
            CLEAR       : in std_logic;                             -- Reset process
61
            D           : in std_logic;                             -- Signal input
62
            Q           : out std_logic                             -- Signal D was at least THRESHOLD samples high
63
        );
64
    end component;
65 20 hasw
    component slib_input_filter is
66
        generic (
67
            SIZE        : natural := 4      -- Filter counter size
68
        );
69
        port (
70
            CLK         : in std_logic;     -- Clock
71
            RST         : in std_logic;     -- Reset
72
            CE          : in std_logic;     -- Clock enable
73
            D           : in std_logic;     -- Signal input
74
            Q           : out std_logic     -- Signal output
75
        );
76
    end component;
77
 
78 2 hasw
    -- Counter
79
    component slib_counter is
80
        generic (
81
            WIDTH       : natural := 4       -- Counter width
82
        );
83
        port (
84
            CLK         : in std_logic;      -- Clock
85
            RST         : in std_logic;      -- Reset
86
            CLEAR       : in std_logic;      -- Clear counter register
87
            LOAD        : in std_logic;      -- Load counter register
88
            ENABLE      : in std_logic;      -- Enable count operation
89
            DOWN        : in std_logic;      -- Count direction down
90
            D           : in std_logic_vector(WIDTH-1 downto 0);    -- Load counter register input
91
            Q           : out std_logic_vector(WIDTH-1 downto 0);   -- Shift register output
92
            OVERFLOW    : out std_logic      -- Counter overflow
93
        );
94
    end component;
95
 
96
    -- FSM
97
    type state_type is (IDLE, START, DATA, PAR, STOP, MWAIT);
98
    signal CState, NState : state_type;
99
 
100
    -- Signals
101 20 hasw
    signal iBaudCount          : std_logic_vector(3 downto 0);      -- Baud counter output
102 2 hasw
    signal iBaudCountClear     : std_logic;                         -- Baud counter clear
103
    signal iBaudStep           : std_logic;                         -- Next symbol pulse
104
    signal iBaudStepD          : std_logic;                         -- Next symbol pulse delayed by one clock
105
    signal iFilterClear        : std_logic;                         -- Reset input filter
106
    signal iFSIN               : std_logic;                         -- Filtered SIN
107 20 hasw
    signal iFStopBit           : std_logic;                         -- Filtered SIN for stop bit detection
108 2 hasw
    signal iParity             : std_logic;                         -- Data parity
109
    signal iParityReceived     : std_logic;                         -- Parity received
110
    signal iDataCount          : integer range 0 to 8;              -- Data bit counter
111
    signal iDataCountInit      : std_logic;                         -- Initialize data bit counter to word length
112
    signal iDataCountFinish    : std_logic;                         -- Data bit counter finished
113
    signal iRXFinished         : std_logic;                         -- Word received, output data valid
114
    signal iFE                 : std_logic;                         -- Internal frame error
115
    signal iBI                 : std_logic;                         -- Internal break interrupt
116
    signal iNoStopReceived     : std_logic;                         -- No valid stop bit received
117
    signal iDOUT               : std_logic_vector(7 downto 0);      -- Data output
118
 
119
begin
120
 
121
    -- Baudrate counter: RXCLK/16
122
    RX_BRC: slib_counter generic map (
123
                                WIDTH       => 4
124
                         ) port map (
125
                                CLK         => CLK,
126
                                RST         => RST,
127
                                CLEAR       => iBaudCountClear,
128
                                LOAD        => '0',
129
                                ENABLE      => RXCLK,
130
                                DOWN        => '0',
131
                                D           => x"0",
132 20 hasw
                                Q           => iBaudCount,
133 2 hasw
                                OVERFLOW    => iBaudStep
134
                         );
135
 
136
    -- Input filter
137
    RX_MVF: slib_mv_filter generic map (
138
                                WIDTH       => 4,
139
                                THRESHOLD   => 10
140
                           ) port map (
141
                                CLK         => CLK,
142
                                RST         => RST,
143
                                SAMPLE      => RXCLK,
144
                                CLEAR       => iFilterClear,
145
                                D           => SIN,
146
                                Q           => iFSIN
147
                            );
148
 
149 20 hasw
    -- Input filter for the stop bit
150
    RX_IFSB: slib_input_filter generic map (
151
                                SIZE        => 4
152
                           ) port map (
153
                                CLK         => CLK,
154
                                RST         => RST,
155
                                CE          => RXCLK,
156
                                D           => SIN,
157
                                Q           => iFStopBit
158
                            );
159
 
160 2 hasw
    -- iBaudStepD
161
    RX_IFC: process (CLK, RST)
162
    begin
163
        if (RST = '1') then
164
            iBaudStepD <= '0';
165
        elsif (CLK'event and CLK = '1') then
166
            iBaudStepD <= iBaudStep;
167
        end if;
168
    end process;
169
 
170
    iFilterClear <= iBaudStepD or iBaudCountClear;
171
 
172
    -- Parity generation
173
    RX_PAR: process (iDOUT, EPS)
174
    begin
175
        iParity <= iDOUT(7) xor iDOUT(6) xor iDOUT(5) xor iDOUT(4) xor iDOUT(3) xor iDOUT(2) xor iDOUT(1) xor iDOUT(0) xor not EPS;
176
    end process;
177
 
178
    -- Data bit capture
179
    RX_DATACOUNT: process (CLK, RST)
180
    begin
181
        if (RST = '1') then
182
            iDataCount <= 0;
183
            iDOUT <= (others => '0');
184
        elsif (CLK'event and CLK = '1') then
185
            if (iDataCountInit = '1') then
186
                iDataCount <= 0;
187
                iDOUT <= (others => '0');
188
            else
189
                if (iBaudStep = '1' and iDataCountFinish = '0') then
190
                    iDOUT(iDataCount) <= iFSIN;
191
                    iDataCount <= iDataCount + 1;
192
                end if;
193
            end if;
194
        end if;
195
    end process;
196
 
197
    iDataCountFinish <= '1' when (WLS = "00" and iDataCount = 5) or
198
                                 (WLS = "01" and iDataCount = 6) or
199
                                 (WLS = "10" and iDataCount = 7) or
200
                                 (WLS = "11" and iDataCount = 8) else '0';
201
 
202
    -- FSM update process
203
    RX_FSMUPDATE: process (CLK, RST)
204
    begin
205
        if (RST = '1') then
206
            CState <= IDLE;
207
        elsif (CLK'event and CLK = '1') then
208
            CState <= NState;
209
        end if;
210
    end process;
211
 
212
    -- RX FSM
213 20 hasw
    RX_FSM: process (CState, SIN, iFSIN, iFStopBit, iBaudStep, iBaudCount, iDataCountFinish, PEN, WLS, STB)
214 2 hasw
    begin
215
        -- Defaults
216
        NState          <= IDLE;
217
        iBaudCountClear <= '0';
218
        iDataCountInit  <= '0';
219
        iRXFinished     <= '0';
220
 
221
        case CState is
222
            when IDLE   =>  if (SIN = '0') then                 -- Start detected
223
                                NState <= START;
224
                            end if;
225
                            iBaudCountClear <= '1';
226
                            iDataCountInit  <= '1';
227
            when START  =>  iDataCountInit  <= '1';
228
                            if (iBaudStep = '1') then           -- Wait for start bit end
229
                                if (iFSIN = '0') then
230
                                    NState <= DATA;
231
                                end if;
232
                            else
233
                                NState <= START;
234
                            end if;
235
            when DATA   =>  if (iDataCountFinish = '1') then    -- Received all data bits
236
                                if (PEN = '1') then
237
                                    NState <= PAR;              -- Parity enabled
238
                                else
239
                                    NState <= STOP;             -- No parity
240
                                end if;
241
                            else
242
                                NState <= DATA;
243
                            end if;
244
            when PAR    =>  if (iBaudStep = '1') then           -- Wait for parity bit
245
                                NState <= STOP;
246
                            else
247
                                NState <= PAR;
248
                            end if;
249 20 hasw
            when STOP   =>  if (iBaudCount(3) = '1') then       -- Wait for stop bit
250
                                if (iFStopBit = '0') then       -- No stop bit received
251 2 hasw
                                    iRXFinished <= '1';
252
                                    NState <= MWAIT;
253
                                else
254
                                    iRXFinished <= '1';
255
                                    NState <= IDLE;             -- Stop bit end
256
                                end if;
257
                            else
258
                                NState <= STOP;
259
                            end if;
260
            when MWAIT  =>  if (SIN = '0') then                 -- Wait for mark
261
                                NState <= MWAIT;
262
                            end if;
263
            when others =>  null;
264
        end case;
265
    end process;
266
 
267
    -- Check parity
268
    RX_PARCHECK: process (CLK, RST)
269
    begin
270
        if (RST = '1') then
271
            PE <= '0';
272
            iParityReceived <= '0';
273
        elsif (CLK'event and CLK = '1') then
274
            if (CState = PAR and iBaudStep = '1') then
275
                iParityReceived <= iFSIN;                       -- Received parity bit
276
            end if;
277
 
278
            -- Check parity
279
            if (PEN = '1') then                                 -- Parity enabled
280
                PE <= '0';
281
                if (SP = '1') then                              -- Sticky parity
282
                    if ((EPS xor iParityReceived) = '0') then
283
                        PE <= '1';                              -- Parity error
284
                    end if;
285
                else
286
                    if (iParity /= iParityReceived) then
287
                        PE <= '1';                              -- Parity error
288
                    end if;
289
                end if;
290
            else
291
                PE <= '0';                                      -- Parity disabled
292
                iParityReceived <= '0';
293
            end if;
294
        end if;
295
    end process;
296
 
297
    -- Framing error and break interrupt
298 20 hasw
    iNoStopReceived <= '1' when iFStopBit = '0' and (CState = STOP) else '0';
299 2 hasw
    iBI <= '1' when iDOUT = "00000000" and
300
                    iParityReceived = '0' and
301
                    iNoStopReceived = '1' else '0';
302
    iFE <= '1' when iNoStopReceived = '1' else '0';
303
 
304
    -- Output signals
305
    DOUT <= iDOUT;
306
    BI   <= iBI;
307
    FE   <= iFE;
308
    RXFINISHED <= iRXFinished;
309
 
310
end rtl;
311
 

powered by: WebSVN 2.1.0

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