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

Subversion Repositories uart16750

[/] [uart16750/] [trunk/] [rtl/] [vhdl/] [uart_16750.vhd] - Blame information for rev 15

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 hasw
--
2
-- UART 16750
3
--
4
-- Author:   Sebastian Witt
5
-- Date:     29.01.2008
6 15 hasw
-- Version:  1.4
7 2 hasw
--
8
-- History:  1.0 - Initial version
9 6 hasw
--           1.1 - THR empty interrupt register connected to RST
10 9 hasw
--           1.2 - Registered outputs
11 13 hasw
--           1.3 - Automatic flow control
12 15 hasw
--           1.4 - De-assert IIR FIFO64 when FIFO is disabled
13 2 hasw
--
14
--
15
-- This code is free software; you can redistribute it and/or
16
-- modify it under the terms of the GNU Lesser General Public
17
-- License as published by the Free Software Foundation; either
18
-- version 2.1 of the License, or (at your option) any later version.
19
--
20
-- This code is distributed in the hope that it will be useful,
21
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
22
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
23
-- Lesser General Public License for more details.
24
--
25
-- You should have received a copy of the GNU Lesser General Public
26
-- License along with this library; if not, write to the
27
-- Free Software  Foundation, Inc., 59 Temple Place, Suite 330,
28
-- Boston, MA  02111-1307  USA
29
--
30
 
31
LIBRARY IEEE;
32
USE IEEE.std_logic_1164.all;
33
USE IEEE.numeric_std.all;
34
 
35
-- Serial UART
36
entity uart_16750 is
37
    port (
38
        CLK         : in std_logic;                             -- Clock
39
        RST         : in std_logic;                             -- Reset
40
        BAUDCE      : in std_logic;                             -- Baudrate generator clock enable
41
        CS          : in std_logic;                             -- Chip select
42
        WR          : in std_logic;                             -- Write to UART
43
        RD          : in std_logic;                             -- Read from UART
44
        A           : in std_logic_vector(2 downto 0);          -- Register select
45
        DIN         : in std_logic_vector(7 downto 0);          -- Data bus input
46
        DOUT        : out std_logic_vector(7 downto 0);         -- Data bus output
47
        DDIS        : out std_logic;                            -- Driver disable
48
        INT         : out std_logic;                            -- Interrupt output
49
        OUT1N       : out std_logic;                            -- Output 1
50
        OUT2N       : out std_logic;                            -- Output 2
51
        RCLK        : in std_logic;                             -- Receiver clock (16x baudrate)
52
        BAUDOUTN    : out std_logic;                            -- Baudrate generator output (16x baudrate)
53
        RTSN        : out std_logic;                            -- RTS output
54
        DTRN        : out std_logic;                            -- DTR output
55
        CTSN        : in std_logic;                             -- CTS input
56
        DSRN        : in std_logic;                             -- DSR input
57
        DCDN        : in std_logic;                             -- DCD input
58
        RIN         : in std_logic;                             -- RI input
59
        SIN         : in std_logic;                             -- Receiver input
60
        SOUT        : out std_logic                             -- Transmitter output
61
    );
62
end uart_16750;
63
 
64
architecture rtl of uart_16750 is
65
    -- UART transmitter
66
    component uart_transmitter is
67
    port (
68
        CLK         : in std_logic;                             -- Clock
69
        RST         : in std_logic;                             -- Reset
70
        TXCLK       : in std_logic;                             -- Transmitter clock (2x baudrate)
71
        TXSTART     : in std_logic;                             -- Start transmitter
72
        CLEAR       : in std_logic;                             -- Clear transmitter state
73
        WLS         : in std_logic_vector(1 downto 0);          -- Word length select
74
        STB         : in std_logic;                             -- Number of stop bits
75
        PEN         : in std_logic;                             -- Parity enable
76
        EPS         : in std_logic;                             -- Even parity select
77
        SP          : in std_logic;                             -- Stick parity
78
        BC          : in std_logic;                             -- Break control
79
        DIN         : in std_logic_vector(7 downto 0);          -- Input data
80
        TXFINISHED  : out std_logic;                            -- Transmitter operation finished
81
        SOUT        : out std_logic                             -- Transmitter output
82
    );
83
    end component;
84
    -- UART receiver
85
    component uart_receiver is
86
    port (
87
        CLK         : in std_logic;                             -- Clock
88
        RST         : in std_logic;                             -- Reset
89
        RXCLK       : in std_logic;                             -- Receiver clock (16x baudrate)
90
        RXCLEAR     : in std_logic;                             -- Reset receiver state
91
        WLS         : in std_logic_vector(1 downto 0);          -- Word length select
92
        STB         : in std_logic;                             -- Number of stop bits
93
        PEN         : in std_logic;                             -- Parity enable
94
        EPS         : in std_logic;                             -- Even parity select
95
        SP          : in std_logic;                             -- Stick parity
96
        SIN         : in std_logic;                             -- Receiver input
97
        PE          : out std_logic;                            -- Parity error
98
        FE          : out std_logic;                            -- Framing error
99
        BI          : out std_logic;                            -- Break interrupt
100
        DOUT        : out std_logic_vector(7 downto 0);         -- Output data
101
        RXFINISHED  : out std_logic                             -- Receiver operation finished
102
    );
103
    end component;
104
    -- UART interrupt control
105
    component uart_interrupt is
106
    port (
107
        CLK         : in std_logic;                             -- Clock
108
        RST         : in std_logic;                             -- Reset
109
        IER         : in std_logic_vector(3 downto 0);          -- IER 3:0
110
        LSR         : in std_logic_vector(4 downto 0);          -- LSR 4:0
111
        THI         : in std_logic;                             -- Transmitter holding register empty interrupt
112
        RDA         : in std_logic;                             -- Receiver data available
113
        CTI         : in std_logic;                             -- Character timeout indication
114 13 hasw
        AFE         : in std_logic;                             -- Automatic flow control enable
115 2 hasw
        MSR         : in std_logic_vector(3 downto 0);          -- MSR 3:0
116
        IIR         : out std_logic_vector(3 downto 0);         -- IIR 3:0
117
        INT         : out std_logic                             -- Interrupt
118
    );
119
    end component;
120
    -- UART baudrate generator
121
    component uart_baudgen is
122
    port (
123
        CLK         : in std_logic;                             -- Clock
124
        RST         : in std_logic;                             -- Reset
125
        CE          : in std_logic;                             -- Clock enable
126
        CLEAR       : in std_logic;                             -- Reset generator (synchronization)
127
        DIVIDER     : in std_logic_vector(15 downto 0);         -- Clock divider
128
        BAUDTICK    : out std_logic                             -- 16xBaudrate tick
129
    );
130
    end component;
131
    -- UART FIFO
132
    component slib_fifo is
133
    generic (
134
        WIDTH       : integer := 8;                             -- FIFO width
135
        SIZE_E      : integer := 6                              -- FIFO size (2^SIZE_E)
136
    );
137
    port (
138
        CLK         : in std_logic;                             -- Clock
139
        RST         : in std_logic;                             -- Reset
140
        CLEAR       : in std_logic;                             -- Clear FIFO
141
        WRITE       : in std_logic;                             -- Write to FIFO
142
        READ        : in std_logic;                             -- Read from FIFO
143
        D           : in std_logic_vector(WIDTH-1 downto 0);    -- FIFO input
144
        Q           : out std_logic_vector(WIDTH-1 downto 0);   -- FIFO output
145
        EMPTY       : out std_logic;                            -- FIFO is empty
146
        FULL        : out std_logic;                            -- FIFO is full
147
        USAGE       : out std_logic_vector(SIZE_E-1 downto 0)   -- FIFO usage
148
    );
149
    end component;
150
    -- Edge detect
151
    component slib_edge_detect is
152
    port (
153
        CLK         : in std_logic;                             -- Clock
154
        RST         : in std_logic;                             -- Reset
155
        D           : in std_logic;                             -- Signal input
156
        RE          : out std_logic;                            -- Rising edge detected
157
        FE          : out std_logic                             -- Falling edge detected
158
    );
159
    end component;
160
    -- Input synchronization
161
    component slib_input_sync is
162
    port (
163
        CLK         : in std_logic;                             -- Clock
164
        RST         : in std_logic;                             -- Reset
165
        D           : in std_logic;                             -- Signal input
166
        Q           : out std_logic                             -- Signal output
167
    );
168
    end component;
169
    -- Input filter
170
    component slib_input_filter is
171
    generic (
172
        SIZE        : natural := 4                              -- Filter width
173
    );
174
    port (
175
        CLK         : in std_logic;                             -- Clock
176
        RST         : in std_logic;                             -- Reset
177
        CE          : in std_logic;                             -- Clock enable
178
        D           : in std_logic;                             -- Signal input
179
        Q           : out std_logic                             -- Signal output
180
    );
181
    end component;
182
    -- Clock enable generation
183
    component slib_clock_div is
184
    generic (
185
        RATIO       : integer := 8                              -- Clock divider ratio
186
    );
187
    port (
188
        CLK         : in std_logic;                             -- Clock
189
        RST         : in std_logic;                             -- Reset
190
        CE          : in std_logic;                             -- Clock enable input
191
        Q           : out std_logic                             -- New clock enable output
192
    );
193
    end component;
194
 
195
    -- Global device signals
196
    signal iCSWR            : std_logic;                        -- Chipselect and write
197
    signal iCSRD            : std_logic;                        -- Chipselect and read
198
    signal iWriteFE         : std_logic;                        -- Write falling edge
199
    signal iReadFE          : std_logic;                        -- Read falling edge
200
    signal iWrite           : std_logic;                        -- Write to UART
201
    signal iRead            : std_logic;                        -- Read from UART
202
    signal iA               : std_logic_vector(2 downto 0);     -- UART register address
203
    signal iDIN             : std_logic_vector(7 downto 0);     -- UART data input
204
 
205
    -- UART registers read/write signals
206
    signal iRBRRead         : std_logic;                        -- Read from RBR
207
    signal iTHRWrite        : std_logic;                        -- Write to THR
208
    signal iDLLWrite        : std_logic;                        -- Write to DLL
209
    signal iDLMWrite        : std_logic;                        -- Write to DLM
210
    signal iIERWrite        : std_logic;                        -- Write to IER
211
    signal iIIRRead         : std_logic;                        -- Read from IIR
212
    signal iFCRWrite        : std_logic;                        -- Write to FCR
213
    signal iLCRWrite        : std_logic;                        -- Write to LCR
214
    signal iMCRWrite        : std_logic;                        -- Write to MCR
215
    signal iLSRRead         : std_logic;                        -- Read from LSR
216
    signal iMSRRead         : std_logic;                        -- Read from MSR
217
    signal iSCRWrite        : std_logic;                        -- Write to SCR
218
 
219
    -- UART registers
220
    signal iTSR             : std_logic_vector(7 downto 0);     -- Transmitter holding register
221
    signal iRBR             : std_logic_vector(7 downto 0);     -- Receiver buffer register
222
    signal iDLL             : std_logic_vector(7 downto 0);     -- Divisor latch LSB
223
    signal iDLM             : std_logic_vector(7 downto 0);     -- Divisor latch MSB
224
    signal iIER             : std_logic_vector(7 downto 0);     -- Interrupt enable register
225
    signal iIIR             : std_logic_vector(7 downto 0);     -- Interrupt identification register
226
    signal iFCR             : std_logic_vector(7 downto 0);     -- FIFO control register
227
    signal iLCR             : std_logic_vector(7 downto 0);     -- Line control register
228
    signal iMCR             : std_logic_vector(7 downto 0);     -- Modem control register
229
    signal iLSR             : std_logic_vector(7 downto 0);     -- Line status register
230
    signal iMSR             : std_logic_vector(7 downto 0);     -- Modem status register
231
    signal iSCR             : std_logic_vector(7 downto 0);     -- Scratch register
232
 
233
    -- IER register signals
234
    signal iIER_ERBI        : std_logic;                        -- IER: Enable received data available interrupt
235
    signal iIER_ETBEI       : std_logic;                        -- IER: Enable transmitter holding register empty interrupt
236
    signal iIER_ELSI        : std_logic;                        -- IER: Enable receiver line status interrupt
237
    signal iIER_EDSSI       : std_logic;                        -- IER: Enable modem status interrupt
238
 
239
    -- IIR register signals
240
    signal iIIR_PI          : std_logic;                        -- IIR: Pending interrupt
241
    signal iIIR_ID0         : std_logic;                        -- IIR: Interrupt ID0
242
    signal iIIR_ID1         : std_logic;                        -- IIR: Interrupt ID1
243
    signal iIIR_ID2         : std_logic;                        -- IIR: Interrupt ID2
244
    signal iIIR_FIFO64      : std_logic;                        -- IIR: 64 byte FIFO enabled
245
 
246
    -- FCR register signals
247
    signal iFCR_FIFOEnable  : std_logic;                        -- FCR: FIFO enable
248
    signal iFCR_RXFIFOReset : std_logic;                        -- FCR: Receiver FIFO reset
249
    signal iFCR_TXFIFOReset : std_logic;                        -- FCR: Transmitter FIFO reset
250
    signal iFCR_DMAMode     : std_logic;                        -- FCR: DMA mode select
251
    signal iFCR_FIFO64E     : std_logic;                        -- FCR: 64 byte FIFO enable
252
    signal iFCR_RXTrigger   : std_logic_vector(1 downto 0);     -- FCR: Receiver trigger
253
 
254
    -- LCR register signals
255
    signal iLCR_WLS         : std_logic_vector(1 downto 0);     -- LCR: Word length select
256
    signal iLCR_STB         : std_logic;                        -- LCR: Number of stop bits
257
    signal iLCR_PEN         : std_logic;                        -- LCR: Parity enable
258
    signal iLCR_EPS         : std_logic;                        -- LCR: Even parity select
259
    signal iLCR_SP          : std_logic;                        -- LCR: Sticky parity
260
    signal iLCR_BC          : std_logic;                        -- LCR: Break control
261
    signal iLCR_DLAB        : std_logic;                        -- LCR: Divisor latch access bit
262
 
263
    -- MCR register signals
264
    signal iMCR_DTR         : std_logic;                        -- MCR: Data terminal ready
