📄 gh_uart_16550.vhd
字号:
-----------------------------------------------------------------------------
-- Filename: gh_uart_16550.vhd
--
-- Description:
-- designed to be a 16550 compatible UART
--
-- Copyright (c) 2006, 2007 by H LeFevre
-- A VHDL 16550 UART core
-- an OpenCores.org Project
-- free to use, but see documentation for conditions
--
-- Revision History:
-- Revision Date Author Comment
-- -------- ---------- --------- -----------
-- 1.0 02/25/06 H LeFevre Initial revision
-- 1.1 03/18/06 H LeFevre mod to clear THREmpty interrupt
-- with IIR read
-- 1.2 04/08/06 H LeFevre add time out interrupt
-- 1.3 04/19/06 H LeFevre fix read fifo signal, so fifo
-- will not lose data when baud rate
-- generator is read
-- 2.0 12/13/06 H LeFevre Fixed THRE interrupt, as recommended
-- by Walter Hogan 12/12/06
-- 2.1 12/23/06 H LeFevre replace fifo's
-- 2.2 01/20/07 H LeFevre replace read fifo
-- 2.3 02/22/07 B Chini Modified TOI Function To Work as Specified in 16550D manual
-- 2.4 07/12/07 H LeFevre fix 6, 7 bits transfers (LCR bits 1,0 were swapped
-- as pointed out by Matthias Klemm
-- 2.5 08/03/07 H LeFevre Mod TOI to fix issues missed in 2.3 (enabled with receiveIRQ,
-- time reset with receive word- as Specified in 16550D manual)
-- 2.6 08/04/07 H LeFevre load TOI when receive IRQ disabled
--
-----------------------------------------------------------------------------
library ieee ;
use ieee.std_logic_1164.all ;
entity gh_uart_16550 is
port(
clk : in std_logic;
BR_clk : in std_logic;
rst : in std_logic;
CS : in std_logic;
WR : in std_logic;
ADD : in std_logic_vector(2 downto 0);
D : in std_logic_vector(7 downto 0);
sRX : in std_logic;
CTSn : in std_logic := '1';
DSRn : in std_logic := '1';
RIn : in std_logic := '1';
DCDn : in std_logic := '1';
sTX : out std_logic;
DTRn : out std_logic;
RTSn : out std_logic;
OUT1n : out std_logic;
OUT2n : out std_logic;
TXRDYn : out std_logic;
RXRDYn : out std_logic;
IRQ : out std_logic;
B_CLK : out std_logic;
RD : out std_logic_vector(7 downto 0)
);
end entity;
architecture a of gh_uart_16550 is
COMPONENT gh_edge_det is
PORT(
clk : in STD_LOGIC;
rst : in STD_LOGIC;
D : in STD_LOGIC;
re : out STD_LOGIC; -- rising edge (need sync source at D)
fe : out STD_LOGIC; -- falling edge (need sync source at D)
sre : out STD_LOGIC; -- sync'd rising edge
sfe : out STD_LOGIC -- sync'd falling edge
);
END COMPONENT;
COMPONENT gh_register_ce is
GENERIC (size: INTEGER := 8);
PORT(
clk : IN STD_LOGIC;
rst : IN STD_LOGIC;
CE : IN STD_LOGIC; -- clock enable
D : IN STD_LOGIC_VECTOR(size-1 DOWNTO 0);
Q : OUT STD_LOGIC_VECTOR(size-1 DOWNTO 0)
);
END COMPONENT;
COMPONENT gh_DECODE_3to8 is
port(
A : IN STD_LOGIC_VECTOR(2 DOWNTO 0); -- address
G1 : IN STD_LOGIC; -- enable positive
G2n : IN STD_LOGIC; -- enable negitive
G3n : IN STD_LOGIC; -- enable negitive
Y : out STD_LOGIC_VECTOR(7 downto 0)
);
END COMPONENT;
COMPONENT gh_jkff is
PORT(
clk : IN STD_logic;
rst : IN STD_logic;
J,K : IN STD_logic;
Q : OUT STD_LOGIC
);
END COMPONENT;
COMPONENT gh_uart_Tx_8bit is
port(
clk : in std_logic; -- clock
rst : in std_logic;
xBRC : in std_logic; -- x clock enable
D_RYn : in std_logic; -- data ready
D : in std_logic_vector(7 downto 0);
num_bits : in integer:= 8; -- number of bits in transfer
Break_CB : in std_logic;
stopB : in std_logic;
Parity_EN : in std_logic;
Parity_EV : in std_logic;
sTX : out std_logic;
BUSYn : out std_logic;
read : out std_logic -- data read
);
END COMPONENT;
COMPONENT gh_uart_Rx_8bit is
port(
clk : in std_logic; -- clock
rst : in std_logic;
BRCx16 : in std_logic; -- 16x clock enable
sRX : in std_logic;
num_bits : in integer;
Parity_EN : in std_logic;
Parity_EV : in std_logic;
Parity_ER : out std_logic;
Frame_ER : out std_logic;
Break_ITR : out std_logic;
D_RDY : out std_logic;
D : out std_logic_vector(7 downto 0)
);
END COMPONENT;
COMPONENT gh_fifo_async16_sr is
GENERIC (data_width: INTEGER :=8 ); -- size of data bus
port (
clk_WR : in STD_LOGIC; -- write clock
clk_RD : in STD_LOGIC; -- read clock
rst : in STD_LOGIC; -- resets counters
srst : in STD_LOGIC; -- resets counters
WR : in STD_LOGIC; -- write control
RD : in STD_LOGIC; -- read control
D : in STD_LOGIC_VECTOR (data_width-1 downto 0);
Q : out STD_LOGIC_VECTOR (data_width-1 downto 0);
empty : out STD_LOGIC;
full : out STD_LOGIC);
END COMPONENT;
COMPONENT gh_baud_rate_gen is
port(
clk : in std_logic;
rst : in std_logic;
BR_clk : in std_logic;
WR : in std_logic;
BE : in std_logic_vector (1 downto 0); -- byte enable
D : in std_logic_vector (15 downto 0);
RD : out std_logic_vector (15 downto 0);
rCE : out std_logic;
rCLK : out std_logic
);
END COMPONENT;
COMPONENT gh_fifo_async16_rcsr_wf is
GENERIC (data_width: INTEGER :=8 ); -- size of data bus
port (
clk_WR : in STD_LOGIC; -- write clock
clk_RD : in STD_LOGIC; -- read clock
rst : in STD_LOGIC; -- resets counters
rc_srst : in STD_LOGIC:='0'; -- resets counters (sync with clk_RD!!!)
WR : in STD_LOGIC; -- write control
RD : in STD_LOGIC; -- read control
D : in STD_LOGIC_VECTOR (data_width-1 downto 0);
Q : out STD_LOGIC_VECTOR (data_width-1 downto 0);
empty : out STD_LOGIC; -- sync with clk_RD!!!
q_full : out STD_LOGIC; -- sync with clk_RD!!!
h_full : out STD_LOGIC; -- sync with clk_RD!!!
a_full : out STD_LOGIC; -- sync with clk_RD!!!
full : out STD_LOGIC);
END COMPONENT;
COMPONENT gh_counter_down_ce_ld_tc IS
GENERIC (size: INTEGER :=8);
PORT(
CLK : IN STD_LOGIC;
rst : IN STD_LOGIC;
LOAD : IN STD_LOGIC;
CE : IN STD_LOGIC;
D : IN STD_LOGIC_VECTOR(size-1 DOWNTO 0);
Q : OUT STD_LOGIC_VECTOR(size-1 DOWNTO 0);
TC : OUT STD_LOGIC
);
END COMPONENT;
COMPONENT gh_edge_det_XCD is -- added 2 aug 2007
port(
iclk : in STD_LOGIC; -- clock for input data signal
oclk : in STD_LOGIC; -- clock for output data pulse
rst : in STD_LOGIC;
D : in STD_LOGIC;
re : out STD_LOGIC; -- rising edge
fe : out STD_LOGIC -- falling edge
);
END COMPONENT;
signal IER : std_logic_vector(3 downto 0); -- Interrupt Enable Register
signal IIR : std_logic_vector(7 downto 0); -- Interrupt ID Register
signal iIIR : std_logic_vector(3 downto 0); -- 12/23/06
signal FCR : std_logic_vector(7 downto 0); -- FIFO Control register
signal LCR : std_logic_vector(7 downto 0); -- Line Control Register
signal MCR : std_logic_vector(4 downto 0); -- Modem Control Register
signal LSR : std_logic_vector(7 downto 0); -- Line Status Register
signal MSR : std_logic_vector(7 downto 0); -- Modem Status Register
signal SCR : std_logic_vector(7 downto 0); -- Line Control Register
signal RDD : std_logic_vector(15 downto 0); -- Divisor Latch
signal iMSR : std_logic_vector(7 downto 4); -- Modem Status Register
signal RD_IIR : std_logic;
signal iRD : std_logic_vector(7 downto 0);
signal CSn : std_logic;
signal WR_B : std_logic_vector(7 downto 0);
signal WR_F : std_logic;
signal WR_IER : std_logic;
signal WR_D : std_logic;
signal WR_DML : std_logic_vector(1 downto 0);
signal D16 : std_logic_vector(15 downto 0);
signal BRC16x : std_logic; -- baud rate clock
signal ITR0 : std_logic;
signal isITR1 : std_logic;
signal sITR1 : std_logic;
signal cITR1 : std_logic;
signal cITR1a : std_logic;
signal ITR1 : std_logic;
signal ITR2 : std_logic;
signal ITR3 : std_logic;
signal DCTS : std_logic;
signal CTSn_RE : std_logic;
signal CTSn_FE : std_logic;
signal iDCTS : std_logic;
signal iLOOP : std_logic;
signal DDSR : std_logic;
signal DSRn_RE : std_logic;
signal DSRn_FE : std_logic;
signal iDDSR : std_logic;
signal TERI : std_logic;
signal RIn_RE : std_logic;
signal DDCD : std_logic;
signal DCDn_RE : std_logic;
signal DCDn_FE : std_logic;
signal iDDCD : std_logic;
signal RD_MSR : std_logic;
signal MSR_CLR : std_logic;
signal RD_LSR : std_logic;
signal LSR_CLR : std_logic;
signal num_bits : integer:=0;
signal stopB : std_logic;
signal Parity_EN : std_logic;
signal Parity_OD : std_logic;
signal Parity_EV : std_logic;
-- signal Parity_sticky : std_logic;
signal Break_CB : std_logic;
signal TF_RD : std_logic;
signal TF_CLR : std_logic;
signal TF_CLRS : std_logic;
signal TF_DO : std_logic_vector(7 downto 0);
signal TF_empty : std_logic;
signal TF_full : std_logic;
signal RF_WR : std_logic;
signal RF_RD : std_logic;
signal RF_RD_brs : std_logic; -- added 3 aug 2007
signal RF_CLR : std_logic;
signal RF_CLRS : std_logic;
signal RF_DI : std_logic_vector(10 downto 0); -- Read FIFO data input
signal RF_DO : std_logic_vector(10 downto 0); -- Read FIFO data output
signal RF_empty : std_logic;
signal RF_full : std_logic;
signal RD_RDY : std_logic;
signal Parity_ER : std_logic;
signal FRAME_ER : std_logic;
signal Break_ITR : std_logic;
signal TSR_EMPTY : std_logic;
signal OVR_ER : std_logic;
signal isTX : std_logic;
signal isRX : std_logic;
signal q_full : std_logic;
signal h_full : std_logic;
signal a_full : std_logic;
signal RF_ER : std_logic;
signal TX_RDY : std_logic;
signal TX_RDYS : std_logic;
signal TX_RDYC : std_logic;
signal RX_RDY : std_logic;
signal RX_RDYS : std_logic;
signal RX_RDYC : std_logic;
signal TOI : std_logic; -- time out interrupt
signal TOI_enc : std_logic; -- time out interrupt counter inable
signal iTOI_enc : std_logic;
signal TOI_set : std_logic;
signal iTOI_set : std_logic; -- added 3 aug 2007
signal TOI_clr : std_logic;
signal TOI_c_ld : std_logic;
signal TOI_c_d : std_logic_vector(11 downto 0);
begin
----------------------------------------------
---- resd ----------------------------------
----------------------------------------------
RD <= RF_DO(7 downto 0) when ((ADD = o"0") and (LCR(7) = '0')) else
(x"0" & IER) when ((ADD = o"1") and (LCR(7) = '0')) else
IIR when (ADD = o"2") else
LCR when (ADD = o"3") else
("000" & MCR) when (ADD = o"4") else
LSR when (ADD = o"5") else
MSR when (ADD = o"6") else
SCR when (ADD = o"7") else
RDD(7 downto 0) when (ADD = o"0") else
RDD(15 downto 8);
----------------------------------------------
U1 : gh_jkff
PORT MAP (
clk => clk,
rst => rst,
j => TX_RDYS,
k => TX_RDYC,
Q => TX_RDY);
TXRDYn <= (not TX_RDY);
TX_RDYS <= '1' when ((FCR(3) = '0') and (TF_empty = '1') and (TSR_EMPTY = '1')) else
'1' when ((FCR(3) = '1') and (TF_empty = '1')) else
'0';
TX_RDYC <= '1' when ((FCR(3) = '0') and (TF_empty = '0')) else
'1' when ((FCR(3) = '1') and (TF_full = '1')) else
'0';
U2 : gh_jkff
PORT MAP (
clk => clk,
rst => rst,
j => RX_RDYS,
k => RX_RDYC,
Q => RX_RDY);
RXRDYn <= (not RX_RDY);
RX_RDYS <= '1' when ((FCR(3) = '0') and (RF_empty = '0')) else -- mod 01/20/07
'1' when ((FCR(3) = '1') and (FCR(7 downto 6) = "11") and (a_full = '1')) else
'1' when ((FCR(3) = '1') and (FCR(7 downto 6) = "10") and (h_full = '1')) else
'1' when ((FCR(3) = '1') and (FCR(7 downto 6) = "01") and (q_full = '1')) else
'1' when ((FCR(3) = '1') and (FCR(7 downto 6) = "00") and (RF_empty = '0')) else
'0';
RX_RDYC <= '1' when (RF_empty = '1') else
'0';
----------------------------------------------
---- Modem Status Register Bits --------------
----------------------------------------------
U3 : gh_edge_det
PORT MAP (
clk => clk,
rst => rst,
d => CTSn,
sre => CTSn_RE,
sfe => CTSn_FE);
iDCTS <= CTSn_RE or CTSn_FE;
U4 : gh_jkff
PORT MAP (
clk => clk,
rst => rst,
j => iDCTS,
k => MSR_CLR,
Q => DCTS);
MSR(0) <= DCTS;
U5 : gh_edge_det
PORT MAP (
clk => clk,
rst => rst,
d => DSRn,
sre => DSRn_RE,
sfe => DSRn_FE);
iDDSR <= DSRn_RE or DSRn_FE;
U6 : gh_jkff
PORT MAP (
clk => clk,
rst => rst,
j => iDDSR,
k => MSR_CLR,
Q => DDSR);
MSR(1) <= DDSR;
U7 : gh_edge_det
PORT MAP (
clk => clk,
rst => rst,
d => RIn,
sre => RIn_RE);
U8 : gh_jkff
PORT MAP (
clk => clk,
rst => rst,
j => RIn_RE,
k => MSR_CLR,
Q => TERI);
MSR(2) <= TERI;
U9 : gh_edge_det
PORT MAP (
clk => clk,
rst => rst,
d => DCDn,
sre => DCDn_RE,
sfe => DCDn_FE);
iDDCD <= DCDn_RE or DCDn_FE;
U10 : gh_jkff
PORT MAP (
clk => clk,
rst => rst,
j => iDDCD,
k => MSR_CLR,
Q => DDCD);
MSR(3) <= DDCD;
iMSR(4) <= (not CTSn) when (iLOOP = '0') else
MCR(1);
iMSR(5) <= (not DSRn) when (iLOOP = '0') else
MCR(0);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -