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

Subversion Repositories t80

[/] [t80/] [trunk/] [rtl/] [vhdl/] [T16450.vhd] - Blame information for rev 9

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

Line No. Rev Author Line
1 9 jesus
--
2
-- 16450 compatible UART with synchronous bus interface
3
-- RClk/BaudOut is XIn enable instead of actual clock
4
-- No break detection, no modem status change detection
5
-- Only one stop bit supported
6
--
7
-- Version : 0208
8
--
9
-- Copyright (c) 2002 Daniel Wallner (jesus@opencores.org)
10
--
11
-- All rights reserved
12
--
13
-- Redistribution and use in source and synthezised forms, with or without
14
-- modification, are permitted provided that the following conditions are met:
15
--
16
-- Redistributions of source code must retain the above copyright notice,
17
-- this list of conditions and the following disclaimer.
18
--
19
-- Redistributions in synthesized form must reproduce the above copyright
20
-- notice, this list of conditions and the following disclaimer in the
21
-- documentation and/or other materials provided with the distribution.
22
--
23
-- Neither the name of the author nor the names of other contributors may
24
-- be used to endorse or promote products derived from this software without
25
-- specific prior written permission.
26
--
27
-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
28
-- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
29
-- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
30
-- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE
31
-- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
32
-- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
33
-- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
34
-- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
35
-- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
36
-- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
37
-- POSSIBILITY OF SUCH DAMAGE.
38
--
39
-- Please report bugs to the author, but before you do so, please
40
-- make sure that this is not a derivative work and that
41
-- you have the latest version of this file.
42
--
43
-- The latest version of this file can be found at:
44
--      http://www.opencores.org/cvsweb.shtml/t80/
45
--
46
-- Limitations :
47
--
48
-- File history :
49
--
50
 
51
library IEEE;
52
use IEEE.std_logic_1164.all;
53
use IEEE.numeric_std.all;
54
 
55
entity T16450 is
56
        port(
57
                MR_n            : in std_logic;
58
                XIn                     : in std_logic;
59
                RClk            : in std_logic;
60
                CS_n            : in std_logic;
61
                Rd_n            : in std_logic;
62
                Wr_n            : in std_logic;
63
                A                       : in std_logic_vector(2 downto 0);
64
                D_In            : in std_logic_vector(7 downto 0);
65
                D_Out           : out std_logic_vector(7 downto 0);
66
                SIn                     : in std_logic;
67
                CTS_n           : in std_logic;
68
                DSR_n           : in std_logic;
69
                RI_n            : in std_logic;
70
                DCD_n           : in std_logic;
71
                SOut            : out std_logic;
72
                RTS_n           : out std_logic;
73
                DTR_n           : out std_logic;
74
                OUT1_n          : out std_logic;
75
                OUT2_n          : out std_logic;
76
                BaudOut         : out std_logic;
77
                Intr            : out std_logic
78
        );
79
end T16450;
80
 
81
architecture rtl of T16450 is
82
 
83
        signal  RBR                             : std_logic_vector(7 downto 0);  -- Reciever Buffer Register
84
        signal  THR                             : std_logic_vector(7 downto 0);  -- Transmitter Holding Register
85
        signal  IER                             : std_logic_vector(7 downto 0);  -- Interrupt Enable Register
86
        signal  IIR                             : std_logic_vector(7 downto 0);  -- Interrupt Ident. Register
87
        signal  LCR                             : std_logic_vector(7 downto 0);  -- Line Control Register
88
        signal  MCR                             : std_logic_vector(7 downto 0);  -- MODEM Control Register
89
        signal  LSR                             : std_logic_vector(7 downto 0);  -- Line Status Register
90
        signal  MSR                             : std_logic_vector(7 downto 0);  -- MODEM Status Register
91
        signal  SCR                             : std_logic_vector(7 downto 0);  -- Scratch Register
92
        signal  DLL                             : std_logic_vector(7 downto 0);  -- Divisor Latch (LS)
93
        signal  DLM                             : std_logic_vector(7 downto 0);  -- Divisor Latch (MS)
94
 
95
        signal  DM0                             : std_logic_vector(7 downto 0);
96
        signal  DM1                             : std_logic_vector(7 downto 0);
97
 
98
        signal  Bit_Phase               : unsigned(3 downto 0);
99
        signal  RX_Filtered             : std_logic;
100
        signal  RX_ShiftReg             : std_logic_vector(7 downto 0);
101
        signal  RX_Bit_Cnt              : integer range 0 to 11;
102
        signal  RX_Parity               : std_logic;
103
        signal  RXD                             : std_logic;
104
 
105
        signal  TX_Tick                 : std_logic;
106
        signal  TX_ShiftReg             : std_logic_vector(7 downto 0);
107
        signal  TX_Bit_Cnt              : integer range 0 to 11;
108
        signal  TX_Parity               : std_logic;
109
        signal  TXD                             : std_logic;
110
 
111
begin
112
 
113
        DTR_n <= MCR(4) or not MCR(0);
114
        RTS_n <= MCR(4) or not MCR(1);
115
        OUT1_n <= MCR(4) or not MCR(2);
116
        OUT2_n <= MCR(4) or not MCR(3);
117
        SOut <= (MCR(4) or TXD) and not LCR(6);
118
        RXD <= SIn when MCR(4) = '0' else TXD;
119
 
120
        Intr <= not IIR(0);
121
 
122
        -- Registers
123
        DM0 <= DLL when LCR(7) = '1' else RBR;
124
        DM1 <= DLM when LCR(7) = '1' else IER;
125
        with A select
126
                D_Out <=
127
                        DM0 when "000",
128
                        DM1 when "001",
129
                        IIR when "010",
130
                        LCR when "011",
131
                        MCR when "100",
132
                        LSR when "101",
133
                        MSR when "110",
134
                        SCR when others;
135
        process (MR_n, XIn)
136
        begin
137
                if MR_n = '0' then
138
                        THR <= "00000000";
139
                        IER <= "00000000";
140
                        LCR <= "00000000";
141
                        MCR <= "00000000";
142
                        MSR <= "00000000";
143
                        SCR <= "00000000"; -- ??
144
                        DLL <= "00000000"; -- ??
145
                        DLM <= "00000000"; -- ??
146
                elsif XIn'event and XIn = '1' then
147
                        if Wr_n = '0' and CS_n = '0' then
148
                                case A is
149
                                when "000" =>
150
                                        if LCR(7) = '1' then
151
                                                DLL <= D_In;
152
                                        else
153
                                                THR <= D_In;
154
                                        end if;
155
                                when "001" =>
156
                                        if LCR(7) = '1' then
157
                                                DLM <= D_In;
158
                                        else
159
                                                IER(3 downto 0) <= D_In(3 downto 0);
160
                                        end if;
161
                                when "011" =>
162
                                        LCR <= D_In;
163
                                when "100" =>
164
                                        MCR <= D_In;
165
                                when "111" =>
166
                                        SCR <= D_In;
167
                                when others =>
168
                                end case;
169
                        end if;
170
                        if MCR(4) = '0' then
171
                                MSR(4) <= CTS_n;
172
                                MSR(5) <= DSR_n;
173
                                MSR(6) <= RI_n;
174
                                MSR(7) <= DCD_n;
175
                        else
176
                                MSR(4) <= MCR(1);
177
                                MSR(5) <= MCR(0);
178
                                MSR(6) <= MCR(2);
179
                                MSR(7) <= MCR(3);
180
                        end if;
181
                end if;
182
        end process;
183
 
184
        IIR(7 downto 3) <= "00000";
185
        IIR(2 downto 0) <=
186
                "110" when IER(2) = '1' and LSR(4 downto 1) /= "0000" else
187
                "110" when (IER(0) and LSR(0)) = '1' else
188
                "010" when (IER(1) and LSR(5)) = '1' else
189
                "001" when IER(3) = '1' and ((MCR(4) = '0' and MSR(3 downto 0) /= "0000") or
190
                                                                        (MCR(4) = '1' and MCR(3 downto 0) /= "0000")) else
191
                "001";
192
 
193
        -- Baud x 16 clock generator
194
        process (MR_n, XIn)
195
                variable Baud_Cnt : unsigned(15 downto 0);
196
        begin
197
                if MR_n = '0' then
198
                        Baud_Cnt := "0000000000000001";
199
                        BaudOut <= '0';
200
                elsif XIn'event and XIn = '1' then
201
                        if Baud_Cnt = "0000000000000001" or (Wr_n = '0' and CS_n = '0' and A(2 downto 1) = "00" and LCR(7) = '1') then
202
                                Baud_Cnt(15 downto 8) := unsigned(DLM);
203
                                Baud_Cnt(7 downto 0) := unsigned(DLL);