265
    signal iMCR_RTS         : std_logic;                        -- MCR: Request to send
266
    signal iMCR_OUT1        : std_logic;                        -- MCR: OUT1
267
    signal iMCR_OUT2        : std_logic;                        -- MCR: OUT2
268
    signal iMCR_LOOP        : std_logic;                        -- MCR: Loop
269
    signal iMCR_AFE         : std_logic;                        -- MCR: Auto flow control enable
270
 
271
    -- LSR register signals
272
    signal iLSR_DR          : std_logic;                        -- LSR: Data ready
273
    signal iLSR_OE          : std_logic;                        -- LSR: Overrun error
274
    signal iLSR_PE          : std_logic;                        -- LSR: Parity error
275
    signal iLSR_FE          : std_logic;                        -- LSR: Framing error
276
    signal iLSR_BI          : std_logic;                        -- LSR: Break Interrupt
277
    signal iLSR_THRE        : std_logic;                        -- LSR: Transmitter holding register empty
278
    signal iLSR_TEMT        : std_logic;                        -- LSR: Transmitter empty
279
    signal iLSR_FIFOERR     : std_logic;                        -- LSR: Error in receiver FIFO
280
 
281
    -- MSR register signals
282
    signal iMSR_dCTS        : std_logic;                        -- MSR: Delta CTS
283
    signal iMSR_dDSR        : std_logic;                        -- MSR: Delta DSR
284
    signal iMSR_TERI        : std_logic;                        -- MSR: Trailing edge ring indicator
285
    signal iMSR_dDCD        : std_logic;                        -- MSR: Delta DCD
286
    signal iMSR_CTS         : std_logic;                        -- MSR: CTS
287
    signal iMSR_DSR         : std_logic;                        -- MSR: DSR
288
    signal iMSR_RI          : std_logic;                        -- MSR: RI
289
    signal iMSR_DCD         : std_logic;                        -- MSR: DCD
290
 
291
    -- UART MSR signals
292
    signal iCTSNs           : std_logic;                        -- Synchronized CTSN input
293
    signal iDSRNs           : std_logic;                        -- Synchronized DSRN input
294
    signal iDCDNs           : std_logic;                        -- Synchronized DCDN input
295
    signal iRINs            : std_logic;                        -- Synchronized RIN input
296
    signal iCTSn            : std_logic;                        -- Filtered CTSN input
297
    signal iDSRn            : std_logic;                        -- Filtered DSRN input
298
    signal iDCDn            : std_logic;                        -- Filtered DCDN input
299
    signal iRIn             : std_logic;                        -- Filtered RIN input
300
    signal iCTSnRE          : std_logic;                        -- CTSn rising edge
301
    signal iCTSnFE          : std_logic;                        -- CTSn falling edge
302
    signal iDSRnRE          : std_logic;                        -- DSRn rising edge
303
    signal iDSRnFE          : std_logic;                        -- DSRn falling edge
304
    signal iDCDnRE          : std_logic;                        -- DCDn rising edge
305
    signal iDCDnFE          : std_logic;                        -- DCDn falling edge
306
    signal iRInRE           : std_logic;                        -- RIn rising edge
307
    signal iRInFE           : std_logic;                        -- RIn falling edge
308
 
309
    -- UART baudrate generation signals
310
    signal iBaudgenDiv      : std_logic_vector(15 downto 0);    -- Baudrate divider
311
    signal iBaudtick16x     : std_logic;                        -- 16x Baudrate output from baudrate generator
312
    signal iBaudtick2x      : std_logic;                        -- 2x Baudrate for transmitter
313
    signal iRCLK            : std_logic;                        -- 16x Baudrate for receiver
314
 
315
    -- UART FIFO signals
316
    signal iTXFIFOClear     : std_logic;                        -- Clear TX FIFO
317
    signal iTXFIFOWrite     : std_logic;                        -- Write to TX FIFO
318
    signal iTXFIFORead      : std_logic;                        -- Read from TX FIFO
319
    signal iTXFIFOEmpty     : std_logic;                        -- TX FIFO is empty
320
    signal iTXFIFOFull      : std_logic;                        -- TX FIFO is full
321
    signal iTXFIFO16Full    : std_logic;                        -- TX FIFO 16 byte mode is full
322
    signal iTXFIFO64Full    : std_logic;                        -- TX FIFO 64 byte mode is full
323
    signal iTXFIFOUsage     : std_logic_vector(5 downto 0);     -- RX FIFO usage
324
    signal iTXFIFOQ         : std_logic_vector(7 downto 0);     -- TX FIFO output
325
    signal iRXFIFOClear     : std_logic;                        -- Clear RX FIFO
326
    signal iRXFIFOWrite     : std_logic;                        -- Write to RX FIFO
327
    signal iRXFIFORead      : std_logic;                        -- Read from RX FIFO
328
    signal iRXFIFOEmpty     : std_logic;                        -- RX FIFO is empty
329
    signal iRXFIFOFull      : std_logic;                        -- RX FIFO is full
330
    signal iRXFIFO16Full    : std_logic;                        -- RX FIFO 16 byte mode is full
331
    signal iRXFIFO64Full    : std_logic;                        -- RX FIFO 64 byte mode is full
332
    signal iRXFIFOD         : std_logic_vector(10 downto 0);    -- RX FIFO input
333
    signal iRXFIFOQ         : std_logic_vector(10 downto 0);    -- RX FIFO output
334
    signal iRXFIFOUsage     : std_logic_vector(5 downto 0);     -- RX FIFO usage
335
    signal iRXFIFOTrigger   : std_logic;                        -- FIFO trigger level reached
336
    signal iRXFIFO16Trigger : std_logic;                        -- FIFO 16 byte mode trigger level reached
337
    signal iRXFIFO64Trigger : std_logic;                        -- FIFO 64 byte mode trigger level reached
338
    signal iRXFIFOPE        : std_logic;                        -- Parity error from FIFO
339
    signal iRXFIFOFE        : std_logic;                        -- Frame error from FIFO
340
    signal iRXFIFOBI        : std_logic;                        -- Break interrupt from FIFO
341
 
342
    -- UART transmitter signals
343
    signal iSOUT            : std_logic;                        -- Transmitter output
344
    signal iTXStart         : std_logic;                        -- Start transmitter
345
    signal iTXClear         : std_logic;                        -- Clear transmitter status
346
    signal iTXFinished      : std_logic;                        -- TX finished, character transmitted
347
    signal iTXRunning       : std_logic;                        -- TX in progress
348
 
349
    -- UART receiver signals
350
    signal iSINr            : std_logic;                        -- Synchronized SIN input
351
    signal iSIN             : std_logic;                        -- Receiver input
352
    signal iRXFinished      : std_logic;                        -- RX finished, character received
353
    signal iRXClear         : std_logic;                        -- Clear receiver status
354
    signal iRXData          : std_logic_vector(7 downto 0);     -- RX data
355
    signal iRXPE            : std_logic;                        -- RX parity error
356
    signal iRXFE            : std_logic;                        -- RX frame error
357
    signal iRXBI            : std_logic;                        -- RX break interrupt
358
 
359
    -- UART control signals
360
    signal iFERE            : std_logic;                        -- Frame error detected
361
    signal iPERE            : std_logic;                        -- Parity error detected
362
    signal iBIRE            : std_logic;                        -- Break interrupt detected
363
    signal iFECounter       : integer range 0 to 64;            -- FIFO error counter
364
    signal iFEIncrement     : std_logic;                        -- FIFO error counter increment
365
    signal iFEDecrement     : std_logic;                        -- FIFO error counter decrement
366
    signal iRDAInterrupt    : std_logic;                        -- Receiver data available interrupt (DA or FIFO trigger level)
367 13 hasw
    signal iTimeoutCount    : unsigned(5 downto 0);             -- Character timeout counter (FIFO mode)
368 2 hasw
    signal iCharTimeout     : std_logic;                        -- Character timeout indication (FIFO mode)
369
    signal iLSR_THRERE      : std_logic;                        -- LSR THRE rising edge for interrupt generation
370
    signal iTHRInterrupt    : std_logic;                        -- Transmitter holding register empty interrupt
371 13 hasw
    signal iTXEnable        : std_logic;                        -- Transmitter enable signal
372
    signal iRTS             : std_logic;                        -- Internal RTS signal with/without automatic flow control
373 2 hasw
 
374
 
375
begin
376
 
377
    -- Global device signals
378
    iCSWR  <= '1' when CS = '1' and WR = '1' else '0';
379
    iCSRD  <= '1' when CS = '1' and RD = '1' else '0';
380
    UART_ED_WRITE: slib_edge_detect port map (CLK => CLK, RST => RST, D => iCSWR, FE => iWriteFE);
381
    UART_ED_READ:  slib_edge_detect port map (CLK => CLK, RST => RST, D => iCSRD, FE => iReadFE);
382
    iWrite <= '1' when iWriteFE = '1' else '0';
383
    iRead  <= '1' when iReadFE  = '1' else '0';
384
 
385
    -- UART registers read/write signals
386
    iRBRRead  <= '1' when iRead  = '1' and iA = "000" and iLCR_DLAB = '0' else '0';
387
    iTHRWrite <= '1' when iWrite = '1' and iA = "000" and iLCR_DLAB = '0' else '0';
388
    iDLLWrite <= '1' when iWrite = '1' and iA = "000" and iLCR_DLAB = '1' else '0';
389
    iDLMWrite <= '1' when iWrite = '1' and iA = "001" and iLCR_DLAB = '1' else '0';
390
    iIERWrite <= '1' when iWrite = '1' and iA = "001" and iLCR_DLAB = '0' else '0';
391
    iIIRRead  <= '1' when iRead  = '1' and iA = "010" else '0';
392
    iFCRWrite <= '1' when iWrite = '1' and iA = "010" else '0';
393
    iLCRWrite <= '1' when iWrite = '1' and iA = "011" else '0';
394
    iMCRWrite <= '1' when iWrite = '1' and iA = "100" else '0';
395
    iLSRRead  <= '1' when iRead  = '1' and iA = "101" else '0';
396
    iMSRRead  <= '1' when iRead  = '1' and iA = "110" else '0';
397
    iSCRWrite <= '1' when iWrite = '1' and iA = "111" else '0';
398
 
399
    -- Async. input synchronization
400
    UART_IS_SIN: slib_input_sync port map (CLK, RST, SIN,  iSINr);
401
    UART_IS_CTS: slib_input_sync port map (CLK, RST, CTSN, iCTSNs);
402
    UART_IS_DSR: slib_input_sync port map (CLK, RST, DSRN, iDSRNs);
403
    UART_IS_DCD: slib_input_sync port map (CLK, RST, DCDN, iDCDNs);
404
    UART_IS_RI:  slib_input_sync port map (CLK, RST, RIN,  iRINs);
405
 
406
    -- Input filter for UART control signals
407 15 hasw
    UART_IF_CTS: slib_input_filter generic map (SIZE => 2) port map (CLK, RST, iBaudtick2x, iCTSNs, iCTSn);
408
    UART_IF_DSR: slib_input_filter generic map (SIZE => 2) port map (CLK, RST, iBaudtick2x, iDSRNs, iDSRn);
409
    UART_IF_DCD: slib_input_filter generic map (SIZE => 2) port map (CLK, RST, iBaudtick2x, iDCDNs, iDCDn);
410
    UART_IF_RI:  slib_input_filter generic map (SIZE => 2) port map (CLK, RST, iBaudtick2x, iRINs, iRIn);
411 2 hasw
 
412
    -- Sync. input synchronization
413
    UART_SIS: process (CLK, RST)
414
    begin
415
        if (RST = '1') then
416
            iA   <= (others => '0');
417
            iDIN <= (others => '0');
418
        elsif (CLK'event and CLK = '1') then
419
            iA   <= A;
420
            iDIN <= DIN;
421
        end if;
422
    end process;
423
 
424
 
425
    -- Divisor latch register
426
    UART_DLR: process (CLK, RST)
427
    begin
428
        if (RST = '1') then
429
            iDLL <= (others => '0');
430
            iDLM <= (others => '0');
431
        elsif (CLK'event and CLK = '1') then
432
            if (iDLLWrite = '1') then
433
                iDLL <= iDIN;
434
            end if;
435
            if (iDLMWrite = '1') then
436
                iDLM <= iDIN;
437
            end if;
438
        end if;
439
    end process;
440
 
441
    -- Interrupt enable register
442
    UART_IER: process (CLK, RST)
443
    begin
444
        if (RST = '1') then
445
            iIER(3 downto 0) <= (others => '0');
446
        elsif (CLK'event and CLK = '1') then
447
            if (iIERWrite = '1') then
448
                iIER(3 downto 0) <= iDIN(3 downto 0);
449
            end if;
450
        end if;
451
    end process;
452
 
453
    iIER_ERBI   <= iIER(0);
454
    iIER_ETBEI  <= iIER(1);
455
    iIER_ELSI   <= iIER(2);
456
    iIER_EDSSI  <= iIER(3);
457
    iIER(7 downto 4) <= (others => '0');
458
 
459
    -- Interrupt control and IIR
460
    UART_IIC: uart_interrupt port map (CLK => CLK,
461
                                       RST => RST,
462
                                       IER => iIER(3 downto 0),
463
                                       LSR => iLSR(4 downto 0),
464
                                       THI => iTHRInterrupt,
465
                                       RDA => iRDAInterrupt,
466
                                       CTI => iCharTimeout,
467 13 hasw
                                       AFE => iMCR_AFE,
468 2 hasw
                                       MSR => iMSR(3 downto 0),
469
                                       IIR => iIIR(3 downto 0),
470
                                       INT => INT
471
                                      );
472
    -- THR empty interrupt
473
    UART_IIC_THRE_ED: slib_edge_detect port map (CLK => CLK, RST => RST, D => iLSR_THRE, RE => iLSR_THRERE);
474
    UART_IIC_THREI: process (CLK, RST)
475
    begin
476
        if (RST = '1') then
477 6 hasw
            iTHRInterrupt <= '0';
478 2 hasw
        elsif (CLK'event and CLK = '1') then
479
            if (iLSR_THRERE = '1' or iFCR_TXFIFOReset = '1' or (iIERWrite = '1' and iDIN(1) = '1' and iLSR_THRE = '1')) then
480
                iTHRInterrupt <= '1';           -- Set on THRE, TX FIFO reset (FIFO enable) or ETBEI enable
481
            elsif ((iIIRRead = '1' and iIIR(3 downto 1) = "001") or iTHRWrite = '1') then
482
                iTHRInterrupt <= '0';           -- Clear on IIR read (if source of interrupt) or THR write
483
            end if;
484
        end if;
485
    end process;
486
 
487
    iRDAInterrupt <= '1' when (iFCR_FIFOEnable = '0' and iLSR_DR = '1') or
488
                              (iFCR_FIFOEnable = '1' and iRXFIFOTrigger = '1') else '0';
489
    iIIR_PI     <= iIIR(0);
490
    iIIR_ID0    <= iIIR(1);
491
    iIIR_ID1    <= iIIR(2);
492
    iIIR_ID2    <= iIIR(3);
493
    iIIR_FIFO64 <= iIIR(5);
494
    iIIR(4)  <= '0';
495 15 hasw
    iIIR(5)  <= iFCR_FIFO64E when iFCR_FIFOEnable = '1' else '0';
496 2 hasw
    iIIR(6)  <= iFCR_FIFOEnable;
497
    iIIR(7)  <= iFCR_FIFOEnable;
498
 
499
    -- Character timeout indication
500
    UART_CTI: process (CLK, RST)
501
    begin
502
        if (RST = '1') then
503
            iTimeoutCount <= (others => '0');
504
            iCharTimeout  <= '0';
505
        elsif (CLK'event and CLK = '1') then
506
            if (iRXFIFOEmpty = '1' or iRBRRead = '1' or iRXFIFOWrite = '1') then
507
                iTimeoutCount <= (others => '0');
508
            elsif (iRXFIFOEmpty = '0' and iBaudtick2x = '1' and iTimeoutCount(5) = '0') then
509 13 hasw
                iTimeoutCount <= iTimeoutCount + 1;
510 2 hasw
            end if;
511
 
512
            -- Timeout indication
513
            if (iFCR_FIFOEnable = '1') then
514
                if (iRBRRead = '1') then
515
                    iCharTimeout <= '0';
516
                elsif (iTimeoutCount(5) = '1') then
517
                    iCharTimeout <= '1';
518
                end if;
519
            else
520
                iCharTimeout <= '0';
521
            end if;
522
        end if;
523
    end process;
524
 
525
    -- FIFO control register
526
    UART_FCR: process (CLK, RST)
527
    begin
528
        if (RST = '1') then
529
            iFCR_FIFOEnable     <= '0';
530
            iFCR_RXFIFOReset    <= '0';
531
            iFCR_TXFIFOReset    <= '0';
532
            iFCR_DMAMode        <= '0';
533
            iFCR_FIFO64E        <= '0';
534
            iFCR_RXTrigger      <= (others => '0');
535
        elsif (CLK'event and CLK = '1') then
536
            -- FIFO reset pulse only
537
            iFCR_RXFIFOReset <= '0';
538
            iFCR_TXFIFOReset <= '0';
539
 
540
            if (iFCRWrite = '1') then
541
                iFCR_FIFOEnable <= iDIN(0);
542
                iFCR_DMAMode    <= iDIN(3);
543
                iFCR_RXTrigger  <= iDIN(7 downto 6);
544
 
545
                if (iLCR_DLAB = '1') then
546
                    iFCR_FIFO64E    <= iDIN(5);
547
                end if;
548
 
549
                -- RX FIFO reset control, reset on FIFO enable/disable
550
                if (iDIN(1) = '1' or (iFCR_FIFOEnable = '0' and iDIN(0) = '1') or (iFCR_FIFOEnable = '1' and iDIN(0) = '0')) then
551
                    iFCR_RXFIFOReset <= '1';
552
                end if;
553
                -- TX FIFO reset control, reset on FIFO enable/disable
554
                if (iDIN(2) = '1' or (iFCR_FIFOEnable = '0' and iDIN(0) = '1') or (iFCR_FIFOEnable = '1' and iDIN(0) = '0')) then
555
                    iFCR_TXFIFOReset <= '1';
556
                end if;
557
            end if;
558
        end if;
559
    end process;
560
 
561
    iFCR(0) <= iFCR_FIFOEnable;
562
    iFCR(1) <= iFCR_RXFIFOReset;
563
    iFCR(2) <= iFCR_TXFIFOReset;
564
    iFCR(3) <= iFCR_DMAMode;
565
    iFCR(4) <= '0';
566
    iFCR(5) <= iFCR_FIFO64E;
567
    iFCR(7 downto 6) <= iFCR_RXTrigger;
568
 
569
    -- Line control register
570
    UART_LCR: process (CLK, RST)
571
    begin
572
        if (RST = '1') then
573
            iLCR <= (others => '0');
574
        elsif (CLK'event and CLK = '1') then
575
            if (iLCRWrite = '1') then
576
                iLCR <= iDIN;
577
            end if;
578
        end if;
579
    end process;
580
 
581
    iLCR_WLS    <= iLCR(1 downto 0);
582
    iLCR_STB    <= iLCR(2);
583
    iLCR_PEN    <= iLCR(3);
584
    iLCR_EPS    <= iLCR(4);
585
    iLCR_SP     <= iLCR(5);
586
    iLCR_BC     <= iLCR(6);
587
    iLCR_DLAB   <= iLCR(7);
588
 
589
    -- Modem control register
590
    UART_MCR: process (CLK, RST)
591
    begin
592
        if (RST = '1') then
593
            iMCR(5 downto 0) <= (others => '0');
594
        elsif (CLK'event and CLK = '1') then
595
            if (iMCRWrite = '1') then
596
                iMCR(5 downto 0) <= iDIN(5 downto 0);
597
            end if;
598
        end if;
599
    end process;
600
 
601
    iMCR_DTR    <= iMCR(0);
602
    iMCR_RTS    <= iMCR(1);
603
    iMCR_OUT1   <= iMCR(2);
604
    iMCR_OUT2   <= iMCR(3);
605
    iMCR_LOOP   <= iMCR(4);
606
    iMCR_AFE    <= iMCR(5);
607
    iMCR(6)     <= '0';
608
    iMCR(7)     <= '0';
609
 
610
    -- Line status register
611
    UART_LSR: process (CLK, RST)
612
    begin
613
        if (RST = '1') then
614
            iLSR_OE     <= '0';
615
            iLSR_PE     <= '0';
616
            iLSR_FE     <= '0';
617
            iLSR_BI     <= '0';
618
            iFECounter  <= 0;
619
        elsif (CLK'event and CLK = '1') then
620
            -- Overrun error
621
            if ((iFCR_FIFOEnable = '0' and iLSR_DR = '1' and iRXFinished = '1') or
622
                (iFCR_FIFOEnable = '1' and iRXFIFOFull  = '1' and iRXFinished = '1')) then
623
                iLSR_OE <= '1';
624
            elsif (iLSRRead = '1') then
625
                iLSR_OE <= '0';
626
            end if;
627
            -- Parity error
628
            if (iPERE = '1') then
629
                iLSR_PE <= '1';
630
            elsif (iLSRRead = '1') then
631
                iLSR_PE <= '0';
632
            end if;
633
            -- Frame error
634
            if (iFERE = '1') then
635
                iLSR_FE <= '1';
636
            elsif (iLSRRead = '1') then
637
                iLSR_FE <= '0';
638
            end if;
639
            -- Break interrupt
640
            if (iBIRE = '1') then
641
                iLSR_BI <= '1';
642
            elsif (iLSRRead = '1') then
643
                iLSR_BI <= '0';
644
            end if;
645
 
646
            -- FIFO error
647
            -- Datasheet: Cleared by LSR read when no subsequent errors in FIFO
648
            -- Observed:  Cleared when no subsequent errors in FIFO
649
            if (iFECounter /= 0) then
650
                iLSR_FIFOERR <= '1';
651
            --elsif (iLSRRead = '1' and iFECounter = 0 and not (iRXFIFOEmpty = '0' and iRXFIFOQ(10 downto 8) /= "000")) then
652
            elsif (iRXFIFOEmpty = '1' or iRXFIFOQ(10 downto 8) = "000") then
653
                iLSR_FIFOERR <= '0';
654
            end if;
655
 
656
            -- FIFO error counter
657
            if (iRXFIFOClear = '1') then
658
                iFECounter <= 0;
659
            else
660
                if (iFEIncrement = '1' and iFEDecrement = '0') then
661
                    iFECounter <= iFECounter + 1;
662
                elsif (iFEIncrement = '0' and iFEDecrement = '1') then
663
                    iFECounter <= iFECounter - 1;
664
                end if;
665
            end if;
666
        end if;
667
    end process;
668
 
669
    iRXFIFOPE <= '1' when iRXFIFOEmpty = '0' and iRXFIFOQ(8)  = '1' else '0';
670
    iRXFIFOFE <= '1' when iRXFIFOEmpty = '0' and iRXFIFOQ(9)  = '1' else '0';
671
    iRXFIFOBI <= '1' when iRXFIFOEmpty = '0' and iRXFIFOQ(10) = '1' else '0';
672
    UART_PEDET: slib_edge_detect port map (CLK, RST, iRXFIFOPE, iPERE);
673
    UART_FEDET: slib_edge_detect port map (CLK, RST, iRXFIFOFE, iFERE);
674
    UART_BIDET: slib_edge_detect port map (CLK, RST, iRXFIFOBI, iBIRE);
675
    iFEIncrement    <= '1' when iRXFIFOWrite = '1' and iRXFIFOD(10 downto 8) /= "000" else '0';
676
    iFEDecrement    <= '1' when iFECounter /= 0 and iRXFIFOEmpty = '0' and (iPERE = '1' or iFERE = '1' or iBIRE = '1') else '0';
677
 
678
    iLSR(0)         <= iLSR_DR;
679
    iLSR(1)         <= iLSR_OE;
680
    iLSR(2)         <= iLSR_PE;
681
    iLSR(3)         <= iLSR_FE;
682
    iLSR(4)         <= iLSR_BI;
683
    iLSR(5)         <= iLSR_THRE;
684
    iLSR(6)         <= iLSR_TEMT;
685
    iLSR(7)         <= '1' when iFCR_FIFOEnable = '1' and iLSR_FIFOERR = '1' else '0';
686
    iLSR_DR         <= '1' when iRXFIFOEmpty = '0' or iRXFIFOWrite = '1' else '0';
687
    iLSR_THRE       <= '1' when iTXFIFOEmpty = '1' else '0';
688
    iLSR_TEMT       <= '1' when iTXRunning = '0' and iLSR_THRE = '1' else '0';
689
 
690
    -- Modem status register
691 13 hasw
    iMSR_CTS <= '1' when (iMCR_LOOP = '1' and iRTS = '1')      or (iMCR_LOOP = '0' and iCTSn = '0') else '0';
692 2 hasw
    iMSR_DSR <= '1' when (iMCR_LOOP = '1' and iMCR_DTR = '1')  or (iMCR_LOOP = '0' and iDSRn = '0') else '0';
693
    iMSR_RI  <= '1' when (iMCR_LOOP = '1' and iMCR_OUT1 = '1') or (iMCR_LOOP = '0' and iRIn  = '0') else '0';
694
    iMSR_DCD <= '1' when (iMCR_LOOP = '1' and iMCR_OUT2 = '1') or (iMCR_LOOP = '0' and iDCDn = '0') else '0';
695
 
696
    -- Edge detection for CTS, DSR, DCD and RI
697
    UART_ED_CTS: slib_edge_detect port map (CLK => CLK, RST => RST, D => iMSR_CTS, RE => iCTSnRE, FE => iCTSnFE);
698
    UART_ED_DSR: slib_edge_detect port map (CLK => CLK, RST => RST, D => iMSR_DSR, RE => iDSRnRE, FE => iDSRnFE);
699
    UART_ED_RI:  slib_edge_detect port map (CLK => CLK, RST => RST, D => iMSR_RI,  RE => iRInRE,  FE => iRInFE);
700
    UART_ED_DCD: slib_edge_detect port map (CLK => CLK, RST => RST, D => iMSR_DCD, RE => iDCDnRE, FE => iDCDnFE);
701
 
702
    UART_MSR: process (CLK, RST)
703
    begin
704
        if (RST = '1') then
705
            iMSR_dCTS <= '0';
706
            iMSR_dDSR <= '0';
707
            iMSR_TERI <= '0';
708
            iMSR_dDCD <= '0';
709
        elsif (CLK'event and CLK = '1') then
710
            -- Delta CTS
711
            if (iCTSnRE = '1' or iCTSnFE = '1') then
712
                iMSR_dCTS <= '1';
713
            elsif (iMSRRead = '1') then
714
                iMSR_dCTS <= '0';
715
            end if;
716
            -- Delta DSR
717
            if (iDSRnRE = '1' or iDSRnFE = '1') then
718
                iMSR_dDSR <= '1';
719
            elsif (iMSRRead = '1') then
720
                iMSR_dDSR <= '0';
721
            end if;
722
            -- Trailing edge RI
723 15 hasw
            if (iRInFE = '1') then
724 2 hasw
                iMSR_TERI <= '1';
725
            elsif (iMSRRead = '1') then
726
                iMSR_TERI <= '0';
727
            end if;
728
            -- Delta DCD
729
            if (iDCDnRE = '1' or iDCDnFE = '1') then
730
                iMSR_dDCD <= '1';
731
            elsif (iMSRRead = '1') then
732
                iMSR_dDCD <= '0';
733
            end if;
734
        end if;
735
    end process;
736
 
737
    iMSR(0)     <= iMSR_dCTS;
738
    iMSR(1)     <= iMSR_dDSR;
739
    iMSR(2)     <= iMSR_TERI;
740
    iMSR(3)     <= iMSR_dDCD;
741
    iMSR(4)     <= iMSR_CTS;
742
    iMSR(5)     <= iMSR_DSR;
743
    iMSR(6)     <= iMSR_RI;
744
    iMSR(7)     <= iMSR_DCD;
745
 
746
    -- Scratch register
747
    UART_SCR: process (CLK, RST)
748
    begin
749
        if (RST = '1') then
750
            iSCR <= (others => '0');
751
        elsif (CLK'event and CLK = '1') then
752
            if (iSCRWrite = '1') then
753
                iSCR <= iDIN;
754
            end if;
755
        end if;
756
    end process;
757
 
758
 
759
    -- Baudrate generator
760
    iBaudgenDiv <= iDLM & iDLL;
761
    UART_BG16: uart_baudgen port map (CLK         => CLK,
762
                                      RST         => RST,
763
                                      CE          => BAUDCE,
764
                                      CLEAR       => '0',
765
                                      DIVIDER     => iBaudgenDiv,
766
                                      BAUDTICK    => iBaudtick16x
767
                                     );
768
    UART_BG2: slib_clock_div generic map (RATIO => 8)
769
                             port map    (CLK   => CLK,
770
                                          RST   => RST,
771
                                          CE    => iBaudtick16x,
772
                                          Q     => iBaudtick2x
773
                                         );
774
    UART_RCLK: slib_edge_detect port map (CLK => CLK,
775
                                          RST => RST,
776
                                          D   => RCLK,
777
                                          RE  => iRCLK
778
                                         );
779
 
780
    -- Transmitter FIFO
781
    UART_TXFF: slib_fifo generic map (WIDTH => 8, SIZE_E => 6)
782
                         port map (CLK      => CLK,
783
                                   RST      => RST,
784
                                   CLEAR    => iTXFIFOClear,
785
                                   WRITE    => iTXFIFOWrite,
786
                                   READ     => iTXFIFORead,
787
                                   D        => iDIN,
788
                                   Q        => iTXFIFOQ,
789
                                   EMPTY    => iTXFIFOEmpty,
790
                                   FULL     => iTXFIFO64Full,
791
                                   USAGE    => iTXFIFOUsage
792
                                  );
793
    -- Transmitter FIFO inputs
794
    iTXFIFO16Full <= iTXFIFOUsage(4);
795
    iTXFIFOFull   <= iTXFIFO16Full when iFCR_FIFO64E = '0' else iTXFIFO64Full;
796
    iTXFIFOWrite  <= '1' when ((iFCR_FIFOEnable = '0' and iTXFIFOEmpty = '1') or (iFCR_FIFOEnable = '1' and iTXFIFOFull = '0')) and iTHRWrite = '1' else '0';
797
    iTXFIFOClear  <= '1' when iFCR_TXFIFOReset = '1' else '0';
798
 
799
    -- Receiver FIFO
800
    UART_RXFF: slib_fifo generic map (WIDTH => 11, SIZE_E => 6)
801
                         port map (CLK      => CLK,
802
                                   RST      => RST,
803
                                   CLEAR    => iRXFIFOClear,
804
                                   WRITE    => iRXFIFOWrite,
805
                                   READ     => iRXFIFORead,
806
                                   D        => iRXFIFOD,
807
                                   Q        => iRXFIFOQ,
808
                                   EMPTY    => iRXFIFOEmpty,
809
                                   FULL     => iRXFIFO64Full,
810
                                   USAGE    => iRXFIFOUsage
811
                                  );
812
    -- Receiver FIFO inputs
813
    iRXFIFORead          <= '1' when iRBRRead = '1' else '0';
814
    iRXFIFO16Full        <= iRXFIFOUsage(4);
815
    iRXFIFOFull          <= iRXFIFO16Full when iFCR_FIFO64E = '0' else iRXFIFO64Full;
816
 
817
 
818
    -- Receiver FIFO outputs
819
    iRBR                 <= iRXFIFOQ(7 downto 0);
820
 
821
    -- FIFO trigger level: 1, 4, 8, 14
822
    iRXFIFO16Trigger     <= '1' when (iFCR_RXTrigger = "00" and iRXFIFOEmpty = '0') or
823
                                     (iFCR_RXTrigger = "01" and (iRXFIFOUsage(2) = '1' or iRXFIFOUsage(3) = '1')) or
824
                                     (iFCR_RXTrigger = "10" and iRXFIFOUsage(3) = '1') or
825
                                     (iFCR_RXTrigger = "11" and iRXFIFOUsage(3) = '1' and iRXFIFOUsage(2) = '1' and iRXFIFOUsage(1) = '1') or
826
                                     iRXFIFO16Full = '1' else '0';
827
    -- FIFO 64 trigger level: 1, 16, 32, 56
828
    iRXFIFO64Trigger     <= '1' when (iFCR_RXTrigger = "00" and iRXFIFOEmpty = '0') or
829
                                     (iFCR_RXTrigger = "01" and (iRXFIFOUsage(4) = '1' or iRXFIFOUsage(5) = '1')) or
830
                                     (iFCR_RXTrigger = "10" and iRXFIFOUsage(5) = '1') or
831
                                     (iFCR_RXTrigger = "11" and iRXFIFOUsage(5) = '1' and iRXFIFOUsage(4) = '1' and iRXFIFOUsage(3) = '1') or
832
                                     iRXFIFO64Full = '1' else '0';
833
    iRXFIFOTrigger       <= iRXFIFO16Trigger when iFCR_FIFO64E = '0' else iRXFIFO64Trigger;
834
 
835
    -- Transmitter
836
    UART_TX: uart_transmitter port map (CLK         => CLK,
837
                                        RST         => RST,
838
                                        TXCLK       => iBaudtick2x,
839
                                        TXSTART     => iTXStart,
840
                                        CLEAR       => iTXClear,
841
                                        WLS         => iLCR_WLS,
842
                                        STB         => iLCR_STB,
843
                                        PEN         => iLCR_PEN,
844
                                        EPS         => iLCR_EPS,
845
                                        SP          => iLCR_SP,
846
                                        BC          => iLCR_BC,
847
                                        DIN         => iTSR,
848
                                        TXFINISHED  => iTXFinished,
849
                                        SOUT        => iSOUT
850
                                       );
851
    iTXClear <= '0';
852
 
853
    -- Receiver
854
    UART_RX: uart_receiver    port map (CLK         => CLK,
855
                                        RST         => RST,
856
                                        RXCLK       => iRCLK,
857
                                        RXCLEAR     => iRXClear,
858
                                        WLS         => iLCR_WLS,
859
                                        STB         => iLCR_STB,
860
                                        PEN         => iLCR_PEN,
861
                                        EPS         => iLCR_EPS,
862
                                        SP          => iLCR_SP,
863
                                        SIN         => iSIN,
864
                                        PE          => iRXPE,
865
                                        FE          => iRXFE,
866
                                        BI          => iRXBI,
867
                                        DOUT        => iRXData,
868
                                        RXFINISHED  => iRXFinished
869
                                       );
870
    iRXClear <= '0';
871
    iSIN <= iSINr when iMCR_LOOP = '0' else iSOUT;
872
 
873 13 hasw
    -- Transmitter enable signal
874
    -- TODO: Use iCTSNs instead of iMSR_CTS? Input filter increases delay for Auto-CTS recognition.
875
    iTXEnable <= '1' when iTXFIFOEmpty = '0' and (iMCR_AFE = '0' or (iMCR_AFE = '1' and iMSR_CTS = '1')) else '0';
876 2 hasw
 
877
    -- Transmitter process
878
    UART_TXPROC: process (CLK, RST)
879
        type state_type is (IDLE, TXSTART, TXRUN, TXEND);
880
        variable State : state_type;
881
    begin
882
        if (RST = '1') then
883
            State       := IDLE;
884
            iTSR        <= (others => '0');
885
            iTXStart    <= '0';
886
            iTXFIFORead <= '0';
887
            iTXRunning  <= '0';
888
        elsif (CLK'event and CLK = '1') then
889
            -- Defaults
890
            iTXStart    <= '0';
891
            iTXFIFORead <= '0';
892
            iTXRunning  <= '0';
893
 
894
            case State is
895 13 hasw
                when IDLE       =>  if (iTXEnable = '1') then
896 2 hasw
                                        iTXStart <= '1';            -- Start transmitter
897
                                        State := TXSTART;
898
                                    else
899
                                        State := IDLE;
900
                                    end if;
901
                when TXSTART    =>  iTSR <= iTXFIFOQ;
902
                                    iTXStart <= '1';                -- Start transmitter
903
                                    iTXFIFORead <= '1';             -- Increment TX FIFO read counter
904
                                    State := TXRUN;
905
                when TXRUN      =>  if (iTXFinished = '1') then     -- TX finished
906
                                        State := TXEND;
907
                                    else
908
                                        State := TXRUN;
909
                                    end if;
910
                                    iTXRunning <= '1';
911
                                    iTXStart   <= '1';
912
                when TXEND      =>  State := IDLE;
913
                when others     =>  State := IDLE;
914
            end case;
915
        end if;
916
    end process;
917
 
918
    -- Receiver process
919
    UART_RXPROC: process (CLK, RST)
920
        type state_type is (IDLE, RXSAVE);
921
        variable State : state_type;
922
    begin
923
        if (RST = '1') then
924
            State        := IDLE;
925
            iRXFIFOWrite <= '0';
926
            iRXFIFOClear <= '0';
927
            iRXFIFOD     <= (others => '0');
928
        elsif (CLK'event and CLK = '1') then
929
            -- Defaults
930
            iRXFIFOWrite <= '0';
931
            iRXFIFOClear <= iFCR_RXFIFOReset;
932
 
933
            case State is
934
                when IDLE       =>  if (iRXFinished = '1') then     -- Receive finished
935
                                        iRXFIFOD <= iRXBI & iRXFE & iRXPE & iRXData;
936
                                        if (iFCR_FIFOEnable = '0') then
937
                                            iRXFIFOClear <= '1';    -- Non-FIFO mode
938
                                        end if;
939
                                        State := RXSAVE;
940
                                    else
941
                                        State := IDLE;
942
                                    end if;
943
                when RXSAVE    =>   if (iFCR_FIFOEnable = '0') then
944
                                        iRXFIFOWrite <= '1';        -- Non-FIFO mode: Overwrite
945
                                    elsif (iRXFIFOFull = '0') then
946
                                        iRXFIFOWrite <= '1';        -- FIFO mode
947
                                    end if;
948
                                    State := IDLE;
949
                when others     =>  State := IDLE;
950
            end case;
951
        end if;
952
    end process;
953
 
954 13 hasw
    -- Automatic flow control
955
    UART_AFC: process (CLK, RST)
956
    begin
957
        if (RST = '1') then
958
            iRTS <= '0';
959
        elsif (CLK'event and CLK = '1') then
960
            if (iMCR_RTS = '0' or (iMCR_AFE = '1' and iRXFIFOTrigger = '1')) then
961
                -- Deassert when MCR_RTS is not set or AFC is enabled and the RX FIFO trigger level is reached
962
                iRTS <= '0';
963
            elsif (iMCR_RTS = '1' and (iMCR_AFE = '0' or (iMCR_AFE = '1' and iRXFIFOEmpty = '1'))) then
964
                -- Assert when MCR_RTS is set and AFC is disabled or when AFC is enabled and the RX FIFO is empty
965
                iRTS <= '1';
966
            end if;
967
        end if;
968
    end process;
969 2 hasw
 
970 9 hasw
    -- Output registers
971
    UART_OUTREGS: process (CLK, RST)
972
    begin
973
        if (RST = '1') then
974
            DDIS     <= '0';
975
            BAUDOUTN <= '0';
976
            OUT1N    <= '0';
977
            OUT2N    <= '0';
978
            RTSN     <= '0';
979
            DTRN     <= '0';
980
            SOUT     <= '0';
981
        elsif (CLK'event and CLK = '1') then
982
            -- Default values
983
            DDIS     <= '0';
984
            BAUDOUTN <= '0';
985
            OUT1N    <= '0';
986
            OUT2N    <= '0';
987
            RTSN     <= '0';
988
            DTRN     <= '0';
989
            SOUT     <= '0';
990 2 hasw
 
991 9 hasw
            -- DDIS
992
            if (CS = '0' or RD = '0') then
993
                DDIS <= '1';
994
            end if;
995
            -- BAUDOUTN
996
            if (iBaudtick16x = '0') then
997
                BAUDOUTN <= '1';
998
            end if;
999
            -- OUT1N
1000
            if (iMCR_LOOP = '1' or iMCR_OUT1 = '0') then
1001
                OUT1N <= '1';
1002
            end if;
1003
            -- OUT2N
1004
            if (iMCR_LOOP = '1' or iMCR_OUT2 = '0') then
1005
                OUT2N <= '1';
1006
            end if;
1007
            -- RTS
1008 13 hasw
            if (iMCR_LOOP = '1' or iRTS = '0') then
1009 9 hasw
                RTSN <= '1';
1010
            end if;
1011
            -- DTR
1012
            if (iMCR_LOOP = '1' or iMCR_DTR = '0') then
1013
                DTRN <= '1';
1014
            end if;
1015
            -- SOUT
1016
            if (iMCR_LOOP = '1' or iSOUT = '1') then
1017
                SOUT <= '1';
1018
            end if;
1019
        end if;
1020
    end process;
1021
 
1022
 
1023 2 hasw
    -- UART data output
1024
    UART_DOUT: process (A, iLCR_DLAB, iRBR, iDLL, iDLM, iIER, iIIR, iLCR, iMCR, iLSR, iMSR, iSCR)
1025
    begin
1026
        case A is
1027
            when "000"  =>  if (iLCR_DLAB = '0') then
1028
                                DOUT <= iRBR;
1029
                            else
1030
                                DOUT <= iDLL;
1031
                            end if;
1032
            when "001"  =>  if (iLCR_DLAB = '0') then
1033
                                DOUT <= iIER;
1034
                            else
1035
                                DOUT <= iDLM;
1036
                            end if;
1037
            when "010"  =>  DOUT <= iIIR;
1038
            when "011"  =>  DOUT <= iLCR;
1039
            when "100"  =>  DOUT <= iMCR;
1040
            when "101"  =>  DOUT <= iLSR;
1041
            when "110"  =>  DOUT <= iMSR;
1042
            when "111"  =>  DOUT <= iSCR;
1043
            when others =>  DOUT <= iRBR;
1044
        end case;
1045
    end process;
1046
 
1047
end rtl;
1048
 
1049
 

powered by: WebSVN 2.1.0

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