Skip to content

Commit

Permalink
soc_core/cpu: add io_regions and deprecate shadow_base (with API retr…
Browse files Browse the repository at this point in the history
…o-compat)

The shadow_base parameter has always been difficult to apprehend, replace it with
io_regions (uncached regions) defined user or the CPU.

The equivalent of a shadow_base parameter of 0x80000000 in the old API is:
io_regions = {0x80000000: 0x80000000} # origin, length

It's still possible to use shadow_base with retro-compat, but user is encouraged
to update and features will be removed in the future.
  • Loading branch information
enjoy-digital committed Oct 9, 2019
1 parent e8b90e8 commit a4ef9b2
Show file tree
Hide file tree
Showing 9 changed files with 60 additions and 19 deletions.
1 change: 1 addition & 0 deletions litex/soc/cores/cpu/lm32/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ class LM32(CPU):
endianness = "big"
gcc_triple = "lm32-elf"
linker_output_format = "elf32-lm32"
io_regions = {0x80000000: 0x80000000} # origin, length

@property
def gcc_flags(self):
Expand Down
1 change: 1 addition & 0 deletions litex/soc/cores/cpu/minerva/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ class Minerva(CPU):
endianness = "little"
gcc_triple = ("riscv64-unknown-elf", "riscv32-unknown-elf", "riscv-none-embed")
linker_output_format = "elf32-littleriscv"
io_regions = {0x80000000: 0x80000000} # origin, length

@property
def gcc_flags(self):
Expand Down
3 changes: 2 additions & 1 deletion litex/soc/cores/cpu/mor1kx/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ class MOR1KX(CPU):
gcc_triple = "or1k-elf"
clang_triple = "or1k-linux"
linker_output_format = "elf32-or1k"
io_regions = {0x80000000: 0x80000000} # origin, length

@property
def mem_map_linux(self):
Expand All @@ -31,7 +32,7 @@ def mem_map_linux(self):
"main_ram" : 0x00000000,
"rom" : 0x10000000,
"sram" : 0x50000000,
"csr" : 0x60000000,
"csr" : 0xe0000000,
}

@property
Expand Down
1 change: 1 addition & 0 deletions litex/soc/cores/cpu/picorv32/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ class PicoRV32(CPU):
endianness = "little"
gcc_triple = ("riscv64-unknown-elf", "riscv32-unknown-elf", "riscv-none-embed")
linker_output_format = "elf32-littleriscv"
io_regions = {0x80000000: 0x80000000} # origin, length

@property
def gcc_flags(self):
Expand Down
1 change: 1 addition & 0 deletions litex/soc/cores/cpu/rocket/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ class RocketRV64(CPU):
endianness = "little"
gcc_triple = ("riscv64-unknown-elf")
linker_output_format = "elf64-littleriscv"
io_regions = {0x80000000: 0x80000000} # origin, length

@property
def mem_map(self):
Expand Down
1 change: 1 addition & 0 deletions litex/soc/cores/cpu/vexriscv/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ class VexRiscv(CPU, AutoCSR):
endianness = "little"
gcc_triple = ("riscv64-unknown-elf", "riscv32-unknown-elf", "riscv-none-embed")
linker_output_format = "elf32-littleriscv"
io_regions = {0x80000000: 0x80000000} # origin, length

@property
def mem_map_linux(self):
Expand Down
3 changes: 1 addition & 2 deletions litex/soc/integration/builder.py
Original file line number Diff line number Diff line change
Expand Up @@ -110,8 +110,7 @@ def define(k, v):
write_to_file(
os.path.join(generated_dir, "csr.h"),
cpu_interface.get_csr_header(self.soc.csr_regions,
self.soc.constants,
shadow_base=self.soc.shadow_base)
self.soc.constants)
)
write_to_file(
os.path.join(generated_dir, "git.h"),
Expand Down
4 changes: 1 addition & 3 deletions litex/soc/integration/export.py
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,7 @@ def _get_rw_functions_c(reg_name, reg_base, nwords, busword, alignment, read_onl
return r


def get_csr_header(regions, constants, with_access_functions=True, with_shadow_base=True, shadow_base=0x80000000):
def get_csr_header(regions, constants, with_access_functions=True):
alignment = constants.get("CONFIG_CSR_ALIGNMENT", 32)
r = generated_banner("//")
r += "#ifndef __GENERATED_CSR_H\n#define __GENERATED_CSR_H\n"
Expand All @@ -174,8 +174,6 @@ def get_csr_header(regions, constants, with_access_functions=True, with_shadow_b
r += "#endif /* ! CSR_ACCESSORS_DEFINED */\n"
for name, region in regions.items():
origin = region.origin
if not with_shadow_base:
origin &= (~shadow_base)
r += "\n/* "+name+" */\n"
r += "#define CSR_"+name.upper()+"_BASE "+hex(origin)+"L\n"
if not isinstance(region.obj, Memory):
Expand Down
64 changes: 51 additions & 13 deletions litex/soc/integration/soc_core.py
Original file line number Diff line number Diff line change
Expand Up @@ -69,16 +69,16 @@ class SoCCore(Module):
csr_map = {}
interrupt_map = {}
mem_map = {
"rom": 0x00000000, # (default shadow @0x80000000)
"sram": 0x01000000, # (default shadow @0x81000000)
"csr": 0x02000000, # (default shadow @0x82000000)
"main_ram": 0x40000000, # (default shadow @0xc0000000)
"rom": 0x00000000,
"sram": 0x01000000,
"main_ram": 0x40000000,
"csr": 0x82000000,
}
io_regions = {}

def __init__(self, platform, clk_freq,
# CPU parameters
cpu_type="vexriscv", cpu_reset_address=0x00000000, cpu_variant=None,
# MEM MAP parameters
shadow_base=0x80000000,
# ROM parameters
integrated_rom_size=0, integrated_rom_init=[],
# SRAM parameters
Expand All @@ -96,14 +96,16 @@ def __init__(self, platform, clk_freq,
# Controller parameters
with_ctrl=True,
# Wishbone parameters
with_wishbone=True, wishbone_timeout_cycles=1e6):
with_wishbone=True, wishbone_timeout_cycles=1e6,
**kwargs):
self.platform = platform
self.clk_freq = clk_freq

# SoC's CSR/Mem/Interrupt mapping (default or user defined + dynamically allocateds)
self.soc_csr_map = {}
self.soc_interrupt_map = {}
self.soc_mem_map = self.mem_map
self.soc_io_regions = self.io_regions

# SoC's Config/Constants/Regions
self.config = {}
Expand All @@ -118,6 +120,8 @@ def __init__(self, platform, clk_freq,
# CSR masters list
self._csr_masters = []

self.add_retro_compat(kwargs)

# Parameters managment ---------------------------------------------------------------------
if cpu_type == "None":
cpu_type = None
Expand All @@ -128,9 +132,6 @@ def __init__(self, platform, clk_freq,
self.cpu_type = cpu_type
self.cpu_variant = cpu.check_format_cpu_variant(cpu_variant)

self.shadow_base = shadow_base
self.config["SHADOW_BASE"] = shadow_base

self.integrated_rom_size = integrated_rom_size
self.integrated_rom_initialized = integrated_rom_init != []
self.integrated_sram_size = integrated_sram_size
Expand Down Expand Up @@ -174,6 +175,9 @@ def __init__(self, platform, clk_freq,
# Update Memory Map (if defined by CPU)
self.soc_mem_map.update(self.cpu.mem_map)

# Update IO Regions (if defined by CPU)
self.soc_io_regions.update(self.cpu.io_regions)

# Set reset address
self.cpu.set_reset_address(self.soc_mem_map["rom"] if integrated_rom_size else cpu_reset_address)
self.config["CPU_RESET_ADDR"] = self.cpu.reset_address
Expand Down Expand Up @@ -348,7 +352,20 @@ def add_csr_master(self, csrm):
raise FinalizeError
self._csr_masters.append(csrm)

def add_memory_region(self, name, origin, length):
def check_io_region(self, name, origin, length):
for region_origin, region_length in self.soc_io_regions.items():
if (origin >= region_origin) & ((origin + length) < (region_origin + region_length)):
return
msg = "{} region: 0x{:08x}-0x{:x} not located in an IO region.\n".format(
name, origin, origin + length - 1)
msg += "Avalaible IO regions:\n"
for region_origin, region_length in self.soc_io_regions.items():
msg += "- 0x{:08x}-0x{:x}\n".format(region_origin, region_origin + region_length - 1)
raise ValueError(msg)

def add_memory_region(self, name, origin, length, io_region=False):
if io_region:
self.check_io_region(name, origin, length)
def in_this_region(addr):
return addr >= origin and addr < origin + length
for n, r in self.mem_regions.items():
Expand All @@ -375,6 +392,7 @@ def check_csr_region(self, name, origin):
raise ValueError("CSR region conflict between {} and {}".format(n, name))

def add_csr_region(self, name, origin, busword, obj):
self.check_io_region(name, origin, 0x800)
self.check_csr_region(name, origin)
self.csr_regions[name] = SoCCSRRegion(origin, busword, obj)

Expand Down Expand Up @@ -433,14 +451,14 @@ def do_finalize(self):
# Check and add CSRs regions
for name, csrs, mapaddr, rmap in self.csrbankarray.banks:
self.check_csr_range(name, 0x800*mapaddr)
self.add_csr_region(name, (self.soc_mem_map["csr"] + 0x800*mapaddr) | self.shadow_base,
self.add_csr_region(name, (self.soc_mem_map["csr"] + 0x800*mapaddr),
self.csr_data_width, csrs)

# Check and add Memory regions
for name, memory, mapaddr, mmap in self.csrbankarray.srams:
self.check_csr_range(name, 0x800*mapaddr)
self.add_csr_region(name + "_" + memory.name_override,
(self.soc_mem_map["csr"] + 0x800*mapaddr) | self.shadow_base,
(self.soc_mem_map["csr"] + 0x800*mapaddr),
self.csr_data_width, memory)

# Add CSRs / Config items to constants
Expand All @@ -464,6 +482,26 @@ def do_finalize(self):
self.comb += self.cpu.interrupt[_id].eq(module.ev.irq)
self.constants[_name.upper() + "_INTERRUPT"] = _id


# API retro-compatibility layer ----------------------------------------------------------------
# Allow user to build the design the old API for ~3 months after the API change is introduced.
# Adds warning and artificical delay to encourage user to update.

def add_retro_compat(self, kwargs):
# 2019-10-09 : deprecate shadow_base, introduce io_regions
if "shadow_base" in kwargs.keys():
deprecated_warning(": shadow_base replaced by IO regions.")
self.retro_compat_shadow_base = kwargs.get("shadow_base", 0x80000000)
self.config["SHADOW_BASE"] = self.retro_compat_shadow_base

def __getattr__(self, name):
# 2019-10-09: deprecate shadow_base, introduce io_regions
if name == "shadow_base":
deprecated_warning(": shadow_base replaced by IO regions.")
return self.retro_compat_shadow_base
else:
return Module.__getattr__(self, name)

# SoCCore arguments --------------------------------------------------------------------------------

def soc_core_args(parser):
Expand Down

0 comments on commit a4ef9b2

Please sign in to comment.