204
                                BaudOut <= '1';
205
                        else
206
                                Baud_Cnt := Baud_Cnt - 1;
207
                                BaudOut <= '0';
208
                        end if;
209
                end if;
210
        end process;
211
 
212
        -- Input filter
213
        process (MR_n, XIn)
214
                variable Samples : std_logic_vector(1 downto 0);
215
        begin
216
                if MR_n = '0' then
217
                        Samples := "11";
218
                        RX_Filtered <= '1';
219
                elsif XIn'event and XIn = '1' then
220
                        if RClk = '1' then
221
                                Samples(1) := Samples(0);
222
                                Samples(0) := RXD;
223
                        end if;
224
                        if Samples = "00" then
225
                                RX_Filtered <= '0';
226
                        end if;
227
                        if Samples = "11" then
228
                                RX_Filtered <= '1';
229
                        end if;
230
                end if;
231
        end process;
232
 
233
        -- Receive state machine
234
        process (MR_n, XIn)
235
        begin
236
                if MR_n = '0' then
237
                        RBR <= "00000000";
238
                        LSR(4 downto 0) <= "00000";
239
                        Bit_Phase <= "0000";
240
                        RX_ShiftReg(7 downto 0) <= "00000000";
241
                        RX_Bit_Cnt <= 0;
242
                        RX_Parity <= '0';
243
                elsif XIn'event and XIn = '1' then
244
                        if A = "000" and LCR(7) = '0' and Rd_n = '0' and CS_n = '0' then
245
                                LSR(0) <= '0';    -- DR
246
                        end if;
247
                        if A = "101" and Rd_n = '0' and CS_n = '0' then
248
                                LSR(3) <= '0';   -- FE
249
                                LSR(2) <= '0';   -- PE
250
                                LSR(1) <= '0';   -- OE
251
                        end if;
252
                        if RClk = '1' then
253
                                if RX_Bit_Cnt = 0 and (RX_Filtered = '1' or Bit_Phase = "0111") then
254
                                        Bit_Phase <= "0000";
255
                                else
256
                                        Bit_Phase <= Bit_Phase + 1;
257
                                end if;
258
                                if RX_Bit_Cnt = 0 then
259
                                        if Bit_Phase = "0111" then
260
                                                RX_Bit_Cnt <= RX_Bit_Cnt + 1;
261
                                                RX_Parity <= not LCR(4);        -- EPS
262
                                        end if;
263
                                elsif Bit_Phase = "1111" then
264
                                        RX_Bit_Cnt <= RX_Bit_Cnt + 1;
265
                                        if RX_Bit_Cnt = 10 then -- Parity stop bit
266
                                                RX_Bit_Cnt <= 0;
267
                                                LSR(0) <= '1'; -- UART Receive complete
268
                                                LSR(3) <= not RX_Filtered; -- Framing error
269
                                        elsif (RX_Bit_Cnt = 9 and LCR(1 downto 0) = "11") or
270
                                                (RX_Bit_Cnt = 8 and LCR(1 downto 0) = "10") or
271
                                                (RX_Bit_Cnt = 7 and LCR(1 downto 0) = "01") or
272
                                                (RX_Bit_Cnt = 6 and LCR(1 downto 0) = "00") then -- Stop bit/Parity
273
                                                RX_Bit_Cnt <= 0;
274
                                                if LCR(3) = '1' then    -- PEN
275
                                                        RX_Bit_Cnt <= 10;
276
                                                        if LCR(5) = '1' then    -- Stick parity
277
                                                                if RX_Filtered = LCR(4) then
278
                                                                        LSR(2) <= '1';
279
                                                                end if;
280
                                                        else
281
                                                                if RX_Filtered /= RX_Parity then
282
                                                                        LSR(2) <= '1';
283
                                                                end if;
284
                                                        end if;
285
                                                else
286
                                                        LSR(0) <= '1'; -- UART Receive complete
287
                                                        LSR(3) <= not RX_Filtered; -- Framing error
288
                                                end if;
289
                                                RBR <= RX_ShiftReg(7 downto 0);
290
                                                LSR(1) <= LSR(0);
291
                                                if A = "101" and Rd_n = '0' and CS_n = '0' then
292
                                                        LSR(1) <= '0';
293
                                                end if;
294
                                        else
295
                                                RX_ShiftReg(6 downto 0) <= RX_ShiftReg(7 downto 1);
296
                                                RX_ShiftReg(7) <= RX_Filtered;
297
                                                if LCR(1 downto 0) = "10" then
298
                                                        RX_ShiftReg(7) <= '0';
299
                                                        RX_ShiftReg(6) <= RX_Filtered;
300
                                                end if;
301
                                                if LCR(1 downto 0) = "01" then
302
                                                        RX_ShiftReg(7) <= '0';
303
                                                        RX_ShiftReg(6) <= '0';
304
                                                        RX_ShiftReg(5) <= RX_Filtered;
305
                                                end if;
306
                                                if LCR(1 downto 0) = "00" then
307
                                                        RX_ShiftReg(7) <= '0';
308
                                                        RX_ShiftReg(6) <= '0';
309
                                                        RX_ShiftReg(5) <= '0';
310
                                                        RX_ShiftReg(4) <= RX_Filtered;
311
                                                end if;
312
                                                RX_Parity <= RX_Filtered xor RX_Parity;
313
                                        end if;
314
                                end if;
315
                        end if;
316
                end if;
317
        end process;
318
 
319
        -- Transmit bit tick
320
        process (MR_n, XIn)
321
                variable TX_Cnt : unsigned(3 downto 0);
322
        begin
323
                if MR_n = '0' then
324
                        TX_Cnt := "0000";
325
                        TX_Tick <= '0';
326
                elsif XIn'event and XIn = '1' then
327
                        TX_Tick <= '0';
328
                        if RClk = '1' then
329
                                if TX_Cnt = "1111" then
330
                                        TX_Tick <= '1';
331
                                end if;
332
                                TX_Cnt := TX_Cnt + 1;
333
                        end if;
334
                end if;
335
        end process;
336
 
337
        -- Transmit state machine
338
        process (MR_n, XIn)
339
        begin
340
                if MR_n = '0' then
341
                        LSR(7 downto 5) <= "011";
342
                        TX_Bit_Cnt <= 0;
343
                        TX_ShiftReg <= (others => '0');
344
                        TXD <= '1';
345
                        TX_Parity <= '0';
346
                elsif XIn'event and XIn = '1' then
347
                        if TX_Tick = '1' then
348
                                case TX_Bit_Cnt is
349
                                when 0 =>
350
                                        if LSR(5) <= '0' then    -- THRE
351
                                                TX_Bit_Cnt <= 1;
352
                                        end if;
353
                                        TXD <= '1';
354
                                when 1 => -- Start bit
355
                                        TX_ShiftReg(7 downto 0) <= THR;
356
                                        LSR(5) <= '1';  -- THRE
357
                                        TXD <= '0';
358
                                        TX_Parity <= not LCR(4);        -- EPS
359
                                        TX_Bit_Cnt <= TX_Bit_Cnt + 1;
360
                                when 10 => -- Parity bit
361
                                        TXD <= TX_Parity;
362
                                        if LCR(5) = '1' then    -- Stick parity
363
                                                TXD <= not LCR(4);
364
                                        end if;
365
                                        TX_Bit_Cnt <= 0;
366
                                when others =>
367
                                        TX_Bit_Cnt <= TX_Bit_Cnt + 1;
368
                                        if (TX_Bit_Cnt = 9 and LCR(1 downto 0) = "11") or
369
                                                (TX_Bit_Cnt = 8 and LCR(1 downto 0) = "10") or
370
                                                (TX_Bit_Cnt = 7 and LCR(1 downto 0) = "01") or
371
                                                (TX_Bit_Cnt = 6 and LCR(1 downto 0) = "00") then
372
                                                TX_Bit_Cnt <= 0;
373
                                                if LCR(3) = '1' then    -- PEN
374
                                                        TX_Bit_Cnt <= 10;
375
                                                end if;
376
                                                LSR(6) <= '1';  -- TEMT
377
                                        end if;
378
                                        TXD <= TX_ShiftReg(0);
379
                                        TX_ShiftReg(6 downto 0) <= TX_ShiftReg(7 downto 1);
380
                                        TX_Parity <= TX_ShiftReg(0) xor TX_Parity;
381
                                end case;
382
                        end if;
383
                        if Wr_n = '0' and CS_n = '0' and A = "000" and LCR(7) = '0' then
384
                                LSR(5) <= '0';   -- THRE
385
                                LSR(6) <= '0';   -- TEMT
386
                        end if;
387
                end if;
388
        end process;
389
 
390
end;

powered by: WebSVN 2.1.0

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