Skip to content

Commit

Permalink
gateware.platform: add support for using yowasp when yosys is not ava…
Browse files Browse the repository at this point in the history
…ilable
  • Loading branch information
antoinevg committed Dec 9, 2024
1 parent be05684 commit 3bbe069
Show file tree
Hide file tree
Showing 3 changed files with 84 additions and 2 deletions.
9 changes: 9 additions & 0 deletions luna/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@
from amaranth import Elaboratable
from amaranth._unused import MustUse

from luna.gateware.platform import configure_toolchain

# Log formatting strings.
LOG_FORMAT_COLOR = "\u001b[37;1m%(levelname)-8s| \u001b[0m\u001b[1m%(module)-12s|\u001b[0m %(message)s"
LOG_FORMAT_PLAIN = "%(levelname)-8s:n%(module)-12s>%(message)s"
Expand Down Expand Up @@ -108,8 +110,15 @@ def top_level_cli(fragment, *pos_args, **kwargs):
join_text = "and uploading gateware to attached" if args.upload else "for"
logging.info(f"Building {join_text} {platform.name}...")

# Configure toolchain.
if not configure_toolchain(platform):
logging.info(f"Failed to configure the toolchain for: {platform.toolchain}")
logging.info(f"Continuing anyway.")

# Now that we're actually building, re-enable Unused warnings.
MustUse._MustUse__silence = False

# Perform the build.
products = platform.build(fragment,
do_program=args.upload,
build_dir=build_dir
Expand Down
5 changes: 3 additions & 2 deletions luna/gateware/platform/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
from amaranth import Record

from .core import NullPin, LUNAPlatform
from .toolchain import configure_toolchain


def _get_platform_from_string(platform):
Expand Down Expand Up @@ -63,11 +64,11 @@ def get_appropriate_platform() -> LUNAPlatform:
"Unable to autodetect a supported platform. "
"The LUNA_PLATFORM environment variable must be set.")
platform = _get_platform_from_string(platform_string)

# If possible, override the platform's device type with the detected FPGA.
if fpga_device is not None:
platform.device = fpga_device

return platform


Expand Down
72 changes: 72 additions & 0 deletions luna/gateware/platform/toolchain.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
#
# This file is part of LUNA.
#
# Copyright (c) 2020-2024 Great Scott Gadgets <[email protected]>
# SPDX-License-Identifier: BSD-3-Clause

""" Utilities for managing LUNA gateware toolchains. """

import importlib
import logging
import os
import shutil

def configure_toolchain(platform):
""" Checks if all the required tools for the Yosys toolchain are available.
If there are missing tools it will attempt to fall back to YoWASP instead.
Returns:
True if a valid toolchain has been configured. Otherwise False.
"""

if platform.has_required_tools():
# All good, no further hanky-panky required.
return True

# Do we have yowasp available to us?
logging.info(f"Failed to locate {platform.toolchain} toolchain, trying YoWASP.")
logging.debug("Checking for required tools:")
for tool in platform.required_tools:
logging.debug(f" {tool}")

problems = 0

# Check whether yowasp-yosys is installed:
try:
import yowasp_yosys
logging.debug(f"Found module: {yowasp_yosys.__name__}")
except Exception as e:
problems += 1
logging.warning(e)

# Check whether yowasp-nextpnr-<target> is installed:
try:
nextpnr = next(filter(lambda x: x.startswith("nextpnr-"), platform.required_tools))
yowasp_nextpnr = importlib.import_module("yowasp_" + nextpnr.replace('-', '_'))
logging.debug(f"Found module: {yowasp_nextpnr.__name__}")
except Exception as e:
problems += 1
logging.warning(e)

# Check whether the YoWASP binaries are on the system PATH:
for tool in platform.required_tools:
env_var = tool.replace('-', '_').upper()
yowasp_tool = "yowasp-" + tool
path = shutil.which(yowasp_tool)
if not path:
problems += 1
logging.warning(f"'{yowasp_tool}' is not on the system PATH.")
else:
logging.debug(f'Setting {env_var}="{yowasp_tool}"')
os.environ[env_var] = yowasp_tool

if problems == 0:
logging.info("YoWASP configured successfully.")
else:
logging.info(f"{problems} problems encountered while configuring YoWASP.")
logging.info(f"You can install it with:")
logging.info(f" pip install yowasp-yosys yowasp-{nextpnr}")
return False

return True

0 comments on commit 3bbe069

Please sign in to comment.