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

Subversion Repositories uart16750

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

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

powered by: WebSVN 2.1.0

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