📄 intface.vhd
字号:
IirRDn_r <= '1' when (Reset='1') else RDn_cs when (ADDR_s=A_IIR) else '1';
-- Delayed signals for rising edge dectection
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
-- Signals for rising edge detection of THR write strobe signal ThrWRn_r
ThrWRn1_r <= ThrWRn_r;
ThrWRn2_r <= ThrWRn1_r;
-- Signals for rising edge detection of RBR read strobe signal RbrRDn_r
RbrRDn1_r <= RbrRDn_r;
RbrRDn2_r <= RbrRDn1_r;
-- Signals for rising edge detection of LSR read strobe signal LsrRDn_r
LsrRDn1_r <= LsrRDn_r;
LsrRDn2_r <= LsrRDn1_r;
-- Signals for rising edge detection of MSR read strobe signal MsrRDn_r
MsrRDn1_r <= MsrRDn_r;
MsrRDn2_r <= MsrRDn1_r;
-- Signals for rising edge detection of IIR read strobe signal 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
--------------------------------------------------------------------------------
-- Registers Read/Write Operation
--------------------------------------------------------------------------------
-- Register Read
Rd_Register_Proc:
process (Reset, RDn_cs, ADDR_s, RBR, IIR, LSR, MSR)
begin
if (Reset='1') then
DOUT <= (others => '1');
elsif (RDn_cs ='0') then
case ADDR_s is
when A_RBR =>
DOUT <= RBR;
when A_IIR =>
DOUT <= "0000" & IIR;
when A_LSR =>
DOUT <= '0' & LSR;
when A_MSR =>
DOUT <= MSR;
when others =>
DOUT <= (others => '1');
end case;
else
DOUT <= (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
case ADDR_s is
when A_THR =>
-- the Databits are aligned to the right (LSB)
THR <= DIN;
when A_IER =>
IER <= DIN(3 downto 0);
when A_LCR =>
LCR <= DIN(6 downto 0);
when A_MCR =>
MCR <= DIN(1 downto 0);
when others =>
end case;
end if;
end process Wr_Register_Proc;
--------------------------------------------------------------------------------
-- Line Control Register
--------------------------------------------------------------------------------
-- 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);
--------------------------------------------------------------------------------
-- Line Status Register
--------------------------------------------------------------------------------
LSR <= TEMT & THRE & BreakInt & FrameErr & ParityErr & OverrunErr & RxRDY;
--------------------------------------------------------------------------------
-- Interrupt Arbitrator
--------------------------------------------------------------------------------
-- Int is the common interrupt line for all internal UART events
INTR <= RxRDy_Int or THRE_Int or DataErr_Int or Modem_Int;
-- Receiving Data Error Flags including Overrun, Parity, Framing and Break
DataErr <= OverrunErr or ParityErr or FrameErr or BreakInt;
-- Whenever bit0,1,2,or3 is set to '1', a Modem Status Interrupt is generated
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
-- Clear Receiver Line Status Interrupt after LSR read
Int_State <= idle;
end if;
when int1 =>
if (RxRDY='0') then
-- Clear Received Data Available Interrupt after RBR read(RxRDY=0)
Int_State <= idle;
end if;
when int2 =>
if (IirRDn_re='1') or (THRE='0') then
-- Clear THR Empty Interrupt after IIR read or THR write(THRE=0)
Int_State <= idle;
end if;
when int3 =>
if (MsrRDn_re='1') then
-- Clear MODEM Status Interrupt after MSR read
Int_State <= idle;
end if;
when others =>
Int_State <= idle;
end case;
end if;
end process Int_Arbit_Proc;
-- Set Receiver Line Status Interrupt
DataErr_Int <= '1' when Int_State = int0 else '0';
-- Set Received Data Available Interrupt
RxRDY_Int <= '1' when Int_State = int1 else '0';
-- Set THR Empty Interrupt
THRE_Int <= '1' when Int_State = int2 else '0';
-- Set MODEM Status Interrupt
Modem_Int <= '1' when Int_State = int3 else '0';
-- Update 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_a;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -