⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 intface.vhd

📁 VHDL的例子
💻 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 + -