Add SVD export capability to Builder (csr_svd parameter) and targets (--csr-svd argum...
authorFlorent Kermarrec <florent@enjoy-digital.fr>
Fri, 6 Mar 2020 07:36:52 +0000 (08:36 +0100)
committerFlorent Kermarrec <florent@enjoy-digital.fr>
Fri, 6 Mar 2020 13:12:58 +0000 (14:12 +0100)
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

litex/soc/doc/__init__.py
litex/soc/integration/builder.py
litex/soc/integration/export.py

index 0ee6c3d5865b5dd6360a3700ba061cb6b3e746fe..fe2f479fdd83a8fd7f45144d92269dd50a9fd85d 100644 (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,
index 333b4fcd431ab83d4221da57917eb31b251772e1..2092067468198f7ea995358d2016aa8a75d52761 100644 (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
@@ -58,8 +59,9 @@ class Builder:
 
         self.compile_software = compile_software
         self.compile_gateware = compile_gateware
-        self.csr_csv = csr_csv
+        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,17 +221,21 @@ 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):
     return {
-        "output_dir": args.output_dir,
-        "gateware_dir": args.gateware_dir,
-        "software_dir": args.software_dir,
-        "include_dir": args.include_dir,
-        "generated_dir": args.generated_dir,
+        "output_dir":       args.output_dir,
+        "gateware_dir":     args.gateware_dir,
+        "software_dir":     args.software_dir,
+        "include_dir":      args.include_dir,
+        "generated_dir":    args.generated_dir,
         "compile_software": not args.no_compile_software,
         "compile_gateware": not args.no_compile_gateware,
-        "csr_csv": args.csr_csv,
-        "csr_json": args.csr_json,
+        "csr_csv":          args.csr_csv,
+        "csr_json":         args.csr_json,
+        "csr_svd":          args.csr_svd,
     }
index f9854cb44a9483a9a0efd94fe9012321ed1beb50..f31e55333a9e8e1687f86fb290811154bbb25dd9 100644 (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"?>')