Add SVD export capability to Builder (csr_svd parameter) and targets (--csr-svd argument) and fix svd regression.

This allows generating SVD export files during the build as we are already doing for .csv or .json.

Use with Builder:
builder = Builder(soc, csr_svd="csr.svd")

Use with target:
./arty.py --csr-svd=csr.svd
This commit is contained in:
Florent Kermarrec 2020-03-06 08:36:52 +01:00
parent e124aed9a2
commit e2dab06386
3 changed files with 43 additions and 37 deletions

View File

@ -32,7 +32,7 @@ def generate_svd(soc, buildpath, filename=None, name="soc", **kwargs):
filename = name + ".svd"
kwargs["name"] = name
with open(buildpath + "/" + filename, "w", encoding="utf-8") as svd:
svd.write(export.get_svd(soc, **kwargs))
svd.write(export.get_csr_svd(soc, **kwargs))
def generate_docs(soc, base_dir,

View File

@ -14,7 +14,7 @@ import struct
import shutil
from litex.build.tools import write_to_file
from litex.soc.integration import cpu_interface, soc_core
from litex.soc.integration import export, soc_core
__all__ = ["soc_software_packages", "soc_directory",
"Builder", "builder_args", "builder_argdict"]
@ -45,7 +45,8 @@ class Builder:
compile_software = True,
compile_gateware = True,
csr_json = None,
csr_csv = None):
csr_csv = None,
csr_svd = None):
self.soc = soc
# From Python doc: makedirs() will become confused if the path
@ -60,6 +61,7 @@ class Builder:
self.compile_gateware = compile_gateware
self.csr_csv = csr_csv
self.csr_json = csr_json
self.csr_svd = csr_svd
self.software_packages = []
for name in soc_software_packages:
@ -79,7 +81,7 @@ class Builder:
def define(k, v):
variables_contents.append("{}={}\n".format(k, _makefile_escape(v)))
for k, v in cpu_interface.get_cpu_mak(self.soc.cpu, self.compile_software):
for k, v in export.get_cpu_mak(self.soc.cpu, self.compile_software):
define(k, v)
# Distinguish between LiteX and MiSoC.
define("LITEX", "1")
@ -106,25 +108,25 @@ class Builder:
"".join(variables_contents))
write_to_file(
os.path.join(self.generated_dir, "output_format.ld"),
cpu_interface.get_linker_output_format(self.soc.cpu))
export.get_linker_output_format(self.soc.cpu))
write_to_file(
os.path.join(self.generated_dir, "regions.ld"),
cpu_interface.get_linker_regions(self.soc.mem_regions))
export.get_linker_regions(self.soc.mem_regions))
write_to_file(
os.path.join(self.generated_dir, "mem.h"),
cpu_interface.get_mem_header(self.soc.mem_regions))
export.get_mem_header(self.soc.mem_regions))
write_to_file(
os.path.join(self.generated_dir, "soc.h"),
cpu_interface.get_soc_header(self.soc.constants))
export.get_soc_header(self.soc.constants))
write_to_file(
os.path.join(self.generated_dir, "csr.h"),
cpu_interface.get_csr_header(self.soc.csr_regions,
export.get_csr_header(self.soc.csr_regions,
self.soc.constants)
)
write_to_file(
os.path.join(self.generated_dir, "git.h"),
cpu_interface.get_git_header()
export.get_git_header()
)
if hasattr(self.soc, "sdram"):
@ -134,16 +136,21 @@ class Builder:
self.soc.sdram.controller.settings.phy,
self.soc.sdram.controller.settings.timing))
def _generate_csr_map(self, csr_json=None, csr_csv=None):
if csr_json is not None:
csr_dir = os.path.dirname(os.path.realpath(csr_json))
def _generate_csr_map(self):
if self.csr_json is not None:
csr_dir = os.path.dirname(os.path.realpath(self.csr_json))
os.makedirs(csr_dir, exist_ok=True)
write_to_file(csr_json, cpu_interface.get_csr_json(self.soc.csr_regions, self.soc.constants, self.soc.mem_regions))
write_to_file(self.csr_json, export.get_csr_json(self.soc.csr_regions, self.soc.constants, self.soc.mem_regions))
if csr_csv is not None:
csr_dir = os.path.dirname(os.path.realpath(csr_csv))
if self.csr_csv is not None:
csr_dir = os.path.dirname(os.path.realpath(self.csr_csv))
os.makedirs(csr_dir, exist_ok=True)
write_to_file(csr_csv, cpu_interface.get_csr_csv(self.soc.csr_regions, self.soc.constants, self.soc.mem_regions))
write_to_file(self.csr_csv, export.get_csr_csv(self.soc.csr_regions, self.soc.constants, self.soc.mem_regions))
if self.csr_svd is not None:
svd_dir = os.path.dirname(os.path.realpath(self.csr_svd))
os.makedirs(svd_dir, exist_ok=True)
write_to_file(self.csr_svd, export.get_csr_svd(self.soc))
def _prepare_software(self):
for name, src_dir in self.software_packages:
@ -180,7 +187,7 @@ class Builder:
if not self.soc.integrated_rom_initialized:
self._initialize_rom()
self._generate_csr_map(self.csr_json, self.csr_csv)
self._generate_csr_map()
if "run" not in kwargs:
kwargs["run"] = self.compile_gateware
@ -214,6 +221,9 @@ def builder_args(parser):
parser.add_argument("--csr-json", default=None,
help="store CSR map in JSON format into the "
"specified file")
parser.add_argument("--csr-svd", default=None,
help="store CSR map in SVD format into the "
"specified file")
def builder_argdict(args):
@ -227,4 +237,5 @@ def builder_argdict(args):
"compile_gateware": not args.no_compile_gateware,
"csr_csv": args.csr_csv,
"csr_json": args.csr_json,
"csr_svd": args.csr_svd,
}

View File

@ -281,7 +281,7 @@ def get_csr_csv(csr_regions={}, constants={}, mem_regions={}):
# SVD Export --------------------------------------------------------------------------------------
def get_svd(soc, vendor="litex", name="soc", description=None):
def get_csr_svd(soc, vendor="litex", name="soc", description=None):
def sub_csr_bit_range(busword, csr, offset):
nwords = (csr.size + busword - 1)//busword
i = nwords - offset - 1
@ -337,17 +337,12 @@ def get_svd(soc, vendor="litex", name="soc", description=None):
interrupts[csr] = irq
documented_regions = []
raw_regions = []
if hasattr(soc, "get_csr_regions"):
raw_regions = soc.get_csr_regions()
else:
for region_name, region in soc.csr_regions.items():
raw_regions.append((region_name, region.origin,
region.busword, region.obj))
for csr_region in raw_regions:
for name, region in soc.csr.regions.items():
documented_regions.append(DocumentedCSRRegion(
csr_region, csr_data_width=soc.csr_data_width))
name = name,
region = region,
csr_data_width = soc.csr.data_width)
)
svd = []
svd.append('<?xml version="1.0" encoding="utf-8"?>')