cpu_interface: add json csr map export, simplify csv csr map export using json

This commit is contained in:
Florent Kermarrec 2019-08-15 09:26:25 +02:00
parent 9d4b7cd515
commit 2899928aba
2 changed files with 65 additions and 32 deletions

View File

@ -1,5 +1,5 @@
# This file is Copyright (c) 2015 Sebastien Bourdeauducq <sb@m-labs.hk>
# This file is Copyright (c) 2015-2018 Florent Kermarrec <florent@enjoy-digital.fr>
# This file is Copyright (c) 2015-2019 Florent Kermarrec <florent@enjoy-digital.fr>
# This file is Copyright (c) 2019 Mateusz Holenko <mholenko@antmicro.com>
# This file is Copyright (c) 2018 Peter Gielda <pgielda@antmicro.com>
# This file is Copyright (c) 2018 Sergiusz Bazanski <q3k@q3k.org>
@ -41,7 +41,7 @@ class Builder:
def __init__(self, soc, output_dir=None,
compile_software=True, compile_gateware=True,
gateware_toolchain_path=None,
csr_csv=None):
csr_json=None, csr_csv=None):
self.soc = soc
if output_dir is None:
output_dir = "soc_{}_{}".format(
@ -54,6 +54,7 @@ class Builder:
self.compile_gateware = compile_gateware
self.gateware_toolchain_path = gateware_toolchain_path
self.csr_csv = csr_csv
self.csr_json = csr_json
self.software_packages = []
for name in soc_software_packages:
@ -128,7 +129,7 @@ class Builder:
self.soc.sdram.controller.settings.phy,
self.soc.sdram.controller.settings.timing))
def _generate_csr_csv(self):
def _generate_csr_map(self, csr_json=None, csr_csv=None):
memory_regions = self.soc.get_memory_regions()
csr_regions = self.soc.get_csr_regions()
constants = self.soc.get_constants()
@ -141,11 +142,15 @@ class Builder:
if flash_boot_address:
constants.append(('flash_boot_address', flash_boot_address))
csr_dir = os.path.dirname(os.path.realpath(self.csr_csv))
os.makedirs(csr_dir, exist_ok=True)
write_to_file(
self.csr_csv,
cpu_interface.get_csr_csv(csr_regions, constants, memory_regions))
if csr_json is not None:
csr_dir = os.path.dirname(os.path.realpath(csr_json))
os.makedirs(csr_dir, exist_ok=True)
write_to_file(csr_json, cpu_interface.get_csr_json(csr_regions, constants, memory_regions))
if csr_csv is not None:
csr_dir = os.path.dirname(os.path.realpath(csr_csv))
os.makedirs(csr_dir, exist_ok=True)
write_to_file(csr_csv, cpu_interface.get_csr_csv(csr_regions, constants, memory_regions))
def _prepare_software(self):
for name, src_dir in self.software_packages:
@ -180,8 +185,7 @@ class Builder:
if not self.soc.integrated_rom_initialized:
self._initialize_rom()
if self.csr_csv is not None:
self._generate_csr_csv()
self._generate_csr_map(self.csr_json, self.csr_csv)
if self.gateware_toolchain_path is not None:
toolchain_path = self.gateware_toolchain_path
@ -209,6 +213,9 @@ def builder_args(parser):
parser.add_argument("--csr-csv", default=None,
help="store CSR map in CSV format into the "
"specified file")
parser.add_argument("--csr-json", default=None,
help="store CSR map in JSON format into the "
"specified file")
def builder_argdict(args):

View File

@ -13,6 +13,7 @@
# License: BSD
import os
import json
from shutil import which
from migen import *
@ -192,30 +193,55 @@ def get_csr_header(regions, constants, with_access_functions=True, with_shadow_b
r += "\n#endif\n"
return r
def get_csr_csv(csr_regions=None, constants=None, memory_regions=None):
def get_csr_json(csr_regions=[], constants=[], memory_regions=[]):
alignment = 32 if constants is None else get_constant("CONFIG_CSR_ALIGNMENT", constants)
d = {
"csr_bases": {},
"csr_registers": {},
"constants": {},
"memories": {},
}
for name, origin, busword, obj in csr_regions:
d["csr_bases"][name] = origin
if not isinstance(obj, Memory):
for csr in obj:
size = (csr.size + busword - 1)//busword
d["csr_registers"][name + "_" + csr.name] = {
"addr": origin,
"size": size,
"type": "ro" if isinstance(csr, CSRStatus) else "rw"
}
origin += alignment//8*size
for name, value in constants:
d["constants"][name.lower()] = value.lower() if isinstance(value, str) else value
for name, origin, length in memory_regions:
d["memories"][name.lower()] = {
"base": origin,
"size": length
}
return json.dumps(d, indent=4)
def get_csr_csv(csr_regions=[], constants=[], memory_regions=[]):
d = json.loads(get_csr_json(csr_regions, constants, memory_regions))
r = generated_banner("#")
if csr_regions is not None:
for name, origin, busword, obj in csr_regions:
r += "csr_base,{},0x{:08x},,\n".format(name, origin)
for name, origin, busword, obj in csr_regions:
if not isinstance(obj, Memory):
for csr in obj:
nr = (csr.size + busword - 1)//busword
r += "csr_register,{}_{},0x{:08x},{},{}\n".format(name, csr.name, origin, nr, "ro" if isinstance(csr, CSRStatus) else "rw")
origin += alignment//8*nr
if constants is not None:
for name, value in constants:
r += "constant,{},{},,\n".format(name.lower(), value)
if memory_regions is not None:
for name, origin, length in memory_regions:
r += "memory_region,{},0x{:08x},{:d},\n".format(name.lower(), origin, length)
for name, value in d["csr_bases"].items():
r += "csr_base,{},0x{:08x},,\n".format(name, value)
for name in d["csr_registers"].keys():
r += "csr_register,{},0x{:08x},{},{}\n".format(name,
d["csr_registers"][name]["addr"],
d["csr_registers"][name]["size"],
d["csr_registers"][name]["type"])
for name, value in d["constants"].items():
r += "constant,{},{},,\n".format(name, value)
for name in d["memories"].keys():
r += "memory_region,{},0x{:08x},{:d},\n".format(name,
d["memories"][name]["base"],
d["memories"][name]["size"])
return r
def get_git_header():