Commit 022721a8 authored by William D. Jones's avatar William D. Jones Committed by whitequark
Browse files

lattice/diamond: Support sourcing by default.

parent 17e6d348
...@@ -14,6 +14,24 @@ from migen.build import tools ...@@ -14,6 +14,24 @@ from migen.build import tools
from migen.build.lattice import common from migen.build.lattice import common
def _get_bindir(path, ver=None):
if ver is None:
# _x64 suffix means StrictVersion will fail.
vers = list(tools.versions(path, strict=False))
if not vers:
raise OSError("no version directory for Diamond tools found in "
+ path)
ver = max(vers)
# Lattice does not provide 32-bit binaries anymore.
if sys.platform in ("win32", "cygwin"):
bin_suffix = "nt64"
else:
bin_suffix = "lin64"
return os.path.join(path, str(ver), "bin", bin_suffix)
def _produces_jedec(device): def _produces_jedec(device):
return device.startswith("LCMX") return device.startswith("LCMX")
...@@ -68,7 +86,7 @@ def _build_files(device, sources, vincpaths, build_name): ...@@ -68,7 +86,7 @@ def _build_files(device, sources, vincpaths, build_name):
tools.write_to_file(build_name + ".tcl", "\n".join(tcl)) tools.write_to_file(build_name + ".tcl", "\n".join(tcl))
def _build_script(build_name, device, toolchain_path, ver=None): def _build_script(build_name, device, toolchain_path, source, ver=None):
if sys.platform in ("win32", "cygwin"): if sys.platform in ("win32", "cygwin"):
script_ext = ".bat" script_ext = ".bat"
build_script_contents = "@echo off\nrem Autogenerated by Migen\n\n" build_script_contents = "@echo off\nrem Autogenerated by Migen\n\n"
...@@ -80,22 +98,36 @@ def _build_script(build_name, device, toolchain_path, ver=None): ...@@ -80,22 +98,36 @@ def _build_script(build_name, device, toolchain_path, ver=None):
copy_stmt = "cp" copy_stmt = "cp"
fail_stmt = "" fail_stmt = ""
if sys.platform not in ("win32", "cygwin"): bindir = _get_bindir(toolchain_path, ver)
build_script_contents += "bindir={}\n".format(toolchain_path) if source:
build_script_contents += ". ${{bindir}}/diamond_env{fail_stmt}\n".format( if sys.platform in ("win32", "cygwin"):
fail_stmt=fail_stmt) build_script_contents += "set PATH={};%PATH%\n".format(bindir)
build_script_contents += "{pnmainc} {tcl_script}{fail_stmt}\n".format( else:
pnmainc=os.path.join(toolchain_path, "pnmainc"), build_script_contents += "bindir={}\n".format(bindir)
build_script_contents += ". ${{bindir}}/diamond_env{fail_stmt}\n".format(
fail_stmt=fail_stmt)
build_script_contents += "pnmainc {tcl_script}{fail_stmt}\n".format(
tcl_script=build_name + ".tcl", tcl_script=build_name + ".tcl",
fail_stmt=fail_stmt) fail_stmt=fail_stmt)
for ext in (".bit", ".jed"): for ext in (".bit", ".jed"):
if ext == ".jed" and not _produces_jedec(device): if ext == ".jed" and not _produces_jedec(device):
continue continue
diamond_product = os.path.join("impl", build_name + "_impl" + ext)
if sys.platform in ("win32", "cygwin"):
# While Windows itself has no problems with forward slashes
# in paths, the COPY command on Windows uses forward slash for
# arguments. MinGW Python 3 may (it is not consistent) create
# paths with forward slashes on Windows, so remove them just in
# case.
diamond_product = diamond_product.replace("/", "\\")
build_script_contents += "{copy_stmt} {diamond_product} {migen_product}" \ build_script_contents += "{copy_stmt} {diamond_product} {migen_product}" \
"{fail_stmt}\n".format( "{fail_stmt}\n".format(
copy_stmt=copy_stmt, copy_stmt=copy_stmt,
fail_stmt=fail_stmt, fail_stmt=fail_stmt,
diamond_product=os.path.join("impl", build_name + "_impl" + ext), diamond_product=diamond_product,
migen_product=build_name + ext) migen_product=build_name + ext)
build_script_file = "build_" + build_name + script_ext build_script_file = "build_" + build_name + script_ext
...@@ -131,9 +163,15 @@ class LatticeDiamondToolchain: ...@@ -131,9 +163,15 @@ class LatticeDiamondToolchain:
special_overrides = common.lattice_ecpx_special_overrides special_overrides = common.lattice_ecpx_special_overrides
def build(self, platform, fragment, build_dir="build", build_name="top", def build(self, platform, fragment, build_dir="build", build_name="top",
toolchain_path=None, run=True, **kwargs): toolchain_path=None, source=True, run=True, ver=None, **kwargs):
if toolchain_path is None: if toolchain_path is None:
toolchain_path = "/opt/Diamond" if sys.platform == "win32":
toolchain_path = "C:\\lscc\\diamond"
elif sys.platform == "cygwin":
toolchain_path = "/cygdrive/c/lscc/diamond"
else:
toolchain_path = "/usr/local/diamond"
os.makedirs(build_dir, exist_ok=True) os.makedirs(build_dir, exist_ok=True)
cwd = os.getcwd() cwd = os.getcwd()
os.chdir(build_dir) os.chdir(build_dir)
...@@ -151,7 +189,8 @@ class LatticeDiamondToolchain: ...@@ -151,7 +189,8 @@ class LatticeDiamondToolchain:
tools.write_to_file(build_name + ".lpf", _build_lpf(named_sc, named_pc)) tools.write_to_file(build_name + ".lpf", _build_lpf(named_sc, named_pc))
script = _build_script(build_name, platform.device, toolchain_path) script = _build_script(build_name, platform.device, toolchain_path,
source, ver)
if run: if run:
_run_script(script) _run_script(script)
......
import os import os
import struct import struct
from distutils.version import StrictVersion from distutils.version import StrictVersion, LooseVersion
import re import re
import subprocess import subprocess
import sys import sys
...@@ -28,13 +28,16 @@ def arch_bits(): ...@@ -28,13 +28,16 @@ def arch_bits():
return struct.calcsize("P")*8 return struct.calcsize("P")*8
def versions(path): def versions(path, strict=True):
for n in os.listdir(path): for n in os.listdir(path):
full = os.path.join(path, n) full = os.path.join(path, n)
if not os.path.isdir(full): if not os.path.isdir(full):
continue continue
try: try:
yield StrictVersion(n) if strict:
yield StrictVersion(n)
else:
yield LooseVersion(n)
except ValueError: except ValueError:
continue continue
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment