vhdl interrupt
Hi
This code is not tested nor simulated. Check the syntax and simulate it.
It could be a starting point for your work.
entity Interrupt_controller is
port
(
CLK_IN : in std_logic; -- Clock input
CS_IN : in std_logic; -- External Chip Select input
IN_0 : in std_logic; -- First Irq source input
IN_1 : in std_logic; -- Second Irq source input
IN_2 : in std_logic; -- Third Irq source input
RD_IN : in std_logic; -- External Read input
RST_IN : in std_logic; -- External Reset input
DATA_OUT : out std_logic_vector (2 downto 0); -- External data bus output
IRQ_PIN : out std_logic; -- Irq output (connected to µP's IRQ input)
);
-- The clock (CLK_IN) period should be at least 4 times lower (or 4 times higher in frequency) than the µP's read cycle.
-- The Irq output (IRQ_PIN) is active low on a state change on any of the three inputs (IN_0, IN_1, IN_2).
-- Reading the status clears (set to 1) the Irq output (IRQ_PIN).
-- Reading the status give the state of the three inputs. Software must check witch input changes state.
-- Warning : IN_0 through IN_2 are not debounced. The do not change state between IRQ pin low and µP's read
begin
end Interrupt_controller;
architechture Arch1 of Interrupt_controller is
signal COMPAR_OUT : std_logic;
signal FIRST_LATCH_OUT : std_logic_vector (2 downto 0);
signal IRQ_OUT : std_logic;
signal READ_EN : std logic;
signal SECOND_LATCH_OUT : std_logic_vector (2 downto 0);
begin
-- Read enable. Active low when CS_IN = 0 and RD_IN = 0
READ_EN <= CS_IN or RD_IN;
-- First level latch of input data
First_latch : process(CLK_IN, RST_IN)
begin
if RST_IN = '1' then
FIRST_LATCH_OUT <= (others => '0');
elsif CLK_IN'event and CLK_IN ='1' then
FIRST_LATCH_OUT(0) <= IN_0;
FIRST_LATCH_OUT(1) <= IN_1;
FIRST_LATCH_OUT(2) <= IN_2;
end if;
end process First_latch;
-- Second level latch
Second_latch : process(CLK_IN, FIRST_LATCH_OUT, READ_EN, RST_IN)
begin
if RST_IN = '1' then
SECOND_LATCH_OUT <= (others => '0');
elsif CLK_IN'event and CLK_IN ='0' then
if READ_EN = '0' then
SECOND_LATCH_OUT <= FIRST_LATCH_OUT;
end if;
end if;
end process Second_latch;
-- Magnitude comparator between first and second latch datas.
Compar : process(FIRST_LATCH_OUT, SECOND_LATCH_OUT)
begin
if FIRST_LATCH_OUT = SECOND_LATCH_OUT then
COMPAR_OUT <= '0';
else
COMPAR_OUT <= '1';
end if;
end process Compar;
-- Internal interrupt signal. Active high, is reseted through RST_IN or µP's read (CS_IN = 0 and RD_IN = 0)
Irq : process(CLK_IN, COMPAR_OUT, READ_EN, RST_IN)
begin
if RST_IN = '1' or READ_EN = '0' then
IRQ_OUT <= '0';
elsif CLK_IN'event and CLK_IN = '0' then
IRQ_OUT <= IRQ_OUT or COMPAR_OUT;
end if;
end process Irq;
-- Output interrupt signal on interrupt pin, active low. If you want it active high, remove 'not'.
IRQ_PIN <= not(IRQ_OUT);
-- Output first latch datas on external bus with tristate. IN_0 through IN_2 must not change state during read
Data_tristate : process(FIRST_LATCH_OUT, READ_EN)
begin
if READ_EN = '0' then
DATA_OUT <= FIRST_LATCH_OUT;
else
DATA_OUT <= (others => 'Z');
end if;
end process Data_tristate;
end Arch_1;