build: assume vendor tools are in the PATH and remove automatic sourcing, source...
authorFlorent Kermarrec <florent@enjoy-digital.fr>
Wed, 4 Mar 2020 08:06:27 +0000 (09:06 +0100)
committerFlorent Kermarrec <florent@enjoy-digital.fr>
Wed, 4 Mar 2020 08:13:26 +0000 (09:13 +0100)
Automatic sourcing was not consistent between build backends (and only really supported by ISE/Vivado)
and had no real additional value vs the complexity needed to support it. Now just assume required vendor
tools are in the PATH.

This also removes distutils dependency.

12 files changed:
litex/build/altera/quartus.py
litex/build/lattice/diamond.py
litex/build/lattice/icestorm.py
litex/build/lattice/trellis.py
litex/build/microsemi/libero_soc.py
litex/build/sim/verilator.py
litex/build/tools.py
litex/build/xilinx/common.py
litex/build/xilinx/ise.py
litex/build/xilinx/programmer.py
litex/build/xilinx/vivado.py
litex/soc/integration/builder.py

index 813969cdf0535b3d23bb02ab36a7e4f845b8ebac..a6c42a074c316a38a589b88f81bd5752db0373e8 100644 (file)
@@ -123,7 +123,7 @@ def _build_qsf(device, ips, sources, vincpaths, named_sc, named_pc, build_name,
 
 # Script -------------------------------------------------------------------------------------------
 
-def _build_script(build_name, quartus_path, create_rbf):
+def _build_script(build_name, create_rbf):
     if sys.platform in ["win32", "cygwin"]:
         script_contents = "REM Autogenerated by LiteX / git: " + tools.get_litex_git_revision()
         script_file = "build_" + build_name + ".bat"
@@ -168,14 +168,9 @@ class AlteraQuartusToolchain:
     def build(self, platform, fragment,
         build_dir      = "build",
         build_name     = "top",
-        toolchain_path = None,
         run            = True,
         **kwargs):
 
-        # Get default toolchain path (if not specified)
-        if toolchain_path is None:
-            toolchain_path = "/opt/Altera"
-
         # Create build directory
         cwd = os.getcwd()
         os.makedirs(build_dir, exist_ok=True)
@@ -214,7 +209,7 @@ class AlteraQuartusToolchain:
             additional_qsf_commands = self.additional_qsf_commands)
 
         # Generate build script
-        script = _build_script(build_name, toolchain_path, platform.create_rbf)
+        script = _build_script(build_name, platform.create_rbf)
 
         # Run
         if run:
index c2c05218f39eb41d906e49bbf8abe5626de04152..083f4ed388cffa7788e5fb665120b0d06bf38198 100644 (file)
@@ -93,7 +93,7 @@ def _build_tcl(device, sources, vincpaths, build_name):
 
 # Script -------------------------------------------------------------------------------------------
 
-def _build_script(build_name, device, toolchain_path, ver=None):
+def _build_script(build_name, device):
     if sys.platform in ("win32", "cygwin"):
         script_ext = ".bat"
         script_contents = "@echo off\nrem Autogenerated by LiteX / git: " + tools.get_litex_git_revision() + "\n\n"
@@ -105,11 +105,7 @@ def _build_script(build_name, device, toolchain_path, ver=None):
         copy_stmt = "cp"
         fail_stmt = ""
 
-    if sys.platform not in ("win32", "cygwin"):
-        script_contents += "bindir={}\n".format(toolchain_path)
-        script_contents += ". ${{bindir}}/diamond_env{fail_stmt}\n".format(fail_stmt=fail_stmt)
-    script_contents += "{pnmainc} {tcl_script}{fail_stmt}\n".format(
-        pnmainc    = os.path.join(toolchain_path, "pnmainc"),
+    script_contents += "pnmainc {tcl_script}{fail_stmt}\n".format(
         tcl_script = build_name + ".tcl",
         fail_stmt  = fail_stmt)
     for ext in (".bit", ".jed"):
@@ -158,13 +154,10 @@ class LatticeDiamondToolchain:
     def build(self, platform, fragment,
         build_dir      = "build",
         build_name     = "top",
-        toolchain_path = None,
         run            = True,
         **kwargs):
 
         # Create build directory
-        if toolchain_path is None:
-            toolchain_path = "/opt/Diamond"
         os.makedirs(build_dir, exist_ok=True)
         cwd = os.getcwd()
         os.chdir(build_dir)
@@ -188,7 +181,7 @@ class LatticeDiamondToolchain:
         _build_tcl(platform.device, platform.sources, platform.verilog_include_paths, build_name)
 
         # Generate build script
-        script = _build_script(build_name, platform.device, toolchain_path)
+        script = _build_script(build_name, platform.device)
 
         # Run
         if run:
index 05b3912cbdf6c2157195c2dd32b2d80c33fca586..0f6fc68b2306be2dd3e8f6f575af50aee230f84e 100644 (file)
@@ -151,7 +151,6 @@ class LatticeIceStormToolchain:
     def build(self, platform, fragment,
         build_dir      = "build",
         build_name     = "top",
-        toolchain_path = None,
         synth_opts     = "",
         run            = True,
         **kwargs):
index 1bd84adbe013e80b76a36ef126e8b17c6693d445..066c169c99aeb60f3f5490fd8fe3a8b648c369db 100644 (file)
@@ -178,17 +178,12 @@ class LatticeTrellisToolchain:
     def build(self, platform, fragment,
         build_dir      = "build",
         build_name     = "top",
-        toolchain_path = None,
         run            = True,
         nowidelut      = False,
         timingstrict   = False,
         ignoreloops    = False,
         **kwargs):
 
-        # Get default toolchain path (if not specified)
-        if toolchain_path is None:
-            toolchain_path = "/usr/share/trellis/"
-
         # Create build directory
         os.makedirs(build_dir, exist_ok=True)
         cwd = os.getcwd()
index 8110034d2da91aac367dbb006fcf239a9a7fc848..5b39861e3640b378f4e371552eb647f69efdf04e 100644 (file)
@@ -184,7 +184,7 @@ def _build_timing_sdc(vns, clocks, false_paths, build_name, additional_timing_co
 
 # Script -------------------------------------------------------------------------------------------
 
-def _build_script(build_name, device, toolchain_path, ver=None):
+def _build_script(build_name, device):
     if sys.platform in ("win32", "cygwin"):
         script_ext = ".bat"
         script_contents = "@echo off\nREM Autogenerated by LiteX / git: " + tools.get_litex_git_revision() + "\n\n"
@@ -238,7 +238,6 @@ class MicrosemiLiberoSoCPolarfireToolchain:
     def build(self, platform, fragment,
             build_dir      = "build",
             build_name     = "top",
-            toolchain_path = None,
             run            = False,
             **kwargs):
 
@@ -273,7 +272,7 @@ class MicrosemiLiberoSoCPolarfireToolchain:
             self.additional_timing_constraints)
 
         # Generate build script
-        script = _build_script(build_name, platform.device, toolchain_path)
+        script = _build_script(build_name, platform.device)
 
         # Run
         if run:
index 5270e3301741655059e7003bbb0ad5083a620eb1..682192a29e291b3fa5202c2feee0bf46484d7623 100644 (file)
@@ -170,7 +170,7 @@ def _run_sim(build_name, as_root=False):
 
 class SimVerilatorToolchain:
     def build(self, platform, fragment, build_dir="build", build_name="dut",
-            toolchain_path=None, serial="console", build=True, run=True, threads=1,
+            serial="console", build=True, run=True, threads=1,
             verbose=True, sim_config=None, coverage=False, opt_level="O0",
             trace=False, trace_fst=False, trace_start=0, trace_end=-1):
 
index 30be031c94f953ac1737b80d09507202d6334e8f..030d32f53819fb120a6cda6e6172a4254c35996e 100644 (file)
@@ -6,7 +6,6 @@
 
 import os
 import struct
-from distutils.version import StrictVersion
 import re
 import subprocess
 import sys
@@ -39,21 +38,6 @@ def write_to_file(filename, contents, force_unix=False):
             f.write(contents)
 
 
-def arch_bits():
-    return struct.calcsize("P")*8
-
-
-def versions(path):
-    for n in os.listdir(path):
-        full = os.path.join(path, n)
-        if not os.path.isdir(full):
-            continue
-        try:
-            yield StrictVersion(n)
-        except ValueError:
-            continue
-
-
 def sub_rules(line, rules, max_matches=1):
     for pattern, color in rules:
         line, matches = re.subn(pattern, color, line, max_matches)
index 8848d85c549c9c4f0ef3d623bea238bc4c0c0e63..bc6c96d50a3ce3e13b34d99015a63c5d29606f53 100644 (file)
@@ -39,36 +39,6 @@ if _have_colorama:
          r"\g<0>" + colorama.Style.RESET_ALL),
     ]
 
