build/parser: Add LiteXSoCArgumentParser compatibility and switch to it in integration/soc.

Move things a bit to add target_group only when platform is set and avoid recursive imports.
This commit is contained in:
Florent Kermarrec 2022-11-07 13:16:24 +01:00
parent a2cb04b218
commit 1ce3271efe
2 changed files with 38 additions and 54 deletions

View File

@ -8,8 +8,9 @@ import argparse
import importlib import importlib
import sys import sys
from litex.soc.integration.soc_core import * from litex.soc.cores import cpu
from litex.soc.integration.builder import * from litex.soc.integration import soc_core
from litex.soc.integration import builder
# Litex Argument Parser ---------------------------------------------------------------------------- # Litex Argument Parser ----------------------------------------------------------------------------
@ -44,30 +45,15 @@ class LiteXArgumentParser(argparse.ArgumentParser):
all arguments passed to argparse.ArgumentParser CTOR all arguments passed to argparse.ArgumentParser CTOR
""" """
argparse.ArgumentParser.__init__(self, kwargs) argparse.ArgumentParser.__init__(self, kwargs)
self._platform = platform self._platform = None
if platform is not None:
self._device = platform.device_family
toolchains = platform.toolchains(self._device)
self._default_toolchain = toolchains[0]
else:
self._device = None self._device = None
toolchains = None self.toolchains = None
self._default_toolchain = None self._default_toolchain = None
self._args = None self._args = None
self._toolchain = None self._toolchain = None
if platform is not None:
self._target_group = self.add_argument_group(title="Target options") self.set_platform(platform)
if toolchains is not None: self.add_target_group()
self.add_target_argument("--toolchain",
default = self._default_toolchain,
choices = toolchains,
help = "FPGA toolchain ({}).".format(" or ".join(toolchains)))
else:
self.add_target_argument("-toolchain", help="FPGA toolchain")
self.add_target_argument("--build", action="store_true", help="Build design.")
self.add_target_argument("--load", action="store_true", help="Load bitstream.")
builder_args(self)
soc_core_args(self)
def set_platform(self, platform): def set_platform(self, platform):
""" set platform. Check first if not already set """ set platform. Check first if not already set
@ -80,8 +66,9 @@ class LiteXArgumentParser(argparse.ArgumentParser):
assert self._platform is None assert self._platform is None
self._platform = platform self._platform = platform
self._device = platform.device_family self._device = platform.device_family
toolchains = platform.toolchains(self._device) self.toolchains = platform.toolchains(self._device)
self._default_toolchain = toolchains[0] self._default_toolchain = self.toolchains[0]
# add a setter (LitexArgumentParserInstance.platform = myPlatform) # add a setter (LitexArgumentParserInstance.platform = myPlatform)
platform = property(None, set_platform) platform = property(None, set_platform)
@ -91,6 +78,20 @@ class LiteXArgumentParser(argparse.ArgumentParser):
""" """
return self._target_group return self._target_group
def add_target_group(self):
""" create target group and add --toolchain/build/load args.
"""
self._target_group = self.add_argument_group(title="Target options")
if self.toolchains is not None:
self.add_target_argument("--toolchain",
default = self._default_toolchain,
choices = self.toolchains,
help = "FPGA toolchain ({}).".format(" or ".join(self.toolchains)))
else:
self.add_target_argument("-toolchain", help="FPGA toolchain")
self.add_target_argument("--build", action="store_true", help="Build design.")
self.add_target_argument("--load", action="store_true", help="Load bitstream.")
def add_target_argument(self, *args, **kwargs): def add_target_argument(self, *args, **kwargs):
""" wrapper to add argument to "Target options group" from outer of this """ wrapper to add argument to "Target options group" from outer of this
class class
@ -106,7 +107,7 @@ class LiteXArgumentParser(argparse.ArgumentParser):
====== ======
builder arguments dict builder arguments dict
""" """
return builder_argdict(self._args) return builder.builder_argdict(self._args)
@property @property
def soc_argdict(self): def soc_argdict(self):
@ -117,7 +118,7 @@ class LiteXArgumentParser(argparse.ArgumentParser):
====== ======
soc_core arguments dict soc_core arguments dict
""" """
return soc_core_argdict(self._args) # FIXME: Rename to soc_argdict in the future. return soc_core.soc_core_argdict(self._args) # FIXME: Rename to soc_argdict in the future.
@property @property
def toolchain_argdict(self): def toolchain_argdict(self):
@ -140,11 +141,18 @@ class LiteXArgumentParser(argparse.ArgumentParser):
Checks first is platform is set: when platform is none: try to Checks first is platform is set: when platform is none: try to
search for a platform argument search for a platform argument
""" """
# When platform is None try to search for a user input # When platform is None try to search for a user input
if self._platform is None: if self._platform is None:
platform = self.get_value_from_key("--platform", None) platform = self.get_value_from_key("--platform", None)
if platform is not None: if platform is not None:
self.set_platform(importlib.import_module(platform).Platform) self.set_platform(importlib.import_module(platform).Platform)
self.add_target_group()
# When platform provided/set, set builder/soc_core args.
if self._platform is not None:
builder.builder_args(self)
soc_core.soc_core_args(self)
# Intercept selected toolchain to fill arguments. # Intercept selected toolchain to fill arguments.
if self._platform is not None: if self._platform is not None:

View File

@ -2096,30 +2096,6 @@ class LiteXSoC(SoC):
# LiteXSoCArgumentParser --------------------------------------------------------------------------- # LiteXSoCArgumentParser ---------------------------------------------------------------------------
class LiteXSoCArgumentParser(argparse.ArgumentParser): from litex.build.parser import LiteXArgumentParser
def parse_args(self):
# FIXME: Use 2 stages parser? class LiteXSoCArgumentParser(LiteXArgumentParser): pass # FIXME: Add compat and remove.
def get_selected_cpu_name():
for name, cpu_cls in cpu.CPUS.items():
if f"--cpu-type={name}" in sys.argv:
return cpu_cls
if f"--cpu-type" in sys.argv:
if name in sys.argv:
return cpu_cls
return None
# Intercept selected CPU to fill arguments.
cpu_cls = get_selected_cpu_name()
if cpu_cls is not None and hasattr(cpu_cls, "args_fill"):
cpu_cls.args_fill(self)
# Get Command-line arguments.
args = argparse.ArgumentParser.parse_args(self)
# Re-inject CPU read arguments.
if cpu_cls is not None and hasattr(cpu_cls, "args_read"):
cpu_cls.args_read(args)
return args