wishbone.SRAM: Support non-32bit wishbone widths.
[litex.git] / litex / soc / interconnect / wishbone.py
index 48d002c40aad38bdd798ad11ceccf5faf33b55e8..7e8b78d7b95f6a687bdb681ce97e1bfda2fd6dfe 100644 (file)
@@ -1,15 +1,15 @@
 from functools import reduce
 from operator import or_
 
-from litex.gen import *
-from litex.gen.genlib import roundrobin
-from litex.gen.genlib.record import *
-from litex.gen.genlib.misc import split, displacer, chooser
-from litex.gen.genlib.fsm import FSM, NextState
+from migen import *
+from migen.genlib import roundrobin
+from migen.genlib.record import *
+from migen.genlib.misc import split, displacer, chooser, WaitTimer
+from migen.genlib.fsm import FSM, NextState
 
 from litex.soc.interconnect import csr
 
-# TODO: rewrite without FlipFlop and Counter
+# TODO: rewrite without FlipFlop
 
 
 _layout = [
@@ -33,6 +33,10 @@ class Interface(Record):
             data_width=data_width,
             sel_width=data_width//8))
 
+    @staticmethod
+    def like(other):
+        return Interface(len(other.dat_w))
+
     def _do_transaction(self):
         yield self.cyc.eq(1)
         yield self.stb.eq(1)
@@ -130,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):
@@ -458,7 +481,7 @@ class Cache(Module):
         self.master = master
         self.slave = slave
 
-        ###
+        # # #
 
         dw_from = len(master.dat_r)
         dw_to = len(slave.dat_r)
@@ -628,7 +651,7 @@ class SRAM(Module):
         # generate write enable signal
         if not read_only:
             self.comb += [port.we[i].eq(self.bus.cyc & self.bus.stb & self.bus.we & self.bus.sel[i])
-                for i in range(4)]
+                for i in range(bus_data_width//8)]
         # address and data
         self.comb += [
             port.adr.eq(self.bus.adr[:len(port.adr)]),