bank/eventmanager: refactor, rename EventSourceLevel -> EventSourceProcess, add fully...
authorSebastien Bourdeauducq <sebastien@milkymist.org>
Wed, 8 May 2013 16:12:26 +0000 (18:12 +0200)
committerSebastien Bourdeauducq <sebastien@milkymist.org>
Wed, 8 May 2013 16:12:26 +0000 (18:12 +0200)
migen/bank/eventmanager.py

index b8981e59d1bc5877f4d8ed80100ef6fb0fe40aa8..85e4476bf40827d27124ae6cbc3a68521a656185 100644 (file)
@@ -6,14 +6,41 @@ from migen.genlib.misc import optree
 class _EventSource(HUID):
        def __init__(self):
                HUID.__init__(self)
-               self.trigger = Signal()
-               self.pending = Signal()
+               self.status = Signal() # value in the status register
+               self.pending = Signal() # value in the pending register + assert irq if unmasked
+               self.trigger = Signal() # trigger signal interface to the user design
+               self.clear = Signal() # clearing attempt by W1C to pending register, ignored by some event sources
 
-class EventSourcePulse(_EventSource):
-       pass
+# set on a positive trigger pulse
+class EventSourcePulse(Module, _EventSource):
+       def __init__(self):
+               _EventSource.__init__(self)
+               self.comb += self.status.eq(0)
+               self.sync += [
+                       If(self.clear, self.pending.eq(0)),
+                       If(self.trigger, self.pending.eq(1))
+               ]
+
+# set on the falling edge of the trigger, status = trigger
+class EventSourceProcess(Module, _EventSource):
+       def __init__(self):
+               _EventSource.__init__(self)
+               self.comb += self.status.eq(self.trigger)
+               old_trigger = Signal()
+               self.sync += [
+                       If(self.clear, self.pending.eq(0)),
+                       old_trigger.eq(self.trigger),
+                       If(~self.trigger & old_trigger, self.pending.eq(1))
+               ]
 
-class EventSourceLevel(_EventSource):
-       pass
+# all status set by external trigger
+class EventSourceLevel(Module, _EventSource):
+       def __init__(self):
+               _EventSource.__init__(self)
+               self.comb += [
+                       self.status.eq(self.trigger),
+                       self.pending.eq(self.trigger)
+               ]
 
 class EventManager(Module, AutoCSR):
        def __init__(self):
@@ -27,38 +54,19 @@ class EventManager(Module, AutoCSR):
                self.pending = CSR(n)
                self.enable = CSRStorage(n)
 
-               # status
-               for i, source in enumerate(sources):
-                       if isinstance(source, EventSourcePulse):
-                               self.comb += self.status.w[i].eq(0)
-                       elif isinstance(source, EventSourceLevel):
-                               self.comb += self.status.w[i].eq(source.trigger)
-                       else:
-                               raise TypeError
-               
-               # pending
                for i, source in enumerate(sources):
-                       # W1C
-                       self.sync += If(self.pending.re & self.pending.r[i], source.pending.eq(0))
-                       if isinstance(source, EventSourcePulse):
-                               # set on a positive trigger pulse
-                               self.sync += If(source.trigger, source.pending.eq(1))
-                       elif isinstance(source, EventSourceLevel):
-                               # set on the falling edge of the trigger
-                               old_trigger = Signal()
-                               self.sync += [
-                                       old_trigger.eq(source.trigger),
-                                       If(~source.trigger & old_trigger, source.pending.eq(1))
-                               ]
-                       else:
-                               raise TypeError
-                       self.comb += self.pending.w[i].eq(source.pending)
+                       self.comb += [
+                               self.status.w[i].eq(source.status),
+                               If(self.pending.re & self.pending.r[i], source.clear.eq(1)),
+                               self.pending.w[i].eq(source.pending)
+                       ]
                
-               # IRQ
                irqs = [self.pending.w[i] & self.enable.storage[i] for i in range(n)]
                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)
+               if isinstance(value, _EventSource):
+                       if self.finalized:
+                               raise FinalizeError
+                       self.submodules += value