soc/interconnect/wishbone: add Timeout to avoid stalling bus when not responding...
authorFlorent Kermarrec <florent@enjoy-digital.fr>
Mon, 6 Aug 2018 10:21:18 +0000 (12:21 +0200)
committerFlorent Kermarrec <florent@enjoy-digital.fr>
Mon, 6 Aug 2018 10:21:18 +0000 (12:21 +0200)
litex/soc/interconnect/wishbone.py

index 8f3437c1239f541ff7488456b8b9da4e39e79b20..93a3126683b428c59c289f28f5793d8c1d7f8d60 100644 (file)
@@ -4,7 +4,7 @@ from operator import or_
 from migen import *
 from migen.genlib import roundrobin
 from migen.genlib.record import *
-from migen.genlib.misc import split, displacer, chooser
+from migen.genlib.misc import split, displacer, chooser, WaitTimer
 from migen.genlib.fsm import FSM, NextState
 
 from litex.soc.interconnect import csr
@@ -134,11 +134,30 @@ class Decoder(Module):
         self.comb += master.dat_r.eq(reduce(or_, masked))
 
 
+class Timeout(Module):
+    def __init__(self, master, cycles):
+        self.error = Signal()
+
+        # # #
+
+        timer = WaitTimer(cycles)
+        self.submodules += timer
+        self.comb += [
+            timer.wait.eq(master.stb & master.cyc & ~master.ack),
+            If(timer.done,
+                master.dat_r.eq((2**len(master.dat_w))-1),
+                master.ack.eq(1),
+                self.error.eq(1)
+            )
+        ]
+
+
 class InterconnectShared(Module):
-    def __init__(self, masters, slaves, register=False):
+    def __init__(self, masters, slaves, register=False, timeout_cycles=2**16):
         shared = Interface()
-        self.submodules += Arbiter(masters, shared)
-        self.submodules += Decoder(shared, slaves, register)
+        self.submodules.arbiter = Arbiter(masters, shared)
+        self.submodules.decoder = Decoder(shared, slaves, register)
+        self.submodules.timeout = Timeout(shared, timeout_cycles)
 
 
 class Crossbar(Module):