Source code for luna_soc.gateware.cpu.ic

#
# This file is part of LUNA.
#
# Copyright (c) 2020-2025 Great Scott Gadgets <info@greatscottgadgets.com>
# SPDX-License-Identifier: BSD-3-Clause

""" The simplest interrupt controller. """

from amaranth              import *
from amaranth.lib          import wiring
from amaranth.lib.wiring   import In, Out

# type aliases only in py 3.12 :-(
# type InterruptMap = dict[int, (str, wiring.Component)]
InterruptMap = dict[int, (str, wiring.Component)]

[docs] class InterruptController(wiring.Component): def __init__(self, *, width): super().__init__({ "pending": Out(unsigned(width)), }) self._interrupts: InterruptMap = dict()
[docs] def interrupts(self) -> InterruptMap: return self._interrupts
[docs] def add(self, peripheral, *, name, number=None): if number is None: raise ValueError("You need to supply a value for the IRQ number.") if number in self._interrupts.keys(): raise ValueError(f"IRQ number '{number}' has already been used.") if name in dict(self._interrupts.values()).keys(): raise ValueError(f"Peripheral name '{name}' has already been used.") if peripheral in dict(self._interrupts.values()).values(): raise ValueError(f"Peripheral '{name}' has already been added: {peripheral}") self._interrupts[number] = (name, peripheral)
[docs] def elaborate(self, platform): m = Module() for number, (name, peripheral) in self._interrupts.items(): m.d.comb += self.pending[number].eq(peripheral.irq) return m