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

Subversion Repositories uart16750

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

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

powered by: WebSVN 2.1.0

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