📄 intface.vhd
字号:
LIBRARY IEEE;
USE IEEE.Std_Logic_1164.all;
USE IEEE.std_logic_unsigned.all;
ENTITY Intface IS
PORT (
-- 全局复位和时钟
Reset : IN STD_LOGIC; -- Master reset
Clk16X : IN STD_LOGIC; -- UART internal clock
-- 处理器接口
ADDR : IN STD_LOGIC_VECTOR(2 DOWNTO 0); -- Address bus
DATAIN : IN STD_LOGIC_VECTOR(7 DOWNTO 0); -- Data bus input
DATAOUT : OUT STD_LOGIC_VECTOR(7 DOWNTO 0); -- Data bus output
Addr_Strob : IN STD_LOGIC; -- Address strobe
CS : IN STD_LOGIC; -- Chip Select
Up_read : IN STD_LOGIC; -- Read
Up_write : IN STD_LOGIC; -- Write
DDIS : OUT STD_LOGIC; -- Driver disable
INTR : OUT STD_LOGIC; -- Interrupt
-- 寄存器
RBR : IN STD_LOGIC_VECTOR(7 DOWNTO 0); --接收缓冲寄存器
THR : OUT STD_LOGIC_VECTOR(7 DOWNTO 0); -- 发送缓冲寄存器
MSR : IN STD_LOGIC_VECTOR(7 DOWNTO 0); -- Modem状态寄存器
MCR : OUT STD_LOGIC_VECTOR(1 DOWNTO 0); -- Modem控制寄存器
--读写寄存器选通信号上升沿
RbrRDn_re : OUT STD_LOGIC; -- pulse indicating rising OF RbrRDn_r
ThrWRn_re : OUT STD_LOGIC; -- pulse indicating rising OF ThrWRn_r
LsrRDn_re : inout STD_LOGIC; -- pulse indicating rising OF LsrRDn_r
MsrRDn_re : inout STD_LOGIC; -- pulse indicating rising OF MsrRDn_r
-- 收发器控制
Databits : OUT STD_LOGIC_VECTOR(1 DOWNTO 0);
Stopbits : OUT STD_LOGIC_VECTOR(1 DOWNTO 0);
ParityEnable: OUT STD_LOGIC;
ParityEven : OUT STD_LOGIC;
ParityStick : OUT STD_LOGIC;
TxBreak : OUT STD_LOGIC;
-- 收发器状态
RxRDY : IN STD_LOGIC;
OverrunErr : IN STD_LOGIC;
ParityErr : IN STD_LOGIC;
FrameErr : IN STD_LOGIC;
BreakInt : IN STD_LOGIC;
THRE : IN STD_LOGIC;
TEMT : IN STD_LOGIC
);
END Intface;
ARCHITECTURE Intface_arch OF Intface IS
SIGNAL ADDR_s : STD_LOGIC_VECTOR(2 DOWNTO 0); -- Latched address bus
SIGNAL CS_r : STD_LOGIC; -- Latched CS SIGNAL
SIGNAL WRn_cs : STD_LOGIC; -- Write strobe qualified by latched CS SIGNAL
SIGNAL RDn_cs : STD_LOGIC; -- Read strobe qualified by latched CS SIGNAL
SIGNAL LSR : STD_LOGIC_VECTOR(6 DOWNTO 0);
SIGNAL LCR : STD_LOGIC_VECTOR(6 DOWNTO 0);
SIGNAL IIR : STD_LOGIC_VECTOR(3 DOWNTO 0);
SIGNAL IER : STD_LOGIC_VECTOR(3 DOWNTO 0);
SIGNAL ThrWRn_r : STD_LOGIC; -- THR write strobe
SIGNAL RbrRDn_r : STD_LOGIC; -- RBR read strobe
SIGNAL LsrRDn_r : STD_LOGIC; -- LSR read strobe
SIGNAL MsrRDn_r : STD_LOGIC; -- MSR read strobe
SIGNAL IirRDn_r : STD_LOGIC; -- IIR read strobe
SIGNAL IirRDn_re : STD_LOGIC; -- Rising edge OF IIR read strobe
SIGNAL ThrWRn1_r : STD_LOGIC; -- 1-clock Delayed version for edge detection
SIGNAL ThrWRn2_r : STD_LOGIC; -- 2-clock Delayed version for edge detection
SIGNAL RbrRDn1_r : STD_LOGIC; -- 1-clock Delayed version for edge detection
SIGNAL RbrRDn2_r : STD_LOGIC; -- 2-clock Delayed version for edge detection
SIGNAL LsrRDn1_r : STD_LOGIC; -- 1-clock Delayed version for edge detection
SIGNAL LsrRDn2_r : STD_LOGIC; -- 2-clock Delayed version for edge detection
SIGNAL MsrRDn1_r : STD_LOGIC; -- 1-clock Delayed version for edge detection
SIGNAL MsrRDn2_r : STD_LOGIC; -- 2-clock Delayed version for edge detection
SIGNAL IirRDn1_r : STD_LOGIC; -- 1-clock Delayed version for edge detection
SIGNAL IirRDn2_r : STD_LOGIC; -- 2-clock Delayed version for edge detection
SIGNAL RxRDY_Int : STD_LOGIC;
SIGNAL THRE_Int : STD_LOGIC;
SIGNAL DataErr_Int : STD_LOGIC;
SIGNAL Modem_Int : STD_LOGIC;
SIGNAL DataErr : STD_LOGIC;
SIGNAL ModemStat : STD_LOGIC;
-- 状态机定义
type state_typ IS (idle, int0, int1, int2, int3);
SIGNAL Int_State : state_typ;
-- UART 寄存器地址
constant A_RBR : STD_LOGIC_VECTOR(2 DOWNTO 0) := "000";
constant A_THR : STD_LOGIC_VECTOR(2 DOWNTO 0) := "000";
constant A_IER : STD_LOGIC_VECTOR(2 DOWNTO 0) := "001";
constant A_IIR : STD_LOGIC_VECTOR(2 DOWNTO 0) := "010";
constant A_LCR : STD_LOGIC_VECTOR(2 DOWNTO 0) := "011";
constant A_MCR : STD_LOGIC_VECTOR(2 DOWNTO 0) := "100";
constant A_LSR : STD_LOGIC_VECTOR(2 DOWNTO 0) := "101";
constant A_MSR : STD_LOGIC_VECTOR(2 DOWNTO 0) := "110";
ATTRIBUTE SYN_KEEP : integer;
ATTRIBUTE SYN_KEEP OF RbrRDn1_r : SIGNAL IS 1;
ATTRIBUTE OPT : string;
ATTRIBUTE OPT OF RbrRDn1_r : SIGNAL IS "KEEP";
begin
--------------------------------------------------------------------------------
--进行地址和片选锁存
--------------------------------------------------------------------------------
Addr_CS_Latch_Proc: PROCESS(Reset, Addr_Strob, ADDR,CS)
begin
IF (Reset='1') THEN
ADDR_s <= (others=>'0');
CS_R<='0';
ELSIF (Addr_Strob='0') THEN
ADDR_s <= ADDR;
CS_r <=CS;
END IF;
END PROCESS Addr_CS_Latch_Proc;
--------------------------------------------------------------------------------
-- 寄存器读写控制
--------------------------------------------------------------------------------
WRn_cs <= WRn WHEN (CS_r='1') else '1';
RDn_cs <= Up_read WHEN (CS_r='1') else '1';
-- 寄存器读写选通
Register_Rd_Wr_strobe:
PROCESS(Reset, Up_write, Up_read,CS)
begin
IF(Reset='1') THEN
ThrWRn_r <= '1';
RbrRDn_r <= '1';
LsrRDn_r <= '1';
MsrRDn_r <= '1';
IirRDn_r <= '1';
ELSIF(ADDR_s=A_THR) THEN
ThrWRn_r <= WRn_cs;
ELSIF(ADDR_s=A_RBR) THEN
RbrRDn_r <=RDn_cs;
ELSIF(ADDR_s=A_LSR) THEN
LsrRDn_r <=RDn_cs;
ELSIF(ADDR_s=A_MSR) THEN
MsrRDn_r <=RDn_cs;
ELSIF(ADDR_s=A_IIR) THEN
IirRDn_r <=RDn_cs;
ELSE
ThrWRn_r <= '1';
RbrRDn_r <= '1';
LsrRDn_r <= '1';
MsrRDn_r <= '1';
IirRDn_r <= '1';
END IF;
END PROCESS Register_Rd_Wr_strobe;
-- 延迟信号进行上升沿的检测
Delay_Signals_Proc: PROCESS(Clk16X, Reset)
begin
IF (Reset='1') THEN
ThrWRn1_r <= '1';
ThrWRn2_r <= '1';
RbrRDn1_r <= '1';
RbrRDn2_r <= '1';
LsrRDn1_r <= '1';
LsrRDn2_r <= '1';
MsrRDn1_r <= '1';
MsrRDn2_r <= '1';
IirRDn1_r <= '1';
IirRDn2_r <= '1';
ELSIF rising_edge(Clk16X) THEN
--检测ThrWRn_r的上升沿
ThrWRn1_r <= ThrWRn_r;
ThrWRn2_r <= ThrWRn1_r;
--检测RbrRDn_r的上升沿
RbrRDn1_r <= RbrRDn_r;
RbrRDn2_r <= RbrRDn1_r;
--检测LsrRDn_r的上升沿
LsrRDn1_r <= LsrRDn_r;
LsrRDn2_r <= LsrRDn1_r;
--检测MsrRDn_r的上升沿
MsrRDn1_r <= MsrRDn_r;
MsrRDn2_r <= MsrRDn1_r;
--检测IirRDn_r的上升沿
IirRDn1_r <= IirRDn_r;
IirRDn2_r <= IirRDn1_r;
END IF;
END PROCESS Delay_Signals_Proc;
-- Rising edge OF registers read/write strobes
ThrWRn_re <= ThrWRn1_r and (not ThrWRn2_r); -- rising edge OF ThrWRn_r
RbrRDn_re <= RbrRDn1_r and (not RbrRDn2_r); -- rising edge OF RbrRDn_r
LsrRDn_re <= LsrRDn1_r and (not LsrRDn2_r); -- rising edge OF LsrRDn_r
MsrRDn_re <= MsrRDn1_r and (not MsrRDn2_r); -- rising edge OF MsrRDn_r
IirRDn_re <= IirRDn1_r and (not IirRDn2_r); -- rising edge OF IirRDn_r
--------------------------------------------------------------------------------
-- 寄存器读写操作
--------------------------------------------------------------------------------
-- Register Read
Rd_Register_Proc:
PROCESS (Reset, RDn_cs, ADDR_s, RBR, IIR, LSR, MSR)
begin
IF (Reset='1') THEN
DATAOUT <= (others => '1');
ELSIF (RDn_cs ='0') THEN
IF(ADDR_s=A_RBR) THEN
DATAOUT <= RBR;
ELSIF(ADDR_s=A_IIR) THEN
DATAOUT <= "0000" & IIR;
ELSIF(ADDR_s=A_LSR) THEN
DATAOUT <= '0' & LSR;
ELSIF(ADDR_s=A_MSR) THEN
DATAOUT <= MSR;
ELSE
DATAOUT <= (others => '1');
END IF;
ELSE
DATAOUT <= (others => '1');
END IF;
END PROCESS Rd_Register_Proc;
-- Register Write
Wr_Register_Proc:
PROCESS (Reset, WRn_cs)
begin
IF (Reset='1') THEN
THR <= (Others=>'0');
IER <= (Others=>'0');
LCR <= (Others=>'0');
MCR <= (Others=>'0');
ELSIF rising_edge(WRn_cs) THEN
IF(ADDR_s=A_THR) THEN
THR <= DATAIN;
ELSIF(ADDR_s=A_IER) THEN
IER <= DATAIN(3 DOWNTO 0);
ELSIF(ADDR_s=A_LCR) THEN
LCR <= DATAIN(6 DOWNTO 0);
ELSIF(ADDR_s=A_MCR) THEN
MCR <= DATAIN(1 DOWNTO 0);
END IF;
END IF;
END PROCESS Wr_Register_Proc;
--------------------------------------------------------------------------------
-- 线性控制寄存器
--------------------------------------------------------------------------------
-- Databits : "00"=5-bit, "01"=6-bit, "10"=7-bit, "11"=8-bit
Databits <= LCR(1 DOWNTO 0);
-- Stopbits : "00"=1-bit, "01"=1.5-bit(5-bit data), "10"=2-bit(6,7,8-bit data)
Stopbits <= "00" WHEN (LCR(2)='0') else
"01" WHEN (LCR(2)='1') and (LCR(1 DOWNTO 0)="00") else
"10";
-- ParityEnable : '0'=Parity Bit Enable, '1'=Parity Bit Disable
ParityEnable <= LCR(3);
-- ParityEven : '0'=Even Parity Selected, '1'=Odd Parity Selected
ParityEven <= LCR(4);
-- ParityStick : '0'=Stick Parity Disable, '1'=Stick Parity Enable
ParityStick <= LCR(5);
-- TxBreak : '0'=Disable BREAK assertion, '1'=Assert BREAK
TxBreak <= LCR(6);
--------------------------------------------------------------------------------
-- 线性状态寄存器
--------------------------------------------------------------------------------
LSR <= TEMT & THRE & BreakInt & FrameErr & ParityErr & OverrunErr & RxRDY;
--------------------------------------------------------------------------------
-- Interrupt Arbitrator
--------------------------------------------------------------------------------
INTR <= RxRDy_Int OR THRE_Int OR DataErr_Int OR Modem_Int; ――中断输出
DataErr <= OverrunErr OR ParityErr OR FrameErr OR BreakInt;――接收数据错误标志位包括
――-Overrun,Parity,Framing and Break
ModemStat <= MSR(0) OR MSR(1) OR MSR(2) OR MSR(3);
――中断仲裁
Int_Arbit_Proc: PROCESS(Reset, Clk16X)
begin
IF (Reset='1') THEN
Int_State <= idle;
ELSIF rising_edge(Clk16X) THEN
CASE Int_State IS
WHEN idle =>
IF (IER(2)='1') and (DataErr='1') THEN
Int_State <= int0;
ELSIF (IER(0)='1') and (RxRDY='1') THEN
Int_State <= int1;
ELSIF (IER(1)='1') and (THRE='1') THEN
Int_State <= int2;
ELSIF (IER(3)='1') and (ModemStat='1') THEN
Int_State <= int3;
END IF;
WHEN int0 =>
IF (LsrRDn_re='1') THEN
Int_State <= idle;――当LSR的中断位访问后清空
END IF;
WHEN int1 =>
IF (RxRDY='0') THEN
Int_State <= idle;
END IF;
WHEN int2 =>
IF (IirRDn_re='1') OR (THRE='0') THEN
Int_State <= idle;
END IF;
WHEN int3 =>
IF (MsrRDn_re='1') THEN
Int_State <= idle;
END IF;
WHEN others =>
Int_State <= idle;
END CASE;
END IF;
END PROCESS Int_Arbit_Proc;
DataErr_Int <= '1' WHEN Int_State = int0 else '0'; -- 设置Receiver Line Status Interrupt
RxRDY_Int <= '1' WHEN Int_State = int1 else '0'; -- 设置Received Data Available Interrupt
THRE_Int <= '1' WHEN Int_State = int2 else '0'; -- 设置THR Empty Interrupt
Modem_Int <= '1' WHEN Int_State = int3 else '0'; -- 设置MODEM Status Interrupt
-- 更新IIR
IIR <= "0110" WHEN Int_State = int0 else -- 1st Priority Interrupt
"0100" WHEN Int_State = int1 else -- 2nd Priority Interrupt
"0010" WHEN Int_State = int2 else -- 3rd Priority Interrupt
"0000" WHEN Int_State = int3 else -- 4th Priority Interrupt
"0001"; -- No Interrupt Pending
-- Driver Disable goes low whenever the CPU IS reading data from the UART
DDIS <= RDn_cs;
END Intface_arch;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -