VHDL Code for Interrupt Controller: Syntax and Example
A basic
interrupt controller in VHDL monitors interrupt request signals and generates an interrupt acknowledge signal. It typically uses input signals for interrupts and outputs a signal to the processor when an interrupt is active. The controller can be implemented using a process that checks interrupt lines and sets flags accordingly.Syntax
The interrupt controller in VHDL usually includes input signals for interrupt requests, an output for interrupt acknowledge, and internal logic to prioritize and handle interrupts.
Key parts:
entity: Defines inputs and outputs likeirq(interrupt requests) andint_ack(interrupt acknowledge).architecture: Contains the logic to detect interrupts and generate acknowledge signals.process: Monitors interrupt lines and sets output signals.
vhdl
entity InterruptController is
Port (
clk : in std_logic;
reset : in std_logic;
irq : in std_logic_vector(3 downto 0); -- 4 interrupt lines
int_ack : out std_logic;
int_num : out std_logic_vector(1 downto 0) -- interrupt number
);
end InterruptController;
architecture Behavioral of InterruptController is
begin
process(clk, reset)
begin
if reset = '1' then
int_ack <= '0';
int_num <= "00";
elsif rising_edge(clk) then
int_ack <= '0';
int_num <= "00";
if irq(0) = '1' then
int_ack <= '1';
int_num <= "00";
elsif irq(1) = '1' then
int_ack <= '1';
int_num <= "01";
elsif irq(2) = '1' then
int_ack <= '1';
int_num <= "10";
elsif irq(3) = '1' then
int_ack <= '1';
int_num <= "11";
end if;
end if;
end process;
end Behavioral;Example
This example shows a simple interrupt controller with 4 interrupt lines. It checks each interrupt in priority order and outputs an acknowledge signal and the interrupt number.
The int_ack signal goes high when any interrupt is active, and int_num indicates which interrupt is active.
vhdl
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity InterruptController is
Port (
clk : in std_logic;
reset : in std_logic;
irq : in std_logic_vector(3 downto 0);
int_ack : out std_logic;
int_num : out std_logic_vector(1 downto 0)
);
end InterruptController;
architecture Behavioral of InterruptController is
begin
process(clk, reset)
begin
if reset = '1' then
int_ack <= '0';
int_num <= "00";
elsif rising_edge(clk) then
int_ack <= '0';
int_num <= "00";
if irq(0) = '1' then
int_ack <= '1';
int_num <= "00";
elsif irq(1) = '1' then
int_ack <= '1';
int_num <= "01";
elsif irq(2) = '1' then
int_ack <= '1';
int_num <= "10";
elsif irq(3) = '1' then
int_ack <= '1';
int_num <= "11";
end if;
end if;
end process;
end Behavioral;Output
When irq(0) = '1', int_ack = '1' and int_num = "00"; for irq(1) = '1', int_ack = '1' and int_num = "01"; similarly for irq(2) and irq(3). If no irq is active, int_ack = '0' and int_num = "00".
Common Pitfalls
Common mistakes when writing an interrupt controller in VHDL include:
- Not resetting output signals properly, causing stale interrupt acknowledges.
- Checking interrupts without priority, which can cause multiple interrupts to be acknowledged simultaneously.
- Forgetting to use
rising_edge(clk)for synchronous logic, leading to glitches. - Not handling the reset condition correctly, which can cause undefined outputs.
vhdl
Wrong approach (no priority, no reset):
process(clk)
begin
if rising_edge(clk) then
if irq(0) = '1' then
int_ack <= '1';
int_num <= "00";
end if;
if irq(1) = '1' then
int_ack <= '1';
int_num <= "01";
end if;
end if;
end process;
Right approach (priority and reset):
process(clk, reset)
begin
if reset = '1' then
int_ack <= '0';
int_num <= "00";
elsif rising_edge(clk) then
int_ack <= '0';
int_num <= "00";
if irq(0) = '1' then
int_ack <= '1';
int_num <= "00";
elsif irq(1) = '1' then
int_ack <= '1';
int_num <= "01";
end if;
end if;
end process;Quick Reference
Interrupt Controller Tips:
- Use a synchronous process with
rising_edge(clk)and asynchronous reset. - Check interrupts in priority order using
elsifto avoid multiple acknowledges. - Reset outputs to known states to avoid glitches.
- Use
std_logic_vectorfor multiple interrupt lines and output interrupt number.
Key Takeaways
Use a synchronous process with reset to handle interrupts cleanly.
Check interrupt lines in priority order using elsif to avoid multiple active interrupts.
Reset output signals to known states to prevent glitches.
Output both interrupt acknowledge and interrupt number for processor handling.
Test your interrupt controller with different interrupt inputs to verify behavior.