Make it harder to have conflicting interrupts.
This commit is contained in:
parent
ff72757b87
commit
295e78ee9e
|
@ -35,7 +35,8 @@ class SoCCore(Module):
|
||||||
"buttons": 5, # user
|
"buttons": 5, # user
|
||||||
"leds": 6, # user
|
"leds": 6, # user
|
||||||
}
|
}
|
||||||
interrupt_map = {
|
interrupt_map = {}
|
||||||
|
soc_interrupt_map = {
|
||||||
"nmi": 0, # Reserve zero for "non-maskable interrupt"
|
"nmi": 0, # Reserve zero for "non-maskable interrupt"
|
||||||
"timer0": 1, # LiteX Timer
|
"timer0": 1, # LiteX Timer
|
||||||
"uart": 2, # LiteX UART (IRQ 2 for UART matches mor1k standard config).
|
"uart": 2, # LiteX UART (IRQ 2 for UART matches mor1k standard config).
|
||||||
|
@ -124,6 +125,8 @@ class SoCCore(Module):
|
||||||
else:
|
else:
|
||||||
self.submodules.uart_phy = uart.RS232PHY(platform.request("serial"), clk_freq, uart_baudrate)
|
self.submodules.uart_phy = uart.RS232PHY(platform.request("serial"), clk_freq, uart_baudrate)
|
||||||
self.submodules.uart = uart.UART(self.uart_phy)
|
self.submodules.uart = uart.UART(self.uart_phy)
|
||||||
|
else:
|
||||||
|
del self.soc_interrupt_map["uart"]
|
||||||
|
|
||||||
if ident:
|
if ident:
|
||||||
if ident_version:
|
if ident_version:
|
||||||
|
@ -134,6 +137,33 @@ class SoCCore(Module):
|
||||||
|
|
||||||
if with_timer:
|
if with_timer:
|
||||||
self.submodules.timer0 = timer.Timer()
|
self.submodules.timer0 = timer.Timer()
|
||||||
|
else:
|
||||||
|
del self.soc_interrupt_map["timer0"]
|
||||||
|
|
||||||
|
# Invert the interrupt map.
|
||||||
|
interrupt_rmap = {}
|
||||||
|
for mod_name, interrupt in self.interrupt_map.items():
|
||||||
|
assert interrupt not in interrupt_rmap, (
|
||||||
|
"Interrupt vector conflict for IRQ %s, user defined %s conflicts with user defined %s" % (
|
||||||
|
interrupt, mod_name, interrupt_rmap[interrupt]))
|
||||||
|
|
||||||
|
interrupt_rmap[interrupt] = mod_name
|
||||||
|
|
||||||
|
# Add the base SoC's interrupt map
|
||||||
|
for mod_name, interrupt in self.soc_interrupt_map.items():
|
||||||
|
assert interrupt not in interrupt_rmap, (
|
||||||
|
"Interrupt vector conflict for IRQ %s, user defined %s conflicts with SoC inbuilt %s" % (
|
||||||
|
interrupt, mod_name, interrupt_rmap[interrupt]))
|
||||||
|
|
||||||
|
self.interrupt_map[mod_name] = interrupt
|
||||||
|
interrupt_rmap[interrupt] = mod_name
|
||||||
|
|
||||||
|
# Make sure other functions are not using this value.
|
||||||
|
self.soc_interrupt_map = None
|
||||||
|
|
||||||
|
# Save the interrupt reverse map
|
||||||
|
self.interrupt_rmap = interrupt_rmap
|
||||||
|
|
||||||
|
|
||||||
def add_cpu_or_bridge(self, cpu_or_bridge):
|
def add_cpu_or_bridge(self, cpu_or_bridge):
|
||||||
if self.finalized:
|
if self.finalized:
|
||||||
|
@ -193,7 +223,7 @@ class SoCCore(Module):
|
||||||
|
|
||||||
def get_constants(self):
|
def get_constants(self):
|
||||||
r = []
|
r = []
|
||||||
for name, interrupt in sorted(self.interrupt_map.items(), key=itemgetter(1)):
|
for interrupt, name in sorted(self.interrupt_rmap.items()):
|
||||||
r.append((name.upper() + "_INTERRUPT", interrupt))
|
r.append((name.upper() + "_INTERRUPT", interrupt))
|
||||||
r += self._constants
|
r += self._constants
|
||||||
return r
|
return r
|
||||||
|
@ -235,9 +265,13 @@ class SoCCore(Module):
|
||||||
|
|
||||||
# Interrupts
|
# Interrupts
|
||||||
if hasattr(self.cpu_or_bridge, "interrupt"):
|
if hasattr(self.cpu_or_bridge, "interrupt"):
|
||||||
for k, v in sorted(self.interrupt_map.items(), key=itemgetter(1)):
|
for interrupt, mod_name in sorted(self.interrupt_rmap.items()):
|
||||||
if hasattr(self, k):
|
if mod_name == "nmi":
|
||||||
self.comb += self.cpu_or_bridge.interrupt[v].eq(getattr(self, k).ev.irq)
|
continue
|
||||||
|
assert hasattr(self, mod_name), "Missing module for interrupt %s" % mod_name
|
||||||
|
mod_impl = getattr(self, mod_name)
|
||||||
|
assert hasattr(mod_impl, 'ev'), "Submodule %s does not have EventManager (xx.ev) module" % mod_name
|
||||||
|
self.comb += self.cpu_or_bridge.interrupt[interrupt].eq(mod_impl.ev.irq)
|
||||||
|
|
||||||
def build(self, *args, **kwargs):
|
def build(self, *args, **kwargs):
|
||||||
return self.platform.build(self, *args, **kwargs)
|
return self.platform.build(self, *args, **kwargs)
|
||||||
|
|
Loading…
Reference in New Issue