bank: support direct mapping of CSRs on Wishbone
authorSebastien Bourdeauducq <sb@m-labs.hk>
Sun, 30 Nov 2014 14:28:39 +0000 (22:28 +0800)
committerSebastien Bourdeauducq <sb@m-labs.hk>
Sun, 30 Nov 2014 14:28:39 +0000 (22:28 +0800)
migen/bank/bank.py [new file with mode: 0644]
migen/bank/csrgen.py
migen/bank/wbgen.py [new file with mode: 0644]

diff --git a/migen/bank/bank.py b/migen/bank/bank.py
new file mode 100644 (file)
index 0000000..a989085
--- /dev/null
@@ -0,0 +1,23 @@
+from migen.fhdl.std import Module, bits_for
+from migen.bank.description import CSR
+
+class GenericBank(Module):
+       def __init__(self, description, busword):
+               # Turn description into simple CSRs and claim ownership of compound CSR modules
+               self.simple_csrs = []
+               for c in description:
+                       if isinstance(c, CSR):
+                               self.simple_csrs.append(c)
+                       else:
+                               c.finalize(busword)
+                               self.simple_csrs += c.get_simple_csrs()
+                               self.submodules += c
+               self.decode_bits = bits_for(len(self.simple_csrs)-1)
+
+def get_offset(description, name, busword):
+       offset = 0
+       for c in description:
+               if c.name == name:
+                       return offset
+               offset += (c.size + busword - 1)//busword
+       raise KeyError("CSR not found: "+name)
index 0eec054616e223d392c6e878470e076c00a6d6cc..2223394b454ebf56d4b546907374439139adffbf 100644 (file)
@@ -1,17 +1,9 @@
 from migen.util.misc import xdir
 from migen.fhdl.std import *
 from migen.bus import csr
-from migen.bank.description import *
+from migen.bank.bank import GenericBank
 
-def get_offset(description, name, csr_data_width=8):
-       offset = 0
-       for c in description:
-               if c.name == name:
-                       return offset
-               offset += (c.size + csr_data_width - 1)//csr_data_width
-       raise KeyError("CSR not found: "+name)
-
-class Bank(Module):
+class Bank(GenericBank):
        def __init__(self, description, address=0, bus=None):
                if bus is None:
                        bus = csr.Interface()
@@ -19,38 +11,23 @@ class Bank(Module):
 
                ###
 
-               if not description:
-                       return
-
-               # Turn description into simple CSRs and claim ownership of compound CSR modules
-               simple_csrs = []
-               for c in description:
-                       if isinstance(c, CSR):
-                               simple_csrs.append(c)
-                       else:
-                               c.finalize(flen(self.bus.dat_w))
-                               simple_csrs += c.get_simple_csrs()
-                               self.submodules += c
-               nbits = bits_for(len(simple_csrs)-1)
+               GenericBank.__init__(self, description, flen(self.bus.dat_w))
 
-               # Decode selection
                sel = Signal()
                self.comb += sel.eq(self.bus.adr[9:] == address)
 
-               # Bus writes
-               for i, c in enumerate(simple_csrs):
+               for i, c in enumerate(self.simple_csrs):
                        self.comb += [
                                c.r.eq(self.bus.dat_w[:c.size]),
                                c.re.eq(sel & \
                                        self.bus.we & \
-                                       (self.bus.adr[:nbits] == i))
+                                       (self.bus.adr[:self.decode_bits] == i))
                        ]
 
-               # Bus reads
-               brcases = dict((i, self.bus.dat_r.eq(c.w)) for i, c in enumerate(simple_csrs))
+               brcases = dict((i, self.bus.dat_r.eq(c.w)) for i, c in enumerate(self.simple_csrs))
                self.sync += [
                        self.bus.dat_r.eq(0),
-                       If(sel, Case(self.bus.adr[:nbits], brcases))
+                       If(sel, Case(self.bus.adr[:self.decode_bits], brcases))
                ]
 
 # address_map(name, memory) returns the CSR offset at which to map
@@ -77,6 +54,8 @@ class BankArray(Module):
                                memories = obj.get_memories()
                                for memory in memories:
                                        mapaddr = self.address_map(name, memory)
+                                       if mapaddr is None:
+                                               continue
                                        sram_bus = csr.Interface(*ifargs, **ifkwargs)
                                        mmap = csr.SRAM(memory, mapaddr, bus=sram_bus)
                                        self.submodules += mmap
@@ -84,6 +63,8 @@ class BankArray(Module):
                                        self.srams.append((name, memory, mapaddr, mmap))
                        if csrs:
                                mapaddr = self.address_map(name, None)
+                               if mapaddr is None:
+                                       continue
                                bank_bus = csr.Interface(*ifargs, **ifkwargs)
                                rmap = Bank(csrs, mapaddr, bus=bank_bus)
                                self.submodules += rmap
diff --git a/migen/bank/wbgen.py b/migen/bank/wbgen.py
new file mode 100644 (file)
index 0000000..0047bc1
--- /dev/null
@@ -0,0 +1,26 @@
+from migen.fhdl.std import *
+from migen.bus import wishbone
+from migen.bank.bank import GenericBank
+
+class Bank(GenericBank):
+       def __init__(self, description, bus=None):
+               if bus is None:
+                       bus = wishbone.Interface()
+               self.bus = bus
+
+               ###
+
+               GenericBank.__init__(self, description, flen(self.bus.dat_w))
+
+               for i, c in enumerate(self.simple_csrs):
+                       self.comb += [
+                               c.r.eq(self.bus.dat_w[:c.size]),
+                               c.re.eq(self.bus.cyc & self.bus.stb & ~self.bus.ack & self.bus.we & \
+                                       (self.bus.adr[:self.decode_bits] == i))
+                       ]
+
+               brcases = dict((i, self.bus.dat_r.eq(c.w)) for i, c in enumerate(self.simple_csrs))
+               self.sync += [
+                       Case(self.bus.adr[:self.decode_bits], brcases),
+                       If(bus.ack, bus.ack.eq(0)).Elif(bus.cyc & bus.stb, bus.ack.eq(1))
+               ]