soc_core: add check_regions_overlap method, add linker_region support (overlap is not checked on linker_regions)

This commit is contained in:
Florent Kermarrec 2019-10-28 18:32:28 +01:00
parent 4014fbffe1
commit 9fcf297387
2 changed files with 34 additions and 17 deletions

View File

@ -77,9 +77,11 @@ def SoCConstant(value):
return value return value
class SoCMemRegion: class SoCMemRegion:
def __init__(self, origin, length): def __init__(self, origin, length, io_region=False, linker_region=False):
self.origin = origin self.origin = origin
self.length = length self.length = length
self.io_region = io_region
self.linker_region = linker_region
class SoCCSRRegion: class SoCCSRRegion:
def __init__(self, origin, busword, obj): def __init__(self, origin, busword, obj):

View File

@ -371,20 +371,35 @@ class SoCCore(Module):
msg += "- 0x{:08x}-0x{:08x}\n".format(region_origin, region_origin + region_length - 1) msg += "- 0x{:08x}-0x{:08x}\n".format(region_origin, region_origin + region_length - 1)
raise ValueError(msg) raise ValueError(msg)
def add_memory_region(self, name, origin, length, io_region=False): @staticmethod
def check_regions_overlap(regions):
i = 0
while i < len(regions):
n0 = list(regions.keys())[i]
r0 = regions[n0]
for n1 in list(regions.keys())[i+1:]:
r1 = regions[n1]
if r0.linker_region or r1.linker_region:
continue
if r0.origin >= (r1.origin + r1.length):
continue
if r1.origin >= (r0.origin + r0.length):
continue
return (n0, n1)
i += 1
return None
def add_memory_region(self, name, origin, length, io_region=False, linker_region=False):
length = 2**log2_int(length, False)
if io_region: if io_region:
self.check_io_region(name, origin, length) self.check_io_region(name, origin, length)
def memory_overlap(o0, l0, o1, l1): if name in self.mem_regions.keys():
if o0 >= (o1 + l1): raise ValueError("Memory region conflict, {} name already used".format(name))
return False self.mem_regions[name] = SoCMemRegion(origin, length,
if o1 >= (o0 + l0): io_region=io_region, linker_region=linker_region)
return False overlap = self.check_regions_overlap(self.mem_regions)
return True if overlap is not None:
for n, r in self.mem_regions.items(): raise ValueError("Memory region conflict between {} and {}".format(overlap[0], overlap[1]))
r.length = 2**log2_int(r.length, False)
if n == name or memory_overlap(o0=r.origin, l0=r.length, o1=origin, l1=length):
raise ValueError("Memory region conflict between {} and {}".format(n, name))
self.mem_regions[name] = SoCMemRegion(origin, length)
def register_mem(self, name, address, interface, size=0x10000000): def register_mem(self, name, address, interface, size=0x10000000):
self.add_wb_slave(address, interface, size) self.add_wb_slave(address, interface, size)
@ -436,9 +451,9 @@ class SoCCore(Module):
def do_finalize(self): def do_finalize(self):
# Verify CPU has required memories # Verify CPU has required memories
if self.cpu_type is not None: if self.cpu_type is not None:
for name in "rom", "sram": for name in ["rom", "sram"]:
if name not in self.mem_regions.keys(): if name not in self.mem_regions.keys():
raise FinalizeError("CPU needs \"{}\" to be registered with SoC.register_mem()".format(name)) raise FinalizeError("CPU needs \"{}\" to be defined as memory or linker region".format(name))
# Add the Wishbone Masters/Slaves interconnect # Add the Wishbone Masters/Slaves interconnect
if len(self._wb_masters): if len(self._wb_masters):