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

Subversion Repositories uart16750

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

Go to most recent revision | 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
-- Version:  1.1
7
--
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.std_logic_unsigned.all;
27
USE IEEE.numeric_std.all;
28
 
29
-- Serial UART receiver
30
entity uart_receiver is
31
    port (
32
        CLK         : in std_logic;                                 -- Clock
33
        RST         : in std_logic;                                 -- Reset
34
        RXCLK       : in std_logic;                                 -- Receiver clock (16x baudrate)
35
        RXCLEAR     : in std_logic;                                 -- Reset receiver state
36
        WLS         : in std_logic_vector(1 downto 0);              -- Word length select
37
        STB         : in std_logic;                                 -- Number of stop bits
38
        PEN         : in std_logic;                                 -- Parity enable
39
        EPS         : in std_logic;                                 -- Even parity select
40
        SP          : in std_logic;                                 -- Stick parity
41
        SIN         : in std_logic;                                 -- Receiver input
42
        PE          : out std_logic;                                -- Parity error
43
        FE          : out std_logic;                                -- Framing error
44
        BI          : out std_logic;                                -- Break interrupt
45
        DOUT        : out std_logic_vector(7 downto 0);             -- Output data
46
        RXFINISHED  : out std_logic                                 -- Receiver operation finished
47
    );
48
end uart_receiver;
49
 
50
architecture rtl of uart_receiver is
51
    -- Serial shift register
52
    component slib_shift_reg is
53
        generic (
54
            WIDTH : natural := 16                                   -- Register width
55
        );
56
        port (
57
            CLK         : in std_logic;                             -- Clock
58
            RST         : in std_logic;                             -- Reset
59
            ENABLE      : in std_logic;                             -- Enable shift operation
60
            LOAD        : in std_logic;                             -- Load shift register
61
            DIR         : in std_logic;                             -- Shift direction
62
            MSB_IN      : in std_logic;                             -- MSB in
63
            LSB_IN      : in std_logic;                             -- LSB in
64
            DIN         : in std_logic_vector(WIDTH-1 downto 0);    -- Load shift register input
65
            DOUT        : out std_logic_vector(WIDTH-1 downto 0)    -- Shift register output
66
        );
67
    end component;
68
    -- Majority voting logic
69
    component slib_mv_filter is
70
        generic (
71
            WIDTH       : natural := 4;
72
            THRESHOLD   : natural := 10
73
        );
74
        port (
75
            CLK         : in std_logic;                             -- Clock
76
            RST         : in std_logic;                             -- Reset
77
            SAMPLE      : in std_logic;                             -- Clock enable for sample process
78
            CLEAR       : in std_logic;                             -- Reset process
79
            D           : in std_logic;                             -- Signal input
80
            Q           : out std_logic                             -- Signal D was at least THRESHOLD samples high
81
        );
82
    end component;
83
    -- Counter
84
    component slib_counter is
85
        generic (
86
            WIDTH       : natural := 4       -- Counter width
87
        );
88
        port (
89
            CLK         : in std_logic;      -- Clock
90
            RST         : in std_logic;      -- Reset
91
            CLEAR       : in std_logic;      -- Clear counter register
92
            LOAD        : in std_logic;      -- Load counter register
93
            ENABLE      : in std_logic;      -- Enable count operation
94
            DOWN        : in std_logic;      -- Count direction down
95
            D           : in std_logic_vector(WIDTH-1 downto 0);    -- Load counter register input
96
            Q           : out std_logic_vector(WIDTH-1 downto 0);   -- Shift register output
97
            OVERFLOW    : out std_logic      -- Counter overflow
98
        );
99
    end component;
100
 
101
    -- FSM
102
    type state_type is (IDLE, START, DATA, PAR, STOP, MWAIT);
103
    signal CState, NState : state_type;
104
 
105
    -- Signals
106
    signal iBaudCountClear     : std_logic;                         -- Baud counter clear
107
    signal iBaudStep           : std_logic;                         -- Next symbol pulse
108
    signal iBaudStepD          : std_logic;                         -- Next symbol pulse delayed by one clock
109
    signal iFilterClear        : std_logic;                         -- Reset input filter
110
    signal iFSIN               : std_logic;                         -- Filtered SIN
111
    signal iParity             : std_logic;                         -- Data parity
112
    signal iParityReceived     : std_logic;                         -- Parity received
113
    signal iDataCount          : integer range 0 to 8;              -- Data bit counter
114
    signal iDataCountInit      : std_logic;                         -- Initialize data bit counter to word length
115
    signal iDataCountFinish    : std_logic;                         -- Data bit counter finished
116
    signal iRXFinished         : std_logic;                         -- Word received, output data valid
117
    signal iFE                 : std_logic;                         -- Internal frame error
118
    signal iBI                 : std_logic;                         -- Internal break interrupt
119
    signal iNoStopReceived     : std_logic;                         -- No valid stop bit received
120
    signal iDOUT               : std_logic_vector(7 downto 0);      -- Data output
121
 
122
begin
123
 
124
    -- Baudrate counter: RXCLK/16
125
    RX_BRC: slib_counter generic map (
126
                                WIDTH       => 4
127
                         ) port map (
128
                                CLK         => CLK,
129
                                RST         => RST,
130
                                CLEAR       => iBaudCountClear,
131
                                LOAD        => '0',
132
                                ENABLE      => RXCLK,
133
                                DOWN        => '0',
134
                                D           => x"0",
135
                                OVERFLOW    => iBaudStep
136
                         );
137
 
138
    -- Input filter
139
    RX_MVF: slib_mv_filter generic map (
140
                                WIDTH       => 4,
141
                                THRESHOLD   => 10
142
                           ) port map (
143
                                CLK         => CLK,
144
                                RST         => RST,
145
                                SAMPLE      => RXCLK,
146
                                CLEAR       => iFilterClear,
147
                                D           => SIN,
148
                                Q           => iFSIN
149
                            );
150
 
151
    -- iBaudStepD
152
    RX_IFC: process (CLK, RST)
153
    begin
154
        if (RST = '1') then
155
            iBaudStepD <= '0';
156
        elsif (CLK'event and CLK = '1') then
157
            iBaudStepD <= iBaudStep;
158
        end if;
159
    end process;
160
 
161
    iFilterClear <= iBaudStepD or iBaudCountClear;
162
 
163
    -- Parity generation
164
    RX_PAR: process (iDOUT, EPS)
165
    begin
166
        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;
167
    end process;
168
 
169
    -- Data bit capture
170
    RX_DATACOUNT: process (CLK, RST)
171
    begin
172
        if (RST = '1') then
173
            iDataCount <= 0;
174
            iDOUT <= (others => '0');
175
        elsif (CLK'event and CLK = '1') then
176
            if (iDataCountInit = '1') then
177
                iDataCount <= 0;
178
                iDOUT <= (others => '0');
179
            else
180
                if (iBaudStep = '1' and iDataCountFinish = '0') then
181
                    iDOUT(iDataCount) <= iFSIN;
182
                    iDataCount <= iDataCount + 1;
183
                end if;
184
            end if;
185
        end if;
186
    end process;
187
 
188
    iDataCountFinish <= '1' when (WLS = "00" and iDataCount = 5) or
189
                                 (WLS = "01" and iDataCount = 6) or
190
                                 (WLS = "10" and iDataCount = 7) or
191
                                 (WLS = "11" and iDataCount = 8) else '0';
192
 
193
    -- FSM update process
194
    RX_FSMUPDATE: process (CLK, RST)
195
    begin
196
        if (RST = '1') then
197
            CState <= IDLE;
198
        elsif (CLK'event and CLK = '1') then
199
            CState <= NState;
200
        end if;
201
    end process;
202
 
203
    -- RX FSM
204
    RX_FSM: process (CState, SIN, iFSIN, iBaudStep, iDataCountFinish, PEN, WLS, STB)
205
    begin
206
        -- Defaults
207
        NState          <= IDLE;
208
        iBaudCountClear <= '0';
209
        iDataCountInit  <= '0';
210
        iRXFinished     <= '0';
211
 
212
        case CState is
213
            when IDLE   =>  if (SIN = '0') then                 -- Start detected
214
                                NState <= START;
215
                            end if;
216
                            iBaudCountClear <= '1';
217
                            iDataCountInit  <= '1';
218
            when START  =>  iDataCountInit  <= '1';
219
                            if (iBaudStep = '1') then           -- Wait for start bit end
220
                                if (iFSIN = '0') then
221
                                    NState <= DATA;
222
                                end if;
223
                            else
224
                                NState <= START;
225
                            end if;
226
            when DATA   =>  if (iDataCountFinish = '1') then    -- Received all data bits
227
                                if (PEN = '1') then
228
                                    NState <= PAR;              -- Parity enabled
229
                                else
230
                                    NState <= STOP;             -- No parity
231
                                end if;
232
                            else
233
                                NState <= DATA;
234
                            end if;
235
            when PAR    =>  if (iBaudStep = '1') then           -- Wait for parity bit
236
                                NState <= STOP;
237
                            else
238
                                NState <= PAR;
239
                            end if;
240
            when STOP   =>  if (iBaudStep = '1') then           -- Wait for stop bit
241
                                if (iFSIN = '0') then           -- No stop bit received
242
                                    iRXFinished <= '1';
243
                                    NState <= MWAIT;
244
                                else
245
                                    iRXFinished <= '1';
246
                                    NState <= IDLE;             -- Stop bit end
247
                                end if;
248
                            else
249
                                NState <= STOP;
250
                            end if;
251
            when MWAIT  =>  if (SIN = '0') then                 -- Wait for mark
252
                                NState <= MWAIT;
253
                            end if;
254
            when others =>  null;
255
        end case;
256
    end process;
257
 
258
    -- Check parity
259
    RX_PARCHECK: process (CLK, RST)
260
    begin
261
        if (RST = '1') then
262
            PE <= '0';
263
            iParityReceived <= '0';
264
        elsif (CLK'event and CLK = '1') then
265
            if (CState = PAR and iBaudStep = '1') then
266
                iParityReceived <= iFSIN;                       -- Received parity bit
267
            end if;
268
 
269
            -- Check parity
270
            if (PEN = '1') then                                 -- Parity enabled
271
                PE <= '0';
272
                if (SP = '1') then                              -- Sticky parity
273
                    if ((EPS xor iParityReceived) = '0') then
274
                        PE <= '1';                              -- Parity error
275
                    end if;
276
                else
277
                    if (iParity /= iParityReceived) then
278
                        PE <= '1';                              -- Parity error
279
                    end if;
280
                end if;
281
            else
282
                PE <= '0';                                      -- Parity disabled
283
                iParityReceived <= '0';
284
            end if;
285
        end if;
286
    end process;
287
 
288
    -- Framing error and break interrupt
289
    iNoStopReceived <= '1' when iFSIN = '0' and (CState = STOP) else '0';
290
    iBI <= '1' when iDOUT = "00000000" and
291
                    iParityReceived = '0' and
292
                    iNoStopReceived = '1' else '0';
293
    iFE <= '1' when iNoStopReceived = '1' else '0';
294
 
295
    -- Output signals
296
    DOUT <= iDOUT;
297
    BI   <= iBI;
298
    FE   <= iFE;
299
    RXFINISHED <= iRXFinished;
300
 
301
end rtl;
302
 

powered by: WebSVN 2.1.0

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