gateware: merge kasli_generic into kasli. Closes #2279

This commit is contained in:
Sebastien Bourdeauducq 2023-11-14 14:01:17 +08:00
parent de10e584f6
commit e81e8f28cf
4 changed files with 160 additions and 328 deletions

View File

@ -77,6 +77,9 @@ Accesses to the data argument should be replaced as below:
Refer to the updated ``no_hardware/arguments_demo.py`` example for current usage. Refer to the updated ``no_hardware/arguments_demo.py`` example for current usage.
* Almazny v1.2 is incompatible with the legacy versions and is the default. * Almazny v1.2 is incompatible with the legacy versions and is the default.
To use legacy versions, specify ``almazny_hw_rev`` in the JSON description. To use legacy versions, specify ``almazny_hw_rev`` in the JSON description.
* kasli_generic.py has been merged into kasli.py, and the demonstration designs without JSON descriptions
have been removed. The base classes remain present in kasli.py to support third-party flows without
JSON descriptions.
* Legacy PYON databases should be converted to LMDB with the script below: * Legacy PYON databases should be converted to LMDB with the script below:
:: ::

View File

@ -1,6 +1,8 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
import argparse import argparse
import logging
from packaging.version import Version
from migen import * from migen import *
from migen.genlib.resetsync import AsyncResetSynchronizer from migen.genlib.resetsync import AsyncResetSynchronizer
@ -14,16 +16,20 @@ from misoc.targets.kasli import (
BaseSoC, MiniSoC, soc_kasli_args, soc_kasli_argdict) BaseSoC, MiniSoC, soc_kasli_args, soc_kasli_argdict)
from misoc.integration.builder import builder_args, builder_argdict from misoc.integration.builder import builder_args, builder_argdict
from artiq import __version__ as artiq_version
from artiq.gateware.amp import AMPSoC from artiq.gateware.amp import AMPSoC
from artiq.gateware import rtio from artiq.gateware import rtio
from artiq.gateware.rtio.phy import ttl_simple, ttl_serdes_7series, edge_counter from artiq.gateware.rtio.phy import ttl_simple, ttl_serdes_7series, edge_counter
from artiq.gateware.rtio.xilinx_clocking import fix_serdes_timing_path from artiq.gateware.rtio.xilinx_clocking import fix_serdes_timing_path
from artiq.gateware import eem from artiq.gateware import rtio, eem, eem_7series
from artiq.gateware.drtio.transceiver import gtp_7series, eem_serdes from artiq.gateware.drtio.transceiver import gtp_7series, eem_serdes
from artiq.gateware.drtio.siphaser import SiPhaser7Series from artiq.gateware.drtio.siphaser import SiPhaser7Series
from artiq.gateware.drtio.rx_synchronizer import XilinxRXSynchronizer from artiq.gateware.drtio.rx_synchronizer import XilinxRXSynchronizer
from artiq.gateware.drtio import * from artiq.gateware.drtio import *
from artiq.build_soc import * from artiq.build_soc import *
from artiq.coredevice import jsondesc
logger = logging.getLogger(__name__)
class SMAClkinForward(Module): class SMAClkinForward(Module):
@ -130,89 +136,6 @@ class StandaloneBase(MiniSoC, AMPSoC):
self.csr_devices.append("rtio_analyzer") self.csr_devices.append("rtio_analyzer")
class Tester(StandaloneBase):
"""
Configuration for CI tests. Contains the maximum number of different EEMs.
"""
def __init__(self, hw_rev=None, dds=None, **kwargs):
if hw_rev is None:
hw_rev = "v2.0"
if dds is None:
dds = "ad9910"
StandaloneBase.__init__(self, hw_rev=hw_rev, **kwargs)
# self.config["SI5324_EXT_REF"] = None
self.config["RTIO_FREQUENCY"] = "125.0"
if hw_rev == "v1.0":
# EEM clock fan-out from Si5324, not MMCX
self.comb += self.platform.request("clk_sel").eq(1)
self.rtio_channels = []
eem.DIO.add_std(self, 5,
ttl_serdes_7series.InOut_8X, ttl_serdes_7series.Output_8X,
edge_counter_cls=edge_counter.SimpleEdgeCounter)
eem.Urukul.add_std(self, 0, 1, ttl_serdes_7series.Output_8X, dds,
ttl_simple.ClockGen)
eem.Sampler.add_std(self, 3, 2, ttl_serdes_7series.Output_8X)
eem.Zotino.add_std(self, 4, ttl_serdes_7series.Output_8X)
if hw_rev in ("v1.0", "v1.1"):
for i in (1, 2):
sfp_ctl = self.platform.request("sfp_ctl", i)
phy = ttl_simple.Output(sfp_ctl.led)
self.submodules += phy
self.rtio_channels.append(rtio.Channel.from_phy(phy))
self.config["HAS_RTIO_LOG"] = None
self.config["RTIO_LOG_CHANNEL"] = len(self.rtio_channels)
self.rtio_channels.append(rtio.LogChannel())
self.add_rtio(self.rtio_channels)
class SUServo(StandaloneBase):
"""
SUServo (Sampler-Urukul-Servo) extension variant configuration
"""
def __init__(self, hw_rev=None, **kwargs):
if hw_rev is None:
hw_rev = "v2.0"
StandaloneBase.__init__(self, hw_rev=hw_rev, **kwargs)
# self.config["SI5324_EXT_REF"] = None
self.config["RTIO_FREQUENCY"] = "125.0"
if hw_rev == "v1.0":
# EEM clock fan-out from Si5324, not MMCX
self.comb += self.platform.request("clk_sel").eq(1)
self.rtio_channels = []
# EEM0, EEM1: DIO
eem.DIO.add_std(self, 0,
ttl_serdes_7series.InOut_8X, ttl_serdes_7series.Output_8X)
eem.DIO.add_std(self, 1,
ttl_serdes_7series.Output_8X, ttl_serdes_7series.Output_8X)
# EEM3/2: Sampler, EEM5/4: Urukul, EEM7/6: Urukul
eem.SUServo.add_std(self,
eems_sampler=(3, 2),
eems_urukul=[[5, 4], [7, 6]])
for i in (1, 2):
sfp_ctl = self.platform.request("sfp_ctl", i)
phy = ttl_simple.Output(sfp_ctl.led)
self.submodules += phy
self.rtio_channels.append(rtio.Channel.from_phy(phy))
self.config["HAS_RTIO_LOG"] = None
self.config["RTIO_LOG_CHANNEL"] = len(self.rtio_channels)
self.rtio_channels.append(rtio.LogChannel())
self.add_rtio(self.rtio_channels)
pads = self.platform.lookup_request("sampler3_adc_data_p")
self.platform.add_false_path_constraints(
pads.clkout, self.crg.cd_sys.clk)
class MasterBase(MiniSoC, AMPSoC): class MasterBase(MiniSoC, AMPSoC):
mem_map = { mem_map = {
"cri_con": 0x10000000, "cri_con": 0x10000000,
@ -640,77 +563,184 @@ class SatelliteBase(BaseSoC, AMPSoC):
self.get_native_sdram_if(), cpu_dw=self.cpu_dw) self.get_native_sdram_if(), cpu_dw=self.cpu_dw)
self.csr_devices.append("rtio_analyzer") self.csr_devices.append("rtio_analyzer")
class GenericStandalone(StandaloneBase):
class Master(MasterBase): def __init__(self, description, hw_rev=None,**kwargs):
def __init__(self, hw_rev=None, **kwargs):
if hw_rev is None: if hw_rev is None:
hw_rev = "v2.0" hw_rev = description["hw_rev"]
MasterBase.__init__(self, hw_rev=hw_rev, **kwargs) self.class_name_override = description["variant"]
StandaloneBase.__init__(self, hw_rev=hw_rev, **kwargs)
self.config["RTIO_FREQUENCY"] = "{:.1f}".format(description["rtio_frequency"]/1e6)
if "ext_ref_frequency" in description:
self.config["SI5324_EXT_REF"] = None
self.config["EXT_REF_FREQUENCY"] = "{:.1f}".format(
description["ext_ref_frequency"]/1e6)
if hw_rev == "v1.0":
# EEM clock fan-out from Si5324, not MMCX
self.comb += self.platform.request("clk_sel").eq(1)
has_grabber = any(peripheral["type"] == "grabber" for peripheral in description["peripherals"])
if has_grabber:
self.grabber_csr_group = []
self.rtio_channels = [] self.rtio_channels = []
eem_7series.add_peripherals(self, description["peripherals"])
phy = ttl_simple.Output(self.platform.request("user_led", 0)) if hw_rev in ("v1.0", "v1.1"):
self.submodules += phy for i in (1, 2):
self.rtio_channels.append(rtio.Channel.from_phy(phy)) print("SFP LED at RTIO channel 0x{:06x}".format(len(self.rtio_channels)))
# matches Tester EEM numbers sfp_ctl = self.platform.request("sfp_ctl", i)
eem.DIO.add_std(self, 5, phy = ttl_simple.Output(sfp_ctl.led)
ttl_serdes_7series.InOut_8X, ttl_serdes_7series.Output_8X) self.submodules += phy
eem.Urukul.add_std(self, 0, 1, ttl_serdes_7series.Output_8X) self.rtio_channels.append(rtio.Channel.from_phy(phy))
if hw_rev in ("v1.1", "v2.0"):
for i in range(3):
print("USER LED at RTIO channel 0x{:06x}".format(len(self.rtio_channels)))
phy = ttl_simple.Output(self.platform.request("user_led", i))
self.submodules += phy
self.rtio_channels.append(rtio.Channel.from_phy(phy))
self.config["HAS_RTIO_LOG"] = None self.config["HAS_RTIO_LOG"] = None
self.config["RTIO_LOG_CHANNEL"] = len(self.rtio_channels) self.config["RTIO_LOG_CHANNEL"] = len(self.rtio_channels)
self.rtio_channels.append(rtio.LogChannel()) self.rtio_channels.append(rtio.LogChannel())
self.add_rtio(self.rtio_channels) self.add_rtio(self.rtio_channels, sed_lanes=description["sed_lanes"])
if has_grabber:
self.config["HAS_GRABBER"] = None
self.add_csr_group("grabber", self.grabber_csr_group)
for grabber in self.grabber_csr_group:
self.platform.add_false_path_constraints(
self.crg.cd_sys.clk, getattr(self, grabber).deserializer.cd_cl.clk)
class Satellite(SatelliteBase): class GenericMaster(MasterBase):
def __init__(self, hw_rev=None, **kwargs): def __init__(self, description, hw_rev=None, **kwargs):
if hw_rev is None: if hw_rev is None:
hw_rev = "v2.0" hw_rev = description["hw_rev"]
SatelliteBase.__init__(self, hw_rev=hw_rev, **kwargs) self.class_name_override = description["variant"]
has_drtio_over_eem = any(peripheral["type"] == "shuttler" for peripheral in description["peripherals"])
MasterBase.__init__(self,
hw_rev=hw_rev,
rtio_clk_freq=description["rtio_frequency"],
enable_sata=description["enable_sata_drtio"],
enable_sys5x=has_drtio_over_eem,
**kwargs)
if "ext_ref_frequency" in description:
self.config["SI5324_EXT_REF"] = None
self.config["EXT_REF_FREQUENCY"] = "{:.1f}".format(
description["ext_ref_frequency"]/1e6)
if hw_rev == "v1.0":
# EEM clock fan-out from Si5324, not MMCX
self.comb += self.platform.request("clk_sel").eq(1)
if has_drtio_over_eem:
self.eem_drtio_channels = []
has_grabber = any(peripheral["type"] == "grabber" for peripheral in description["peripherals"])
if has_grabber:
self.grabber_csr_group = []
self.rtio_channels = [] self.rtio_channels = []
phy = ttl_simple.Output(self.platform.request("user_led", 0)) eem_7series.add_peripherals(self, description["peripherals"])
self.submodules += phy if hw_rev in ("v1.1", "v2.0"):
self.rtio_channels.append(rtio.Channel.from_phy(phy)) for i in range(3):
# matches Tester EEM numbers print("USER LED at RTIO channel 0x{:06x}".format(len(self.rtio_channels)))
eem.DIO.add_std(self, 5, phy = ttl_simple.Output(self.platform.request("user_led", i))
ttl_serdes_7series.InOut_8X, ttl_serdes_7series.Output_8X) self.submodules += phy
self.rtio_channels.append(rtio.Channel.from_phy(phy))
self.add_rtio(self.rtio_channels) self.config["HAS_RTIO_LOG"] = None
self.config["RTIO_LOG_CHANNEL"] = len(self.rtio_channels)
self.rtio_channels.append(rtio.LogChannel())
if has_drtio_over_eem:
self.add_eem_drtio(self.eem_drtio_channels)
self.add_drtio_cpuif_groups()
self.add_rtio(self.rtio_channels, sed_lanes=description["sed_lanes"])
if has_grabber:
self.config["HAS_GRABBER"] = None
self.add_csr_group("grabber", self.grabber_csr_group)
for grabber in self.grabber_csr_group:
self.platform.add_false_path_constraints(
self.gt_drtio.gtps[0].txoutclk, getattr(self, grabber).deserializer.cd_cl.clk)
VARIANTS = {cls.__name__.lower(): cls for cls in [Tester, SUServo, Master, Satellite]} class GenericSatellite(SatelliteBase):
def __init__(self, description, hw_rev=None, **kwargs):
if hw_rev is None:
hw_rev = description["hw_rev"]
self.class_name_override = description["variant"]
SatelliteBase.__init__(self,
hw_rev=hw_rev,
rtio_clk_freq=description["rtio_frequency"],
enable_sata=description["enable_sata_drtio"],
**kwargs)
if hw_rev == "v1.0":
# EEM clock fan-out from Si5324, not MMCX
self.comb += self.platform.request("clk_sel").eq(1)
has_grabber = any(peripheral["type"] == "grabber" for peripheral in description["peripherals"])
if has_grabber:
self.grabber_csr_group = []
self.rtio_channels = []
eem_7series.add_peripherals(self, description["peripherals"])
if hw_rev in ("v1.1", "v2.0"):
for i in range(3):
print("USER LED at RTIO channel 0x{:06x}".format(len(self.rtio_channels)))
phy = ttl_simple.Output(self.platform.request("user_led", i))
self.submodules += phy
self.rtio_channels.append(rtio.Channel.from_phy(phy))
self.config["HAS_RTIO_LOG"] = None
self.config["RTIO_LOG_CHANNEL"] = len(self.rtio_channels)
self.rtio_channels.append(rtio.LogChannel())
self.add_rtio(self.rtio_channels, sed_lanes=description["sed_lanes"])
if has_grabber:
self.config["HAS_GRABBER"] = None
self.add_csr_group("grabber", self.grabber_csr_group)
for grabber in self.grabber_csr_group:
self.platform.add_false_path_constraints(
self.gt_drtio.gtps[0].txoutclk, getattr(self, grabber).deserializer.cd_cl.clk)
def main(): def main():
parser = argparse.ArgumentParser( parser = argparse.ArgumentParser(
description="ARTIQ device binary builder for Kasli systems") description="ARTIQ device binary builder for generic Kasli systems")
builder_args(parser) builder_args(parser)
soc_kasli_args(parser) soc_kasli_args(parser)
parser.set_defaults(output_dir="artiq_kasli") parser.set_defaults(output_dir="artiq_kasli")
parser.add_argument("-V", "--variant", default="tester", parser.add_argument("description", metavar="DESCRIPTION",
help="variant: {} (default: %(default)s)".format( help="JSON system description file")
"/".join(sorted(VARIANTS.keys()))))
parser.add_argument("--tester-dds", default=None,
help="Tester variant DDS type: ad9910/ad9912 "
"(default: ad9910)")
parser.add_argument("--gateware-identifier-str", default=None, parser.add_argument("--gateware-identifier-str", default=None,
help="Override ROM identifier") help="Override ROM identifier")
args = parser.parse_args() args = parser.parse_args()
description = jsondesc.load(args.description)
argdict = dict() min_artiq_version = description["min_artiq_version"]
argdict["gateware_identifier_str"] = args.gateware_identifier_str if Version(artiq_version) < Version(min_artiq_version):
argdict["dds"] = args.tester_dds logger.warning("ARTIQ version mismatch: current %s < %s minimum",
artiq_version, min_artiq_version)
variant = args.variant.lower() if description["target"] != "kasli":
try: raise ValueError("Description is for a different target")
cls = VARIANTS[variant]
except KeyError:
raise SystemExit("Invalid variant (-V/--variant)")
soc = cls(**soc_kasli_argdict(args), **argdict) if description["drtio_role"] == "standalone":
cls = GenericStandalone
elif description["drtio_role"] == "master":
cls = GenericMaster
elif description["drtio_role"] == "satellite":
cls = GenericSatellite
else:
raise ValueError("Invalid DRTIO role")
has_shuttler = any(peripheral["type"] == "shuttler" for peripheral in description["peripherals"])
if has_shuttler and (description["drtio_role"] == "standalone"):
raise ValueError("Shuttler requires DRTIO, please switch role to master")
soc = cls(description, gateware_identifier_str=args.gateware_identifier_str, **soc_kasli_argdict(args))
args.variant = description["variant"]
build_artiq_soc(soc, builder_argdict(args)) build_artiq_soc(soc, builder_argdict(args))

View File

@ -1,201 +0,0 @@
#!/usr/bin/env python3
import argparse
import logging
from packaging.version import Version
from misoc.integration.builder import builder_args, builder_argdict
from misoc.targets.kasli import soc_kasli_args, soc_kasli_argdict
from artiq import __version__ as artiq_version
from artiq.coredevice import jsondesc
from artiq.gateware import rtio, eem_7series
from artiq.gateware.rtio.phy import ttl_simple
from artiq.gateware.targets.kasli import StandaloneBase, MasterBase, SatelliteBase
from artiq.build_soc import *
logger = logging.getLogger(__name__)
class GenericStandalone(StandaloneBase):
def __init__(self, description, hw_rev=None,**kwargs):
if hw_rev is None:
hw_rev = description["hw_rev"]
self.class_name_override = description["variant"]
StandaloneBase.__init__(self, hw_rev=hw_rev, **kwargs)
self.config["RTIO_FREQUENCY"] = "{:.1f}".format(description["rtio_frequency"]/1e6)
if "ext_ref_frequency" in description:
self.config["SI5324_EXT_REF"] = None
self.config["EXT_REF_FREQUENCY"] = "{:.1f}".format(
description["ext_ref_frequency"]/1e6)
if hw_rev == "v1.0":
# EEM clock fan-out from Si5324, not MMCX
self.comb += self.platform.request("clk_sel").eq(1)
has_grabber = any(peripheral["type"] == "grabber" for peripheral in description["peripherals"])
if has_grabber:
self.grabber_csr_group = []
self.rtio_channels = []
eem_7series.add_peripherals(self, description["peripherals"])
if hw_rev in ("v1.0", "v1.1"):
for i in (1, 2):
print("SFP LED at RTIO channel 0x{:06x}".format(len(self.rtio_channels)))
sfp_ctl = self.platform.request("sfp_ctl", i)
phy = ttl_simple.Output(sfp_ctl.led)
self.submodules += phy
self.rtio_channels.append(rtio.Channel.from_phy(phy))
if hw_rev in ("v1.1", "v2.0"):
for i in range(3):
print("USER LED at RTIO channel 0x{:06x}".format(len(self.rtio_channels)))
phy = ttl_simple.Output(self.platform.request("user_led", i))
self.submodules += phy
self.rtio_channels.append(rtio.Channel.from_phy(phy))
self.config["HAS_RTIO_LOG"] = None
self.config["RTIO_LOG_CHANNEL"] = len(self.rtio_channels)
self.rtio_channels.append(rtio.LogChannel())
self.add_rtio(self.rtio_channels, sed_lanes=description["sed_lanes"])
if has_grabber:
self.config["HAS_GRABBER"] = None
self.add_csr_group("grabber", self.grabber_csr_group)
for grabber in self.grabber_csr_group:
self.platform.add_false_path_constraints(
self.crg.cd_sys.clk, getattr(self, grabber).deserializer.cd_cl.clk)
class GenericMaster(MasterBase):
def __init__(self, description, hw_rev=None, **kwargs):
if hw_rev is None:
hw_rev = description["hw_rev"]
self.class_name_override = description["variant"]
has_drtio_over_eem = any(peripheral["type"] == "shuttler" for peripheral in description["peripherals"])
MasterBase.__init__(self,
hw_rev=hw_rev,
rtio_clk_freq=description["rtio_frequency"],
enable_sata=description["enable_sata_drtio"],
enable_sys5x=has_drtio_over_eem,
**kwargs)
if "ext_ref_frequency" in description:
self.config["SI5324_EXT_REF"] = None
self.config["EXT_REF_FREQUENCY"] = "{:.1f}".format(
description["ext_ref_frequency"]/1e6)
if hw_rev == "v1.0":
# EEM clock fan-out from Si5324, not MMCX
self.comb += self.platform.request("clk_sel").eq(1)
if has_drtio_over_eem:
self.eem_drtio_channels = []
has_grabber = any(peripheral["type"] == "grabber" for peripheral in description["peripherals"])
if has_grabber:
self.grabber_csr_group = []
self.rtio_channels = []
eem_7series.add_peripherals(self, description["peripherals"])
if hw_rev in ("v1.1", "v2.0"):
for i in range(3):
print("USER LED at RTIO channel 0x{:06x}".format(len(self.rtio_channels)))
phy = ttl_simple.Output(self.platform.request("user_led", i))
self.submodules += phy
self.rtio_channels.append(rtio.Channel.from_phy(phy))
self.config["HAS_RTIO_LOG"] = None
self.config["RTIO_LOG_CHANNEL"] = len(self.rtio_channels)
self.rtio_channels.append(rtio.LogChannel())
if has_drtio_over_eem:
self.add_eem_drtio(self.eem_drtio_channels)
self.add_drtio_cpuif_groups()
self.add_rtio(self.rtio_channels, sed_lanes=description["sed_lanes"])
if has_grabber:
self.config["HAS_GRABBER"] = None
self.add_csr_group("grabber", self.grabber_csr_group)
for grabber in self.grabber_csr_group:
self.platform.add_false_path_constraints(
self.gt_drtio.gtps[0].txoutclk, getattr(self, grabber).deserializer.cd_cl.clk)
class GenericSatellite(SatelliteBase):
def __init__(self, description, hw_rev=None, **kwargs):
if hw_rev is None:
hw_rev = description["hw_rev"]
self.class_name_override = description["variant"]
SatelliteBase.__init__(self,
hw_rev=hw_rev,
rtio_clk_freq=description["rtio_frequency"],
enable_sata=description["enable_sata_drtio"],
**kwargs)
if hw_rev == "v1.0":
# EEM clock fan-out from Si5324, not MMCX
self.comb += self.platform.request("clk_sel").eq(1)
has_grabber = any(peripheral["type"] == "grabber" for peripheral in description["peripherals"])
if has_grabber:
self.grabber_csr_group = []
self.rtio_channels = []
eem_7series.add_peripherals(self, description["peripherals"])
if hw_rev in ("v1.1", "v2.0"):
for i in range(3):
print("USER LED at RTIO channel 0x{:06x}".format(len(self.rtio_channels)))
phy = ttl_simple.Output(self.platform.request("user_led", i))
self.submodules += phy
self.rtio_channels.append(rtio.Channel.from_phy(phy))
self.config["HAS_RTIO_LOG"] = None
self.config["RTIO_LOG_CHANNEL"] = len(self.rtio_channels)
self.rtio_channels.append(rtio.LogChannel())
self.add_rtio(self.rtio_channels, sed_lanes=description["sed_lanes"])
if has_grabber:
self.config["HAS_GRABBER"] = None
self.add_csr_group("grabber", self.grabber_csr_group)
for grabber in self.grabber_csr_group:
self.platform.add_false_path_constraints(
self.gt_drtio.gtps[0].txoutclk, getattr(self, grabber).deserializer.cd_cl.clk)
def main():
parser = argparse.ArgumentParser(
description="ARTIQ device binary builder for generic Kasli systems")
builder_args(parser)
soc_kasli_args(parser)
parser.set_defaults(output_dir="artiq_kasli")
parser.add_argument("description", metavar="DESCRIPTION",
help="JSON system description file")
parser.add_argument("--gateware-identifier-str", default=None,
help="Override ROM identifier")
args = parser.parse_args()
description = jsondesc.load(args.description)
min_artiq_version = description["min_artiq_version"]
if Version(artiq_version) < Version(min_artiq_version):
logger.warning("ARTIQ version mismatch: current %s < %s minimum",
artiq_version, min_artiq_version)
if description["target"] != "kasli":
raise ValueError("Description is for a different target")
if description["drtio_role"] == "standalone":
cls = GenericStandalone
elif description["drtio_role"] == "master":
cls = GenericMaster
elif description["drtio_role"] == "satellite":
cls = GenericSatellite
else:
raise ValueError("Invalid DRTIO role")
has_shuttler = any(peripheral["type"] == "shuttler" for peripheral in description["peripherals"])
if has_shuttler and (description["drtio_role"] == "standalone"):
raise ValueError("Shuttler requires DRTIO, please switch role to master")
soc = cls(description, gateware_identifier_str=args.gateware_identifier_str, **soc_kasli_argdict(args))
args.variant = description["variant"]
build_artiq_soc(soc, builder_argdict(args))
if __name__ == "__main__":
main()

