build/xxx/platform: adding methods to return toolchains list by device, and args by toolchain

This commit is contained in:
Gwenhael Goavec-Merou 2022-09-03 23:15:11 +02:00
parent 38ee44a85a
commit d061e9b9cf
17 changed files with 198 additions and 8 deletions

View File

@ -16,6 +16,8 @@ class AlteraPlatform(GenericPlatform):
bitstream_ext = ".sof"
create_rbf = True
_supported_toolchains = ["quartus"]
def __init__(self, *args, toolchain="quartus", **kwargs):
GenericPlatform.__init__(self, *args, **kwargs)
self.ips = set()

View File

@ -15,6 +15,8 @@ from litex.build.anlogic import common, anlogic
class AnlogicPlatform(GenericPlatform):
bitstream_ext = ".fs"
_supported_toolchains = ["td"]
def __init__(self, device, *args, toolchain="td", **kwargs):
GenericPlatform.__init__(self, device, *args, **kwargs)
if toolchain == "td":

View File

@ -18,6 +18,8 @@ from litex.build.efinix import EfinixDbParser
class EfinixPlatform(GenericPlatform):
bitstream_ext = ".bit"
_supported_toolchains = ["efinity"]
def __init__(self, *args, iobank_info=None, toolchain="efinity", **kwargs):
GenericPlatform.__init__(self, *args, **kwargs)

View File

@ -322,6 +322,8 @@ class ConstraintManager:
# Generic Platform ---------------------------------------------------------------------------------
class GenericPlatform:
device_family = None
def __init__(self, device, io, connectors=[], name=None):
self.toolchain = None
self.device = device
@ -467,3 +469,54 @@ class GenericPlatform:
@property
def support_mixed_language(self):
return self.toolchain.support_mixed_language
@classmethod
def fill_args(cls, toolchain, parser):
"""
pass parser to the specific toolchain to
fill this with toolchain args
Parameters
==========
toolchain: str
toolchain name
parser: argparse.ArgumentParser
parser to be filled
"""
pass # pass must be overloaded (if required)
@classmethod
def get_argdict(cls, toolchain, args):
"""
return a dict of args
Parameters
==========
toolchain: str
toolchain name
Return
======
a dict of key/value for each args or an empty dict
"""
return {} # Empty must be overloaded (if required)
@classmethod
def toolchains(cls, device):
"""
Returns list of toolchains compatible with device
Parameters
==========
device: str
device name (ice40, ecp5, nexus)
Return
======
A list of compatible toolchains (str) or an empty list
"""
if type(cls._supported_toolchains) == dict:
assert device is not None
return cls._supported_toolchains[device]
else:
return cls._supported_toolchains

View File

@ -15,6 +15,8 @@ from litex.build.gowin import common, gowin
class GowinPlatform(GenericPlatform):
bitstream_ext = ".fs"
_supported_toolchains = ["gowin", "apicula"]
def __init__(self, device, *args, toolchain="gowin", devicename=None, **kwargs):
GenericPlatform.__init__(self, device, *args, **kwargs)
if not devicename:

View File

@ -1,2 +1,2 @@
from litex.build.lattice.platform import LatticePlatform
from litex.build.lattice.platform import LatticePlatform, LatticeiCE40Platform, LatticeECP5Platform, LatticeNexusPlatform
from litex.build.lattice.programmer import LatticeProgrammer

View File

@ -106,7 +106,7 @@ class LatticeIceStormToolchain(YosysNextPNRToolchain):
def icestorm_args(parser):
toolchain_group = parser.add_argument_group(title="Toolchain options")
toolchain_group = parser.add_argument_group(title="Icestorm toolchain options")
yosys_nextpnr_args(toolchain_group)
def icestorm_argdict(args):

View File

@ -62,7 +62,7 @@ class LatticeOxideToolchain(YosysNextPNRToolchain):
return (self._build_name + ".pdc", "PDC")
def oxide_args(parser):
toolchain_group = parser.add_argument_group(title="Toolchain options")
toolchain_group = parser.add_argument_group(title="Oxide toolchain options")
yosys_nextpnr_args(toolchain_group)
toolchain_group.add_argument("--nexus-es-device", action="store_true", help="Use Nexus-ES1 part.")

View File

@ -13,6 +13,12 @@ from litex.build.lattice import common, diamond, icestorm, trellis, radiant, oxi
class LatticePlatform(GenericPlatform):
bitstream_ext = ".bit"
_supported_toolchains = {
"ice40": ["icestorm"],
"ecp5": ["trellis", "diamond"],
"nexus": ["radiant", "oxide"],
}
def __init__(self, *args, toolchain="diamond", **kwargs):
GenericPlatform.__init__(self, *args, **kwargs)
if toolchain == "diamond":
@ -38,7 +44,6 @@ class LatticePlatform(GenericPlatform):
attr_translate = self.toolchain.attr_translate,
**kwargs)
def build(self, *args, **kwargs):
return self.toolchain.build(self, *args, **kwargs)
@ -54,3 +59,67 @@ class LatticePlatform(GenericPlatform):
if hasattr(to, "p"):
to = to.p
self.toolchain.add_false_path_constraint(self, from_, to)
@classmethod
def fill_args(cls, toolchain, parser):
"""
pass parser to the specific toolchain to
fill this with toolchain args
Parameters
==========
toolchain: str
toolchain name
parser: argparse.ArgumentParser
parser to be filled
"""
if toolchain == "radiant":
radiant.radiant_build_args(parser)
elif toolchain == "oxide":
oxide.oxide_args(parser)
elif toolchain == "trellis":
trellis.trellis_args(parser)
elif toolchain == "icestorm":
icestorm.icestorm_args(parser)
# nothing for diamond
@classmethod
def get_argdict(cls, toolchain, args):
"""
return a dict of args
Parameters
==========
toolchain: str
toolchain name
Return
======
a dict of key/value for each args or an empty dict
"""
if toolchain == "radiant":
return radiant.radiant_build_argdict(args)
elif toolchain == "oxide":
return oxide.oxide_argdict(args)
elif toolchain == "trellis":
return trellis.trellis_argdict(args)
elif toolchain == "icestorm":
return icestorm.icestorm_argdict(args)
else:
return {}
# nothing for diamond
# LatticeiCE40Platform -----------------------------------------------------------------------------
class LatticeiCE40Platform(LatticePlatform):
device_family = "ice40"
# LatticeECP5Platform ------------------------------------------------------------------------------
class LatticeECP5Platform(LatticePlatform):
device_family = "ecp5"
# LatticeNexusPlatform -----------------------------------------------------------------------------
class LatticeNexusPlatform(LatticePlatform):
device_family = "nexus"

View File

@ -273,7 +273,7 @@ class LatticeRadiantToolchain(GenericToolchain):
def radiant_build_args(parser):
toolchain_group = parser.add_argument_group(title="Toolchain options")
toolchain_group = parser.add_argument_group(title="Radiant toolchain options")
toolchain_group.add_argument("--synth-mode", default="synplify", help="Synthesis mode (synplify or yosys).")
def radiant_build_argdict(args):

View File

@ -150,7 +150,7 @@ class LatticeTrellisToolchain(YosysNextPNRToolchain):
freq=str(float(1/period)*1000), clk="{clk}"), clk=clk)
def trellis_args(parser):
toolchain_group = parser.add_argument_group(title="Toolchain options")
toolchain_group = parser.add_argument_group(title="Trellis toolchain options")
yosys_nextpnr_args(toolchain_group)
toolchain_group.add_argument("--ecppack-bootaddr", default=0, help="Set boot address for next image.")
toolchain_group.add_argument("--ecppack-spimode", default=None, help="Set slave SPI programming mode.")

View File

@ -12,6 +12,8 @@ from litex.build.microsemi import common, libero_soc
class MicrosemiPlatform(GenericPlatform):
bitstream_ext = ".bit"
_supported_toolchains = ["libero_soc_polarfire"]
def __init__(self, *args, toolchain="libero_soc_polarfire", **kwargs):
GenericPlatform.__init__(self, *args, **kwargs)
if toolchain == "libero_soc_polarfire":

View File

@ -14,6 +14,8 @@ from litex.build.osfpga import common, osfpga
class OSFPGAPlatform(GenericPlatform):
bitstream_ext = ".bin"
_supported_toolchains = ["osfpga"]
def __init__(self, device, *args, toolchain="foedag", devicename=None, **kwargs):
GenericPlatform.__init__(self, device, *args, **kwargs)
self.devicename = devicename

View File

@ -14,6 +14,8 @@ from litex.build.quicklogic import common, f4pga
class QuickLogicPlatform(GenericPlatform):
bitstream_ext = ".bit"
_supported_toolchains = ["f4pga"]
def __init__(self, *args, toolchain="f4pga", **kwargs):
GenericPlatform.__init__(self, *args, **kwargs)
if toolchain == "symbiflow" or toolchain == "f4pga":

View File

@ -16,6 +16,9 @@ from litex.soc.interconnect.csr import AutoCSR, CSR, CSRStorage
class SimPlatform(GenericPlatform):
_supported_toolchains = ["verilator"]
def __init__(self, device, io, name="sim", toolchain="verilator", **kwargs):
if "sim_trace" not in (iface[0] for iface in io):
io.append(("sim_trace", 0, Pins(1)))

View File

@ -1,2 +1,2 @@
from litex.build.xilinx.platform import XilinxPlatform
from litex.build.xilinx.platform import XilinxPlatform, XilinxSpartan6Platform, Xilinx7SeriesPlatform
from litex.build.xilinx.programmer import UrJTAG, XC3SProg, FpgaProg, VivadoProgrammer, iMPACT, Adept

View File

@ -9,13 +9,18 @@
import os
from litex.build.generic_platform import GenericPlatform
from litex.build.xilinx import common
from litex.build.xilinx import common, vivado, ise, yosys_nextpnr
# XilinxPlatform -----------------------------------------------------------------------------------
class XilinxPlatform(GenericPlatform):
bitstream_ext = ".bit"
_supported_toolchains = {
"serie7": ["vivado", "f4pga", "yosys+nextpnr"],
"spartan6": ["ise"],
}
def __init__(self, *args, toolchain="ise", **kwargs):
GenericPlatform.__init__(self, *args, **kwargs)
self.edifs = set()
@ -84,3 +89,49 @@ class XilinxPlatform(GenericPlatform):
if hasattr(to, "p"):
to = to.p
self.toolchain.add_false_path_constraint(self, from_, to)
@classmethod
def fill_args(cls, toolchain, parser):
"""
pass parser to the specific toolchain to
fill this with toolchain args
Parameters
==========
toolchain: str
toolchain name
parser: argparse.ArgumentParser
parser to be filled
"""
if toolchain == "vivado":
vivado.vivado_build_args(parser)
@classmethod
def get_argdict(cls, toolchain, args):
"""
return a dict of args
Parameters
==========
toolchain: str
toolchain name
Return
======
a dict of key/value for each args or an empty dict
"""
if toolchain == "vivado":
return vivado.vivado_build_argdict(args)
else:
return dict()
# Xilinx7SeriesPlatform -----------------------------------------------------------------------------
class Xilinx7SeriesPlatform(XilinxPlatform):
device_family = "serie7"
# XilinxSpartan6Platform ---------------------------------------------------------------------------
class XilinxSpartan6Platform(XilinxPlatform):
device_family = "spartan6"