integration/soc: add configurable CSR Paging
authorFlorent Kermarrec <florent@enjoy-digital.fr>
Sun, 16 Feb 2020 11:32:05 +0000 (12:32 +0100)
committerFlorent Kermarrec <florent@enjoy-digital.fr>
Sun, 16 Feb 2020 11:32:05 +0000 (12:32 +0100)
litex/soc/integration/soc.py
litex/soc/interconnect/csr_bus.py

index 247685bc8514501631bc5b4557cc3f06b6f0015c..54e852d92d824182cafd79a3e41aa2722868b6d7 100755 (executable)
@@ -26,7 +26,6 @@ from litedram.frontend.axi import LiteDRAMAXI2Native
 
 # TODO:
 # - replace raise with exit on logging error.
-# - add configurable CSR paging.
 # - cleanup SoCCSRRegion
 
 logging.basicConfig(level=logging.INFO)
@@ -429,7 +428,7 @@ class SoCCSRHandler(SoCLocHandler):
     supported_data_width    = [8, 32]
     supported_address_width = [14, 15]
     supported_alignment     = [32, 64]
-    supported_paging        = [0x800]
+    supported_paging        = [0x800, 0x1000]
 
     # Creation -------------------------------------------------------------------------------------
     def __init__(self, data_width=32, address_width=14, alignment=32, paging=0x800, reserved_csrs={}):
@@ -815,7 +814,8 @@ class SoC(Module):
             address_map   = self.csr.address_map,
             data_width    = self.csr.data_width,
             address_width = self.csr.address_width,
-            alignment     = self.csr.alignment
+            alignment     = self.csr.alignment,
+            paging        = self.csr.paging,
         )
         if len(self.csr.masters):
             self.submodules.csr_interconnect = csr_bus.InterconnectShared(
index 8642edbc4475fa9a931dbdbe671d16edb9608d2e..c07a812e37d2e77582c87f6c26729505f3a4dfdf 100644 (file)
@@ -78,7 +78,7 @@ class InterconnectShared(Module):
 
 
 class SRAM(Module):
-    def __init__(self, mem_or_size, address, read_only=None, init=None, bus=None):
+    def __init__(self, mem_or_size, address, paging=0x800, read_only=None, init=None, bus=None):
         if bus is None:
             bus = Interface()
         self.bus = bus
@@ -88,11 +88,12 @@ class SRAM(Module):
         else:
             mem = Memory(data_width, mem_or_size//(data_width//8), init=init)
         mem_size = int(mem.width*mem.depth/8)
-        if mem_size > 512:
-            print("WARNING: memory > 512 bytes in CSR region requires paged access (mem_size = {} bytes)".format(mem_size))
+        if mem_size > paging//4:
+            print("WARNING: memory > {} bytes in CSR region requires paged access (mem_size = {} bytes)".format(
+                paging//4, mem_size))
         csrw_per_memw = (mem.width + data_width - 1)//data_width
         word_bits = log2_int(csrw_per_memw)
-        page_bits = log2_int((mem.depth*csrw_per_memw + 511)//512, False)
+        page_bits = log2_int((mem.depth*csrw_per_memw + paging//4 - 1)//(paging//4), False)
         if page_bits:
             self._page = CSRStorage(page_bits, name=mem.name_override + "_page")
         else:
@@ -111,7 +112,7 @@ class SRAM(Module):
         sel = Signal()
         sel_r = Signal()
         self.sync += sel_r.eq(sel)
-        self.comb += sel.eq(self.bus.adr[9:] == address)
+        self.comb += sel.eq(self.bus.adr[log2_int(paging//4):] == address)
         if bus.alignment == 64:
             self.comb += If(self.bus.adr[0], sel.eq(0))
 
@@ -160,7 +161,7 @@ class SRAM(Module):
 
 
 class CSRBank(csr.GenericBank):
-    def __init__(self, description, address=0, bus=None):
+    def __init__(self, description, address=0, bus=None, paging=0x800):
         if bus is None:
             bus = Interface()
         self.bus = bus
@@ -170,7 +171,7 @@ class CSRBank(csr.GenericBank):
         csr.GenericBank.__init__(self, description, len(self.bus.dat_w))
 
         sel = Signal()
-        self.comb += sel.eq(self.bus.adr[9:] == address)
+        self.comb += sel.eq(self.bus.adr[log2_int(paging//4):] == address)
         if bus.alignment == 64:
             self.comb += If(self.bus.adr[0], sel.eq(0))
 
@@ -201,9 +202,10 @@ class CSRBank(csr.GenericBank):
 # address_map is called exactly once for each object at each call to
 # scan(), so it can have side effects.
 class CSRBankArray(Module):
-    def __init__(self, source, address_map, *ifargs, **ifkwargs):
-        self.source = source
+    def __init__(self, source, address_map, *ifargs, paging=0x800, **ifkwargs):
+        self.source      = source
         self.address_map = address_map
+        self.paging      = paging
         self.scan(ifargs, ifkwargs)
 
     def scan(self, ifargs, ifkwargs):
@@ -227,7 +229,7 @@ class CSRBankArray(Module):
                         continue
                     sram_bus = Interface(*ifargs, **ifkwargs)
                     mmap = SRAM(memory, mapaddr, read_only=read_only,
-                                bus=sram_bus)
+                                bus=sram_bus, paging=self.paging)
                     self.submodules += mmap
                     csrs += mmap.get_csrs()
                     self.srams.append((name, memory, mapaddr, mmap))
@@ -239,7 +241,7 @@ class CSRBankArray(Module):
                 if mapaddr is None:
                     continue
                 bank_bus = Interface(*ifargs, **ifkwargs)
-                rmap = CSRBank(csrs, mapaddr, bus=bank_bus)
+                rmap = CSRBank(csrs, mapaddr, bus=bank_bus, paging=self.paging)
                 self.submodules += rmap
                 self.banks.append((name, csrs, mapaddr, rmap))