Introduction: Design of a Programmable Interrupt Controller in VHDL
I am overwhelmed by the kind of responses I get in this blog. Thanks guys for visiting my blog and motivating me to share my knowledge with you. This time, I am gonna present the design of another interesting module we see in all SOCs -- Interrupt Controller.
We will be designing a simple yet powerful Programmable Interrupt Controller. It is a completely configurable and parameterised design which is portable across platforms. I designed this after reading a lot on some popular interrupt controller architectures out there like NVIC, 8259a, RISC-V PLIC, Microblaze's INTC etc. Hope you guys find this blog helpful and helps you get a flavor on how interrupts are handled by a processor with the help of a Interrupt Controller.
Step 1: Specifications
Following are the specifications of the IP:
- AHB3-Lite interface.
- Statically configurable parameters:
- No. of external interrupt sources; supports up to 63 interrupts.
- No. of priority levels; supports up to 63 levels.
- No. of nesting levels; supports up to 8 level of nesting.
- Bus width; 32 or 64.
RISC-V PLIC specifications inspired interrupt handshaking mechanism is used in the design.
Interrupt pre-emption is inspired from 8259a
Step 2: Overview of PIC
Programmable Interrupt Controller (PIC) receives multiple interrupts from external peripherals and merges them into a single interrupt output to a target processor core.
PIC is controlled through control and status registers. All PIC registers are memory mapped, and accessed through AHB3-Lite bus interface.
The register bank consists of configuration register, enable registers, pending registers, in-service registers, priority registers and ID register, which are typical in Interrupt Controllers.
Configuration register is used to set the mode of operation of PIC. It can work in either Fully Nested Mode or Equal Priority Mode.
Each interrupt can be assigned priorities and individually masked. Global masking of all interrupts is also supported.
The register bank interact with Priority Resolver and BTC (Binary-Tree-Comparator) to resolve priorities of pending interrupts and assert interrupt to processor accordingly. ID register contains the ID of the highest priority pending interrupt.
Step 3: RTL Design and Implementation
PIC's design stress on reducing the latency of resolving priorities, which is the most time critical part of the design. Since the design resolves priorities in a single clock cycle, performance degrades with the increase in number of sources with a Log2 complexity.
The design was successfully implemented and timing verified up to following frequencies on Artix-7 FPGAs.
- Up to 15 sources : 100 MHz
- Up to 63 sources : 50 MHz
Interrupt Latency added by PIC alone is 3 clock cycles (Excluding the context switch time of Processor and the first ISR instruction fetch time).
Step 4: Important Notes and Attached Files
- If AHB3-Lite interface is undesired, you can change the top module and use the skeleton design of PIC. However the test bench provided is for IP with AHB3-Lite Interface.
- PIC IP v1.0 is a completely portable, bare RTL design.
- Functionally verified to work on both modes.
- Design codes and testbench in VHDL.
- Full IP Documentation.
It is an open-source design ... Feel free to use ...
For any queries, any time: