/
uart_interrupt.vhd
102 lines (90 loc) 路 4.15 KB
/
uart_interrupt.vhd
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
--
-- UART interrupt control
--
-- Author: Sebastian Witt
-- Date: 27.01.2008
-- Version: 1.1
--
-- History: 1.0 - Initial version
-- 1.1 - Automatic flow control
--
--
-- This code is free software; you can redistribute it and/or
-- modify it under the terms of the GNU Lesser General Public
-- License as published by the Free Software Foundation; either
-- version 2.1 of the License, or (at your option) any later version.
--
-- This code is distributed in the hope that it will be useful,
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-- Lesser General Public License for more details.
--
-- You should have received a copy of the GNU Lesser General Public
-- License along with this library; if not, write to the
-- Free Software Foundation, Inc., 59 Temple Place, Suite 330,
-- Boston, MA 02111-1307 USA
--
LIBRARY IEEE;
USE IEEE.std_logic_1164.all;
USE IEEE.numeric_std.all;
-- Serial UART interrupt control
entity uart_interrupt is
port (
CLK : in std_logic; -- Clock
RST : in std_logic; -- Reset
IER : in std_logic_vector(3 downto 0); -- IER 3:0
LSR : in std_logic_vector(4 downto 0); -- LSR 4:0
THI : in std_logic; -- Transmitter holding register empty interrupt
RDA : in std_logic; -- Receiver data available
CTI : in std_logic; -- Character timeout indication
AFE : in std_logic; -- Automatic flow control enable
MSR : in std_logic_vector(3 downto 0); -- MSR 3:0
IIR : out std_logic_vector(3 downto 0); -- IIR 3:0
INT : out std_logic -- Interrupt
);
end uart_interrupt;
architecture rtl of uart_interrupt is
-- Signals
signal iRLSInterrupt : std_logic; -- Receiver line status interrupt
signal iRDAInterrupt : std_logic; -- Received data available interrupt
signal iCTIInterrupt : std_logic; -- Character timeout indication interrupt
signal iTHRInterrupt : std_logic; -- Transmitter holding register empty interrupt
signal iMSRInterrupt : std_logic; -- Modem status interrupt
signal iIIR : std_logic_vector(3 downto 0); -- IIR register
begin
-- Priority 1: Receiver line status interrupt on: Overrun error, parity error, framing error or break interrupt
iRLSInterrupt <= IER(2) and (LSR(1) or LSR(2) or LSR(3) or LSR(4));
-- Priority 2: Received data available or trigger level reached in FIFO mode
iRDAInterrupt <= IER(0) and RDA;
-- Priority 2: Character timeout indication
iCTIInterrupt <= IER(0) and CTI;
-- Priority 3: Transmitter holding register empty
iTHRInterrupt <= IER(1) and THI;
-- Priority 4: Modem status interrupt: dCTS (when AFC is disabled), dDSR, TERI, dDCD
iMSRInterrupt <= IER(3) and ((MSR(0) and not AFE) or MSR(1) or MSR(2) or MSR(3));
-- IIR
IC_IIR: process (CLK, RST)
begin
if (RST = '1') then
iIIR <= "0001"; -- TODO: Invert later
elsif (CLK'event and CLK = '1') then
-- IIR register
if (iRLSInterrupt = '1') then
iIIR <= "0110";
elsif (iCTIInterrupt = '1') then
iIIR <= "1100";
elsif (iRDAInterrupt = '1') then
iIIR <= "0100";
elsif (iTHRInterrupt = '1') then
iIIR <= "0010";
elsif (iMSRInterrupt = '1') then
iIIR <= "0000";
else
iIIR <= "0001";
end if;
end if;
end process;
-- Outputs
IIR <= iIIR;
INT <= not iIIR(0);
end rtl;