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

Subversion Repositories wb_uart

[/] [wb_uart/] [trunk/] [src/] [wb8_uart_16750.vhd] - Blame information for rev 12

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

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

powered by: WebSVN 2.1.0

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