-# Settings -----------------------------------------------------------------------------------------
-
-def settings(path, ver=None, sub=None):
-    if ver is None:
-        vers = list(tools.versions(path))
-        if not vers:
-            raise OSError("no version directory for Xilinx tools found in "
-                          + path)
-        ver = max(vers)
-
-    full = os.path.join(path, str(ver))
-    if sub:
-        full = os.path.join(full, sub)
-
-    search = [64, 32]
-    if tools.arch_bits() == 32:
-        search.reverse()
-
-    if sys.platform == "win32" or sys.platform == "cygwin":
-        script_ext = "bat"
-    else:
-        script_ext = "sh"
-
-    for b in search:
-        settings = os.path.join(full, "settings{0}.{1}".format(b, script_ext))
-        if os.path.exists(settings):
-            return settings
-
-    raise OSError("no Xilinx tools settings file found")
-
 # Common MultiReg ----------------------------------------------------------------------------------
 
 class XilinxMultiRegImpl(MultiRegImpl):
index a6c3e9b150cf73ee1a54c9c636a3f6dd2f80715b..57864174a59be5a11aad7bff697413e116cebf0f 100644 (file)
@@ -105,23 +105,17 @@ write_edif -pvector bra {build_name}.edif""".format(build_name=build_name, famil
 
 # ISE Run ------------------------------------------------------------------------------------------
 
-def _run_ise(build_name, ise_path, source, mode, ngdbuild_opt,
-        toolchain, platform, ver=None):
+def _run_ise(build_name, mode, ngdbuild_opt, toolchain, platform):
     if sys.platform == "win32" or sys.platform == "cygwin":
-        source_cmd = "call "
         script_ext = ".bat"
         shell = ["cmd", "/c"]
         build_script_contents = "@echo off\nrem Autogenerated by LiteX / git: " + tools.get_litex_git_revision() + "\n"
         fail_stmt = " || exit /b"
     else:
-        source_cmd = "source "
         script_ext = ".sh"
         shell = ["bash"]
         build_script_contents = "# Autogenerated by LiteX / git: " + tools.get_litex_git_revision() + "\nset -e\n"
         fail_stmt = ""
-    if source:
-        settings = common.settings(ise_path, ver, "ISE_DS")
-        build_script_contents += source_cmd + tools.cygpath(settings) + "\n"
     if mode == "edif":
         ext = "ngo"
         build_script_contents += """
@@ -189,21 +183,10 @@ class XilinxISEToolchain:
     def build(self, platform, fragment,
         build_dir      = "build",
         build_name     = "top",
-        toolchain_path = None,
-        source         = True,
         run            = True,
         mode           = "xst",
         **kwargs):
 
