📄 opb_interproc_int_if.vhd
字号:
library ieee;use ieee.std_logic_1164.all;use ieee.std_logic_arith.all;use ieee.std_logic_unsigned.all;library Unisim;use Unisim.all;library Common_v1_00_a;use Common_v1_00_a.all;use Common_v1_00_a.Common_Types.all;use Common_v1_00_a.pselect;-- OPB Inter Processor Interrupt Hardware Interfaceentity OPB_INTERPROC_INT_IF is generic ( C_OPB_AWIDTH : integer := 32; C_OPB_DWIDTH : integer := 32; C_BASEADDR : std_logic_vector(0 to 31) := X"0000_0000"; C_HIGHADDR : std_logic_vector(0 to 31) := X"FFFF_FFFF"); port ( -- OPB interface Side OPB_Clk : in std_logic; OPB_Rst : in std_logic; OPB_ABus : in std_logic_vector(0 to C_OPB_AWIDTH - 1); OPB_BE : in std_logic_vector(0 to C_OPB_DWIDTH/8 - 1); OPB_DBus : in std_logic_vector(0 to C_OPB_DWIDTH - 1); OPB_RNW : in std_logic; OPB_select : in std_logic; OPB_seqAddr : in std_logic; InterProcIntIf_DBus : out std_logic_vector(0 to C_OPB_DWIDTH - 1); InterProcIntIf_errAck : out std_logic; InterProcIntIf_retry : out std_logic; InterProcIntIf_toutSup : out std_logic; InterProcIntIf_xferAck : out std_logic; Interrupt : out std_logic; RCV_IntReq0 : in std_logic; SND_IntReq0 : out std_logic; RCV_IntReq1 : in std_logic; SND_IntReq1 : out std_logic; RCV_IntReq2 : in std_logic; SND_IntReq2 : out std_logic; RCV_IntReq3 : in std_logic; SND_IntReq3 : out std_logic);end OPB_INTERPROC_INT_IF;architecture Behavior of OPB_INTERPROC_INT_IF is component pselect generic ( C_AB : integer; C_AW : integer; C_BAR : std_logic_vector); port ( A : in std_logic_vector(0 to C_AW - 1); AValid : in std_logic; PS : out std_logic); end component; function GET_AWIDTH ( BASEADDR, HIGHADDR : std_logic_vector(0 to C_OPB_AWIDTH - 1)) return integer is variable tmp_awidth : std_logic_vector(0 to C_OPB_AWIDTH - 1); begin -- GET_AWIDTH tmp_awidth := BASEADDR xor HIGHADDR; for I in 0 to C_OPB_AWIDTH - 1 loop if (tmp_awidth(I) = '1') then return (I); end if; end loop; -- I return C_OPB_AWIDTH - 1; end GET_AWIDTH; constant C_AB : integer := GET_AWIDTH( C_BASEADDR, C_HIGHADDR ); constant SET_REG_ADDR : std_logic_vector(0 to 1) := "00"; constant CLEAR_REG_ADDR : std_logic_vector(0 to 1) := "01"; constant STATUS_REG_ADDR : std_logic_vector(0 to 1) := "10"; signal s_select : std_logic; signal xferack : std_logic; signal s_xferack : std_logic; signal d_xferack : std_logic; signal snd_intreq : std_logic; signal s_snd_intreq : std_logic; signal d_snd_intreq : std_logic; signal clr_int : std_logic; signal s_clr_int : std_logic; signal d_clr_int : std_logic; signal rcv_intreq : std_logic; signal s_rcv_intreq : std_logic;begin -- Behavior pselect_I : pselect generic map ( C_AB => C_AB, C_AW => C_OPB_AWIDTH, C_BAR => C_BASEADDR) port map ( A => OPB_ABus, AValid => OPB_select, PS => s_select); -- Interrupt Request s_rcv_intreq <= RCV_IntReq3 or RCV_IntReq2 or RCV_IntReq1 or RCV_IntReq0; process (OPB_Clk, OPB_Rst, s_clr_int) begin -- process if OPB_Rst = '1' then rcv_intreq <= '0'; elsif OPB_Clk'event and OPB_Clk = '1' then if s_clr_int = '1' then rcv_intreq <= '0'; else if (s_rcv_intreq = '1') then rcv_intreq <= '1'; else rcv_intreq <= rcv_intreq; end if; end if; end if; end process; Interrupt <= rcv_intreq; -- process (OPB_Clk, OPB_Rst) begin -- process if OPB_Rst = '1' then -- asynchronous reset (active low) snd_intreq <= '0'; clr_int <= '0'; xferack <= '0'; elsif OPB_Clk'event and OPB_Clk = '1' then -- rising clock edge if s_select = '1' then case OPB_ABus(28 to 29) is when SET_REG_ADDR => snd_intreq <= OPB_DBus(0) and s_select; clr_int <= '0'; xferack <= s_select; when CLEAR_REG_ADDR => snd_intreq <= '0'; clr_int <= OPB_DBus(0) and s_select; xferack <= s_select; when STATUS_REG_ADDR => snd_intreq <= '0'; clr_int <= '0'; xferack <= s_select; when others => snd_intreq <= '0'; clr_int <= '0'; xferack <= s_select; end case; else snd_intreq <= '0'; clr_int <= '0'; xferack <= '0'; end if; end if; end process; process (OPB_Clk, OPB_Rst) begin -- process if OPB_Rst = '1' then -- asynchronous reset (active low) s_snd_intreq <= '0'; d_snd_intreq <= '0'; elsif OPB_Clk'event and OPB_Clk = '1' then -- rising clock edge s_snd_intreq <= snd_intreq and not d_snd_intreq; d_snd_intreq <= snd_intreq; end if; end process; SND_IntReq3 <= s_snd_intreq and OPB_DBus(28); SND_IntReq2 <= s_snd_intreq and OPB_DBus(29); SND_IntReq1 <= s_snd_intreq and OPB_DBus(30); SND_IntReq0 <= s_snd_intreq and OPB_DBus(31); -- Gen s_clk_int process (OPB_Clk, OPB_Rst) begin -- process if OPB_Rst = '1' then -- asynchronous reset (active low) s_clr_int <= '0'; d_clr_int <= '0'; elsif OPB_Clk'event and OPB_Clk = '1' then -- rising clock edge s_clr_int <= clr_int and not d_clr_int; d_clr_int <= clr_int; end if; end process; -- Gen xfer_ack process (OPB_Clk, OPB_Rst) begin -- process if OPB_Rst = '1' then -- asynchronous reset (active low) s_xferack <= '0'; d_xferack <= '0'; elsif OPB_Clk'event and OPB_Clk = '1' then -- rising clock edge s_xferack <= xferack and not d_xferack; d_xferack <= xferack; end if; end process; InterProcIntIf_xferAck <= s_xferack; InterProcIntIf_toutSup <= '0'; InterProcIntIf_retry <= '0'; InterProcIntIf_errAck <= '0'; InterProcIntIf_DBus(0 to C_OPB_DWIDTH - 6) <= (others => '0'); InterProcIntIf_DBus(C_OPB_DWIDTH - 5 to C_OPB_DWIDTH - 1) <= RCV_IntReq3 & RCV_IntReq2 & RCV_IntReq1 & RCV_IntReq0 & rcv_intreq when (s_select = '1') else (others => '0');end Behavior;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -