---------------------------------------------------------------------------------- -- Company: University of Connecticut -- Engineer: Igor Senderovich -- -- Create Date: 22:52:57 11/29/2007 -- Design Name: -- Module Name: INTCatcher - behavioral -- Description: Loops over interrupts from the ethernet controller and returns -- when an interrupt occurs which matches the specified Mask and -- returns Done. Mask (in order from MSB to LSB) picks out: -- 15- INT1(7) Unused -- 14- INT1(6) Unused -- 13- INT1(5) Wake-on-LAN -- 12- INT1(4) Link Status Changed -- 11- INT1(3) Jabber Detected -- 10- INT1(2) AutoNegotiation Failed -- 9- INT1(1) Reserved -- 8- INT1(0) AutoNegotiation Complete -- 7- INT0(7) End Of Packet, packet readout complete -- 6- INT0(6) Receive FIFO empty, no more packets to read -- 5- INT0(5) Self Initiatization Complete -- 4- INT0(4) Oscillator Initialization Complete -- 3- INT0(3) Flash Read/Erase Operation Complete -- 2- INT0(2) Packet Transmitted -- 1- INT0(1) Receive FIFO Full, new packets to be dropped -- 0- INT0(0) Packet Received ---------------------------------------------------------------------------------- library IEEE; use IEEE.std_logic_1164.all; use IEEE.std_logic_arith.all; use IEEE.std_logic_unsigned.all; library FPGA_BasicComp; use FPGA_BasicComp.BasicComp.all; entity INTCatcher is Port ( Clk : in std_logic; INT_low: in std_logic; Go : in std_logic; Mask : in std_logic_vector(15 downto 0); Found : out std_logic_vector(15 downto 0); Done : out std_logic; TxRx_Go : out std_logic; TxRx_A_tri : out std_logic_vector (7 downto 0); TxRx_Rd_tri : out std_logic; TxRx_D_tri : out std_logic_vector (7 downto 0); TxRx_Q : in std_logic_vector (7 downto 0); TxRx_Done : in std_logic); --Ser_Go : out std_logic; --Ser_Done : in std_logic; --Ser_D_tri : out std_logic_vector (7 downto 0)); --Debug : out std_logic); end INTCatcher; architecture behavioral of INTCatcher is type stage_t is (S0,S1,S2,S3,S4,S5,S6,S7,S8); --,SS); signal stage : stage_t := S0; signal Done_reg : std_logic := '0'; signal Found_reg : std_logic_vector (15 downto 0) := (others => '0'); signal Pending_rec : std_logic_vector (7 downto 0) := (others => '0'); signal TxRx_Go_reg : std_logic := '0'; signal TxRx_A_reg : std_logic_vector (7 downto 0) := (others => '0'); signal TxRx_Rd_reg : std_logic := '0'; signal TxRx_D_reg : std_logic_vector (7 downto 0) := (others => '0'); --signal Ser_Go_reg : std_logic := '0'; --signal Ser_D_reg : std_logic_vector (7 downto 0) := (others => '0'); begin Found <= Found_reg; TxRx_Go <= TxRx_Go_reg; TxRx_A_tri <= TxRx_A_reg when (TxRx_Go_reg = '1') else (others => 'Z'); TxRx_D_tri <= TxRx_D_reg when (TxRx_Go_reg = '1') else (others => 'Z'); TxRx_Rd_tri <= TxRx_Rd_reg when (TxRx_Go_reg = '1') else 'Z'; Wait4Interrupt : process (Clk) variable op_complete_var : std_logic; constant Stage_Ok : std_logic_vector (7 downto 0) := X"80"; begin if rising_edge(Clk) then stage <= stage; Done_reg <= '0'; Found_reg <= Found_reg; Pending_rec <= Pending_rec; -- disable the MuxIntel bus when not in use TxRx_Go_reg <= '0'; TxRx_Rd_reg <= '1'; TxRx_A_reg <= (others => '0'); TxRx_D_reg <= (others => '0'); -- disable the serial port when not in use --Ser_Go_reg <= '0'; --Ser_D_reg <= (others => '0'); --Debug_reg <= '0'; op_complete_var := TxRx_Go_reg and TxRx_Done; case stage is when S0 => if (Go = '1') then stage <= S1; end if; ---------------------------------------------------------------- -- Check if one of the enabled interrupts has occurred already ---------------------------------------------------------------- when S1 => if (Mask(0) = '1' and Pending_rec(7) = '1') then Pending_rec <= Pending_rec + 1; Found_reg(0) <= '1'; stage <= S8; else stage <= S2; end if; ---------------------------------------------------------- -- Nothing so far, set the interrupt enable bits and wait ---------------------------------------------------------- when S2 => TxRx_A_reg <= X"64"; TxRx_Rd_reg <= '0'; TxRx_D_reg <= Mask(7 downto 0); TxRx_Go_reg <= not TxRx_Done; if (op_complete_var = '1') then stage <= S3; end if; when S3 => TxRx_A_reg <= X"7D"; TxRx_Rd_reg <= '0'; TxRx_D_reg <= Mask(15 downto 8); TxRx_Go_reg <= not TxRx_Done; if (op_complete_var = '1') then stage <= S4; end if; when S4 => if (INT_low = '0') then stage <= S5; end if; ---------------------------------------------------------- -- Interrupt detected, read and clear the INT0/INT1 regs ---------------------------------------------------------- when S5 => TxRx_A_reg <= X"63"; TxRx_Rd_reg <= '1'; TxRx_Go_reg <= not TxRx_Done; Found_reg(7 downto 0) <= TxRx_Q; if (op_complete_var = '1') then stage <= S6; end if; when S6 => TxRx_A_reg <= X"7F"; TxRx_Rd_reg <= '1'; TxRx_Go_reg <= not TxRx_Done; Found_reg(15 downto 8) <= TxRx_Q; if (op_complete_var = '1') then stage <= S7; end if; when S7 => if (Found_reg(0) = '1' and Mask(0) = '0') then Pending_rec <= Pending_rec - 1; Found_reg(0) <= '0'; end if; stage <= S8; ----------------------------------------------- -- Send a serial port message and you are done ----------------------------------------------- -- when SS => -- Ser_D_reg <= X"49"; -- Ser_Go_reg <= not Ser_Done; -- op_complete_var := Ser_Go_reg and Ser_Done; -- if (op_complete_var = '1') then -- stage <= S9; -- end if; when S8 => if (Go = '1') then Done_reg <= '1'; else stage <= S0; end if; end case; else stage <= stage; Done_reg <= Done_reg; Found_reg <= Found_reg; Pending_rec <= Pending_rec; TxRx_Go_reg <= TxRx_Go_reg; TxRx_Rd_reg <= TxRx_Rd_reg; TxRx_A_reg <= TxRx_A_reg; TxRx_D_reg <= TxRx_D_reg; --Ser_Go_reg <= Ser_Go_reg; --Ser_D_reg <= Ser_D_reg; --Debug_reg <= Debug_reg; end if; end process; --Ser_Go <= Ser_Go_reg; --Ser_D_tri <= Ser_D_reg when (Ser_Go_reg = '1') else (others => 'Z'); --Debug_reg <= Debug_reg; Done <= Done_reg; end behavioral;