integration/soc: add configurable CSR Paging

This commit is contained in:
Florent Kermarrec 2020-02-16 12:32:05 +01:00
parent 6576470179
commit 67e8a042f8
2 changed files with 16 additions and 14 deletions

View File

@ -26,7 +26,6 @@ from litedram.frontend.axi import LiteDRAMAXI2Native
# TODO: # TODO:
# - replace raise with exit on logging error. # - replace raise with exit on logging error.
# - add configurable CSR paging.
# - cleanup SoCCSRRegion # - cleanup SoCCSRRegion
logging.basicConfig(level=logging.INFO) logging.basicConfig(level=logging.INFO)
@ -429,7 +428,7 @@ class SoCCSRHandler(SoCLocHandler):
supported_data_width = [8, 32] supported_data_width = [8, 32]
supported_address_width = [14, 15] supported_address_width = [14, 15]
supported_alignment = [32, 64] supported_alignment = [32, 64]
supported_paging = [0x800] supported_paging = [0x800, 0x1000]
# Creation ------------------------------------------------------------------------------------- # Creation -------------------------------------------------------------------------------------
def __init__(self, data_width=32, address_width=14, alignment=32, paging=0x800, reserved_csrs={}): 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, address_map = self.csr.address_map,
data_width = self.csr.data_width, data_width = self.csr.data_width,
address_width = self.csr.address_width, address_width = self.csr.address_width,
alignment = self.csr.alignment alignment = self.csr.alignment,
paging = self.csr.paging,
) )
if len(self.csr.masters): if len(self.csr.masters):
self.submodules.csr_interconnect = csr_bus.InterconnectShared( self.submodules.csr_interconnect = csr_bus.InterconnectShared(

View File

@ -78,7 +78,7 @@ class InterconnectShared(Module):
class SRAM(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: if bus is None:
bus = Interface() bus = Interface()
self.bus = bus self.bus = bus
@ -88,11 +88,12 @@ class SRAM(Module):
else: else:
mem = Memory(data_width, mem_or_size//(data_width//8), init=init) mem = Memory(data_width, mem_or_size//(data_width//8), init=init)
mem_size = int(mem.width*mem.depth/8) mem_size = int(mem.width*mem.depth/8)
if mem_size > 512: if mem_size > paging//4:
print("WARNING: memory > 512 bytes in CSR region requires paged access (mem_size = {} bytes)".format(mem_size)) 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 csrw_per_memw = (mem.width + data_width - 1)//data_width
word_bits = log2_int(csrw_per_memw) 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: if page_bits:
self._page = CSRStorage(page_bits, name=mem.name_override + "_page") self._page = CSRStorage(page_bits, name=mem.name_override + "_page")
else: else:
@ -111,7 +112,7 @@ class SRAM(Module):
sel = Signal() sel = Signal()
sel_r = Signal() sel_r = Signal()
self.sync += sel_r.eq(sel) 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: if bus.alignment == 64:
self.comb += If(self.bus.adr[0], sel.eq(0)) self.comb += If(self.bus.adr[0], sel.eq(0))
@ -160,7 +161,7 @@ class SRAM(Module):
class CSRBank(csr.GenericBank): 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: if bus is None:
bus = Interface() bus = Interface()
self.bus = bus self.bus = bus
@ -170,7 +171,7 @@ class CSRBank(csr.GenericBank):
csr.GenericBank.__init__(self, description, len(self.bus.dat_w)) csr.GenericBank.__init__(self, description, len(self.bus.dat_w))
sel = Signal() 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: if bus.alignment == 64:
self.comb += If(self.bus.adr[0], sel.eq(0)) 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 # address_map is called exactly once for each object at each call to
# scan(), so it can have side effects. # scan(), so it can have side effects.
class CSRBankArray(Module): class CSRBankArray(Module):
def __init__(self, source, address_map, *ifargs, **ifkwargs): def __init__(self, source, address_map, *ifargs, paging=0x800, **ifkwargs):
self.source = source self.source = source
self.address_map = address_map self.address_map = address_map
self.paging = paging
self.scan(ifargs, ifkwargs) self.scan(ifargs, ifkwargs)
def scan(self, ifargs, ifkwargs): def scan(self, ifargs, ifkwargs):
@ -227,7 +229,7 @@ class CSRBankArray(Module):
continue continue
sram_bus = Interface(*ifargs, **ifkwargs) sram_bus = Interface(*ifargs, **ifkwargs)
mmap = SRAM(memory, mapaddr, read_only=read_only, mmap = SRAM(memory, mapaddr, read_only=read_only,
bus=sram_bus) bus=sram_bus, paging=self.paging)
self.submodules += mmap self.submodules += mmap
csrs += mmap.get_csrs() csrs += mmap.get_csrs()
self.srams.append((name, memory, mapaddr, mmap)) self.srams.append((name, memory, mapaddr, mmap))
@ -239,7 +241,7 @@ class CSRBankArray(Module):
if mapaddr is None: if mapaddr is None:
continue continue
bank_bus = Interface(*ifargs, **ifkwargs) 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.submodules += rmap
self.banks.append((name, csrs, mapaddr, rmap)) self.banks.append((name, csrs, mapaddr, rmap))