-        # Get default toolchain path (if not specified)
-        if toolchain_path is None:
-            if sys.platform == "win32":
-                toolchain_path = "C:\\Xilinx"
-            elif sys.platform == "cygwin":
-                toolchain_path = "/cygdrive/c/Xilinx"
-            else:
-                toolchain_path = "/opt/Xilinx"
-
         # Create build directory
         os.makedirs(build_dir, exist_ok=True)
         cwd = os.getcwd()
@@ -250,7 +233,7 @@ class XilinxISEToolchain:
 
             # Run ISE
             if run:
-                _run_ise(build_name, toolchain_path, source, isemode, self.ngdbuild_opt, self, platform)
+                _run_ise(build_name, isemode, self.ngdbuild_opt, self, platform)
         finally:
             os.chdir(cwd)
 
index 0ad0abac4b625b5010086b655b79072ed7efbb0c..eddbda5a85ab13b4aec68f898e2d91e86344c276 100644 (file)
@@ -7,7 +7,6 @@
 import os
 import sys
 import subprocess
-from distutils.spawn import find_executable
 
 from litex.build.generic_programmer import GenericProgrammer
 from litex.build.xilinx import common
@@ -122,25 +121,7 @@ quit
 # Vivado -------------------------------------------------------------------------------------------
 
 def _run_vivado(path, ver, cmds):
-    if sys.platform == "win32" or sys.platform == "cygwin":
-        vivado_cmd = "vivado -mode tcl"
-    else:
-        vivado_cmd = ""
-        if not find_executable("vivado"):
-            # For backwards compatibility with ISE paths, also
-            # look for a version in a subdirectory named "Vivado"
-            # under the current directory.
-            paths_to_try = [path, os.path.join(path, "Vivado")]
-            for p in paths_to_try:
-                try:
-                    settings = common.settings(p, ver)
-                except OSError:
-                    continue
-                break
-            else:
-                raise OSError("Unable to locate Vivado directory or settings.")
-            vivado_cmd += "source " + settings + " && "
-        vivado_cmd += "vivado -mode tcl"
+    vivado_cmd = "vivado -mode tcl"
     with subprocess.Popen(vivado_cmd, stdin=subprocess.PIPE, shell=True) as process:
         process.stdin.write(cmds.encode("ASCII"))
         process.communicate()
index e5c568bec356104fdd4ef847ca2593b195523aeb..014b5ca286184d20373e55e53e18c7c9f409ac00 100644 (file)
@@ -5,7 +5,6 @@ import os
 import subprocess
 import sys
 import math
-from distutils.spawn import find_executable
 
 from migen.fhdl.structure import _Fragment
 
@@ -66,7 +65,7 @@ def _build_xdc(named_sc, named_pc):
 
 # Script -------------------------------------------------------------------------------------------
 
-def _build_script(build_name, vivado_path, source, ver=None):
+def _build_script(build_name):
     if sys.platform in ["win32", "cygwin"]:
         script_contents = "REM Autogenerated by LiteX / git: " + tools.get_litex_git_revision() + "\n"
         script_contents += "vivado -mode batch -source " + build_name + ".tcl\n"
@@ -74,22 +73,6 @@ def _build_script(build_name, vivado_path, source, ver=None):
         tools.write_to_file(script_file, script_contents)
     else:
         script_contents = "# Autogenerated by LiteX / git: " + tools.get_litex_git_revision() + "\nset -e\n"
-        # Only source Vivado settings if not already in our $PATH
-        if not find_executable("vivado"):
-            # For backwards compatibility with ISE paths, also
-            # look for a version in a subdirectory named "Vivado"
-            # under the current directory.
-            paths_to_try = [vivado_path, os.path.join(vivado_path, "Vivado")]
-            for p in paths_to_try:
-                try:
-                    settings = common.settings(p, ver)
-                except OSError:
-                    continue
-                break
-            else:
-                raise OSError("Unable to locate Vivado directory or settings.")
-            script_contents += "source " + settings + "\n"
-
         script_contents += "vivado -mode batch -source " + build_name + ".tcl\n"
         script_file = "build_" + build_name + ".sh"
         tools.write_to_file(script_file, script_contents)
@@ -303,18 +286,13 @@ class XilinxVivadoToolchain:
         )
 
     def build(self, platform, fragment,
-        build_dir      = "build",
-        build_name     = "top",
-        toolchain_path = None,
-        source         = True, run=True,
-        synth_mode     = "vivado",
-        enable_xpm     = False,
+        build_dir  = "build",
+        build_name = "top",
+        run        = True,
+        synth_mode = "vivado",
+        enable_xpm = False,
         **kwargs):
 
-        # Get default toolchain path (if not specified)
-        if toolchain_path is None:
-            toolchain_path = "/opt/Xilinx/Vivado"
-
         # Create build directory
         os.makedirs(build_dir, exist_ok=True)
         cwd = os.getcwd()
@@ -351,7 +329,7 @@ class XilinxVivadoToolchain:
         if run:
             if synth_mode == "yosys":
                 common._run_yosys(platform.device, platform.sources, platform.verilog_include_paths, build_name)
-            script = _build_script(build_name, toolchain_path, source)
+            script = _build_script(build_name)
             _run_script(script)
 
         os.chdir(cwd)
index a5963973923ac21eaf74e292baf8fb313ad0dc5d..0a2b161e84053a0d33a126961f5ca87fb2c44e57 100644 (file)
@@ -45,7 +45,6 @@ class Builder:
         generated_dir           = None,
         compile_software        = True,
         compile_gateware        = True,
-        gateware_toolchain_path = None,
         csr_json                = None,
         csr_csv                 = None):
         self.soc = soc
@@ -60,7 +59,6 @@ class Builder:
 
         self.compile_software = compile_software
         self.compile_gateware = compile_gateware
-        self.gateware_toolchain_path = gateware_toolchain_path
         self.csr_csv = csr_csv
         self.csr_json = csr_json
 
@@ -168,7 +166,7 @@ class Builder:
         bios_data = soc_core.get_mem_data(bios_file, self.soc.cpu.endianness)
         self.soc.initialize_rom(bios_data)
 
-    def build(self, toolchain_path=None, **kwargs):
+    def build(self, **kwargs):
         self.soc.platform.output_dir = self.output_dir
         os.makedirs(self.gateware_dir, exist_ok=True)
         os.makedirs(self.software_dir, exist_ok=True)
@@ -185,13 +183,9 @@ class Builder:
 
         self._generate_csr_map(self.csr_json, self.csr_csv)
 
-        if self.gateware_toolchain_path is not None:
-            toolchain_path = self.gateware_toolchain_path
-
         if "run" not in kwargs:
             kwargs["run"] = self.compile_gateware
-        vns = self.soc.build(build_dir=self.gateware_dir,
-                             toolchain_path=toolchain_path, **kwargs)
+        vns = self.soc.build(build_dir=self.gateware_dir, **kwargs)
         self.soc.do_exit(vns=vns)
         return vns
 
@@ -215,9 +209,6 @@ def builder_args(parser):
     parser.add_argument("--no-compile-gateware", action="store_true",
                         help="do not compile the gateware, only generate "
                              "HDL source files and build scripts")
-    parser.add_argument("--gateware-toolchain-path", default=None,
-                        help="set gateware toolchain (ISE, Quartus, etc.) "
-                             "installation path")
     parser.add_argument("--csr-csv", default=None,
                         help="store CSR map in CSV format into the "
                              "specified file")
@@ -235,7 +226,6 @@ def builder_argdict(args):
         "generated_dir": args.generated_dir,
         "compile_software": not args.no_compile_software,
         "compile_gateware": not args.no_compile_gateware,
-        "gateware_toolchain_path": args.gateware_toolchain_path,
         "csr_csv": args.csr_csv,
         "csr_json": args.csr_json,
     }