View File

@ -16,7 +16,7 @@ ARTIQ itself does not depend on Nix, and it is also possible to compile everythi
* Enable flakes in Nix by e.g. adding ``experimental-features = nix-command flakes`` to ``nix.conf`` (for example ``~/.config/nix/nix.conf``). * Enable flakes in Nix by e.g. adding ``experimental-features = nix-command flakes`` to ``nix.conf`` (for example ``~/.config/nix/nix.conf``).
* Clone the ARTIQ Git repository and run ``nix develop`` at the root (where ``flake.nix`` is). * Clone the ARTIQ Git repository and run ``nix develop`` at the root (where ``flake.nix`` is).
* Make the current source code of ARTIQ available to the Python interpreter by running ``export PYTHONPATH=`pwd`:$PYTHONPATH``. * Make the current source code of ARTIQ available to the Python interpreter by running ``export PYTHONPATH=`pwd`:$PYTHONPATH``.
* You can then build the firmware and gateware with a command such as ``$ python -m artiq.gateware.targets.kasli``. If you are using a JSON system description file, use ``$ python -m artiq.gateware.targets.kasli_generic file.json``. * You can then build the firmware and gateware with a command such as ``$ python -m artiq.gateware.targets.kasli file.json``.
* Flash the binaries into the FPGA board with a command such as ``$ artiq_flash --srcbuild -d artiq_kasli/<your_variant>``. You need to configure OpenOCD as explained :ref:`in the user section <configuring-openocd>`. OpenOCD is already part of the flake's development environment. * Flash the binaries into the FPGA board with a command such as ``$ artiq_flash --srcbuild -d artiq_kasli/<your_variant>``. You need to configure OpenOCD as explained :ref:`in the user section <configuring-openocd>`. OpenOCD is already part of the flake's development environment.
* Check that the board boots and examine the UART messages by running a serial terminal program, e.g. ``$ flterm /dev/ttyUSB1`` (``flterm`` is part of MiSoC and installed in the flake's development environment). Leave the terminal running while you are flashing the board, so that you see the startup messages when the board boots immediately after flashing. You can also restart the board (without reflashing it) with ``$ artiq_flash start``. * Check that the board boots and examine the UART messages by running a serial terminal program, e.g. ``$ flterm /dev/ttyUSB1`` (``flterm`` is part of MiSoC and installed in the flake's development environment). Leave the terminal running while you are flashing the board, so that you see the startup messages when the board boots immediately after flashing. You can also restart the board (without reflashing it) with ``$ artiq_flash start``.
* The communication parameters are 115200 8-N-1. Ensure that your user has access to the serial device (e.g. by adding the user account to the ``dialout`` group). * The communication parameters are 115200 8-N-1. Ensure that your user has access to the serial device (e.g. by adding the user account to the ``dialout`` group).