litex/migen/bank/eventmanager.py

65 lines
1.9 KiB
Python
Raw Normal View History

2012-02-06 11:39:32 -05:00
from migen.fhdl.structure import *
from migen.fhdl.module import Module
2012-02-06 11:39:32 -05:00
from migen.bank.description import *
2013-02-22 17:19:37 -05:00
from migen.genlib.misc import optree
2012-02-06 11:39:32 -05:00
class _EventSource(HUID):
2012-02-06 11:39:32 -05:00
def __init__(self):
HUID.__init__(self)
2012-02-06 11:39:32 -05:00
self.trigger = Signal()
2012-05-21 13:56:23 -04:00
self.pending = Signal()
2012-02-06 11:39:32 -05:00
class EventSourcePulse(_EventSource):
2012-02-06 11:39:32 -05:00
pass
class EventSourceLevel(_EventSource):
2012-02-06 11:39:32 -05:00
pass
class EventManager(Module, AutoReg):
def __init__(self):
2012-02-06 11:39:32 -05:00
self.irq = Signal()
def do_finalize(self):
sources_u = [v for v in self.__dict__.values() if isinstance(v, _EventSource)]
sources = sorted(sources_u, key=lambda x: x.huid)
n = len(sources)
2013-03-12 10:45:24 -04:00
self.status = RegisterRaw(n)
self.pending = RegisterRaw(n)
self.enable = RegisterFields(*(Field(1, READ_WRITE, READ_ONLY, name="e" + str(i)) for i in range(n)))
2012-02-06 11:39:32 -05:00
# status
for i, source in enumerate(sources):
2012-02-06 11:39:32 -05:00
if isinstance(source, EventSourcePulse):
self.comb += self.status.w[i].eq(0)
2012-02-06 11:39:32 -05:00
elif isinstance(source, EventSourceLevel):
self.comb += self.status.w[i].eq(source.trigger)
2012-02-06 11:39:32 -05:00
else:
raise TypeError
# pending
for i, source in enumerate(sources):
2012-02-06 11:39:32 -05:00
# W1C
self.sync += If(self.pending.re & self.pending.r[i], source.pending.eq(0))
2012-02-06 11:39:32 -05:00
if isinstance(source, EventSourcePulse):
# set on a positive trigger pulse
self.sync += If(source.trigger, source.pending.eq(1))
2012-02-06 11:39:32 -05:00
elif isinstance(source, EventSourceLevel):
# set on the falling edge of the trigger
old_trigger = Signal()
self.sync += [
2012-02-06 11:39:32 -05:00
old_trigger.eq(source.trigger),
2012-05-21 13:56:23 -04:00
If(~source.trigger & old_trigger, source.pending.eq(1))
2012-02-06 11:39:32 -05:00
]
else:
raise TypeError
self.comb += self.pending.w[i].eq(source.pending)
2012-02-06 11:39:32 -05:00
# IRQ
irqs = [self.pending.w[i] & field.r for i, field in enumerate(self.enable.fields)]
self.comb += self.irq.eq(optree("|", irqs))
def __setattr__(self, name, value):
if isinstance(value, _EventSource) and self.finalized:
raise FinalizeError
object.__setattr__(self, name, value)