diff --git a/RELEASE_NOTES.rst b/RELEASE_NOTES.rst index 525455f53..f0291cf45 100644 --- a/RELEASE_NOTES.rst +++ b/RELEASE_NOTES.rst @@ -19,6 +19,8 @@ Release notes * The master now has a ``--name`` argument. If given, the dashboard is labelled with this name rather than the server address. * ``artiq_flash --adapter`` has been changed to ``artiq_flash --variant``. +* ``kc705_dds`` has been renamed ``kc705``. +* the ``-H/--hw-adapter`` option of ``kc705`` has ben renamed ``-V/--variant``. 3.2 diff --git a/artiq/build_soc.py b/artiq/build_soc.py new file mode 100644 index 000000000..ab2caf9ce --- /dev/null +++ b/artiq/build_soc.py @@ -0,0 +1,27 @@ +import os +import subprocess + +from misoc.integration.builder import * + +from artiq.gateware.amp import AMPSoC +from artiq import __artiq_dir__ as artiq_dir + + +def build_artiq_soc(soc, argdict): + firmware_dir = os.path.join(artiq_dir, "firmware") + builder = Builder(soc, **argdict) + builder.software_packages = [] + builder.add_software_package("bootloader", os.path.join(firmware_dir, "bootloader")) + if isinstance(soc, AMPSoC): + builder.add_software_package("libm") + builder.add_software_package("libprintf") + builder.add_software_package("libunwind") + builder.add_software_package("ksupport", os.path.join(firmware_dir, "ksupport")) + builder.add_software_package("runtime", os.path.join(firmware_dir, "runtime")) + else: + # Assume DRTIO satellite. + builder.add_software_package("satman", os.path.join(firmware_dir, "satman")) + try: + builder.build() + except subprocess.CalledProcessError as e: + raise SystemExit("Command {} failed".format(" ".join(e.cmd))) diff --git a/artiq/frontend/artiq_devtool.py b/artiq/frontend/artiq_devtool.py index 6fbf6dceb..d0283f61e 100755 --- a/artiq/frontend/artiq_devtool.py +++ b/artiq/frontend/artiq_devtool.py @@ -29,17 +29,16 @@ def get_argparser(): verbosity_args(parser) parser.add_argument("-t", "--target", metavar="TARGET", - type=str, default="kc705_dds", + type=str, default="kc705", help="target to build, one of: " - "kc705_dds kasli sayma_rtm sayma_amc_standalone " - "sayma_amc_drtio_master sayma_amc_drtio_satellite") + "kc705 kasli sayma_rtm sayma_amc") parser.add_argument("-g", "--build-gateware", default=False, action="store_true", help="build gateware, not just software") parser.add_argument("-H", "--host", type=str, default="lab.m-labs.hk", help="SSH host where the development board is located") - parser.add_argument('-b', "--board", + parser.add_argument("-b", "--board", type=str, default="{board_type}-1", help="board to connect to on the development SSH host") parser.add_argument("-B", "--board-file", @@ -73,15 +72,11 @@ def main(): return os.path.join("/tmp", target, *path) extra_build_args = [] - if args.target == "kc705_dds": + if args.target == "kc705": board_type, firmware = "kc705", "runtime" - elif args.target == "sayma_amc_standalone": + elif args.target == "sayma_amc": board_type, firmware = "sayma_amc", "runtime" extra_build_args += ["--rtm-csr-csv", build_dir("sayma_rtm_csr.csv", target="sayma_rtm")] - elif args.target == "sayma_amc_drtio_master": - board_type, firmware = "sayma_amc", "runtime" - elif args.target == "sayma_amc_drtio_satellite": - board_type, firmware = "sayma_amc", "satman" elif args.target == "sayma_rtm": board_type, firmware = "sayma_rtm", None else: diff --git a/artiq/frontend/artiq_flash.py b/artiq/frontend/artiq_flash.py index 3520357e6..7e1477af5 100755 --- a/artiq/frontend/artiq_flash.py +++ b/artiq/frontend/artiq_flash.py @@ -51,7 +51,7 @@ Prerequisites: parser.add_argument("-t", "--target", default="kc705", help="target board, default: %(default)s, one of: " "kc705 kasli sayma_amc sayma_rtm") - parser.add_argument("-m", "--variant", default=None, + parser.add_argument("-V", "--variant", default=None, help="board variant") parser.add_argument("-I", "--preinit-command", default=[], action="append", help="add a pre-initialization OpenOCD command. " diff --git a/artiq/gateware/amp/__init__.py b/artiq/gateware/amp/__init__.py index df70e9f90..6abb5b594 100644 --- a/artiq/gateware/amp/__init__.py +++ b/artiq/gateware/amp/__init__.py @@ -1 +1 @@ -from artiq.gateware.amp.soc import AMPSoC, build_artiq_soc +from artiq.gateware.amp.soc import AMPSoC diff --git a/artiq/gateware/amp/soc.py b/artiq/gateware/amp/soc.py index 1761fb72c..76d79807c 100644 --- a/artiq/gateware/amp/soc.py +++ b/artiq/gateware/amp/soc.py @@ -1,13 +1,8 @@ -import os -import subprocess - from misoc.cores import timer from misoc.interconnect import wishbone -from misoc.integration.builder import * from artiq.gateware.amp.kernel_cpu import KernelCPU from artiq.gateware.amp.mailbox import Mailbox -from artiq import __artiq_dir__ as artiq_dir class AMPSoC: @@ -42,19 +37,3 @@ class AMPSoC: self.add_csr_region(name, self.mem_map[name] | 0x80000000, 32, csrs) - - -def build_artiq_soc(soc, argdict): - firmware_dir = os.path.join(artiq_dir, "firmware") - builder = Builder(soc, **argdict) - builder.software_packages = [] - builder.add_software_package("libm") - builder.add_software_package("libprintf") - builder.add_software_package("libunwind") - builder.add_software_package("bootloader", os.path.join(firmware_dir, "bootloader")) - builder.add_software_package("ksupport", os.path.join(firmware_dir, "ksupport")) - builder.add_software_package("runtime", os.path.join(firmware_dir, "runtime")) - try: - builder.build() - except subprocess.CalledProcessError as e: - raise SystemExit("Command {} failed".format(" ".join(e.cmd))) diff --git a/artiq/gateware/targets/kasli.py b/artiq/gateware/targets/kasli.py index 5495bb582..79a718ed4 100755 --- a/artiq/gateware/targets/kasli.py +++ b/artiq/gateware/targets/kasli.py @@ -15,9 +15,10 @@ from misoc.targets.kasli import (MiniSoC, soc_kasli_args, soc_kasli_argdict) from misoc.integration.builder import builder_args, builder_argdict -from artiq.gateware.amp import AMPSoC, build_artiq_soc +from artiq.gateware.amp import AMPSoC from artiq.gateware import rtio from artiq.gateware.rtio.phy import ttl_simple, ttl_serdes_7series, spi +from artiq.build_soc import build_artiq_soc from artiq import __version__ as artiq_version @@ -186,8 +187,8 @@ def main(): description="ARTIQ device binary builder for Kasli systems") builder_args(parser) soc_kasli_args(parser) - parser.add_argument("--variant", default="opticlock", - help="extension variant setup: opticlock " + parser.add_argument("-V", "--variant", default="opticlock", + help="variant: opticlock " "(default: %(default)s)") args = parser.parse_args() diff --git a/artiq/gateware/targets/kc705_dds.py b/artiq/gateware/targets/kc705.py similarity index 79% rename from artiq/gateware/targets/kc705_dds.py rename to artiq/gateware/targets/kc705.py index 31baed85e..180a88245 100755 --- a/artiq/gateware/targets/kc705_dds.py +++ b/artiq/gateware/targets/kc705.py @@ -14,15 +14,16 @@ from misoc.cores import gpio from misoc.targets.kc705 import MiniSoC, soc_kc705_args, soc_kc705_argdict from misoc.integration.builder import builder_args, builder_argdict -from artiq.gateware.amp import AMPSoC, build_artiq_soc +from artiq.gateware.amp import AMPSoC from artiq.gateware import rtio, nist_clock, nist_qc2 from artiq.gateware.rtio.phy import (ttl_simple, ttl_serdes_7series, dds, spi, ad5360_monitor) +from artiq.build_soc import build_artiq_soc from artiq import __version__ as artiq_version class _RTIOCRG(Module, AutoCSR): - def __init__(self, platform, rtio_internal_clk): + def __init__(self, platform, rtio_internal_clk, use_sma=True): self._clock_sel = CSRStorage() self._pll_reset = CSRStorage(reset=1) self._pll_locked = CSRStatus() @@ -31,15 +32,17 @@ class _RTIOCRG(Module, AutoCSR): # 100 MHz when using 125MHz input self.clock_domains.cd_ext_clkout = ClockDomain(reset_less=True) - ext_clkout = platform.request("user_sma_gpio_p_33") - self.sync.ext_clkout += ext_clkout.eq(~ext_clkout) + if use_sma: + ext_clkout = platform.request("user_sma_gpio_p_33") + self.sync.ext_clkout += ext_clkout.eq(~ext_clkout) rtio_external_clk = Signal() - user_sma_clock = platform.request("user_sma_clock") - platform.add_period_constraint(user_sma_clock.p, 8.0) - self.specials += Instance("IBUFDS", - i_I=user_sma_clock.p, i_IB=user_sma_clock.n, - o_O=rtio_external_clk) + if use_sma: + user_sma_clock = platform.request("user_sma_clock") + platform.add_period_constraint(user_sma_clock.p, 8.0) + self.specials += Instance("IBUFDS", + i_I=user_sma_clock.p, i_IB=user_sma_clock.n, + o_O=rtio_external_clk) pll_locked = Signal() rtio_clk = Signal() @@ -201,7 +204,7 @@ _urukul = [ ] -class _NIST_Ions(MiniSoC, AMPSoC): +class _Standalone_Base(MiniSoC, AMPSoC): mem_map = { "cri_con": 0x10000000, "rtio": 0x20000000, @@ -273,12 +276,12 @@ class _NIST_Ions(MiniSoC, AMPSoC): self.csr_devices.append("rtio_analyzer") -class NIST_CLOCK(_NIST_Ions): +class NIST_CLOCK(_Standalone_Base): """ NIST clock hardware, with old backplane and 11 DDS channels """ def __init__(self, **kwargs): - _NIST_Ions.__init__(self, **kwargs) + _Standalone_Base.__init__(self, **kwargs) platform = self.platform platform.add_extension(nist_clock.fmc_adapter_io) @@ -374,13 +377,13 @@ class NIST_CLOCK(_NIST_Ions): self.add_rtio(rtio_channels) -class NIST_QC2(_NIST_Ions): +class NIST_QC2(_Standalone_Base): """ NIST QC2 hardware, as used in Quantum I and Quantum II, with new backplane and 24 DDS channels. Two backplanes are used. """ def __init__(self, **kwargs): - _NIST_Ions.__init__(self, **kwargs) + _Standalone_Base.__init__(self, **kwargs) platform = self.platform platform.add_extension(nist_qc2.fmc_adapter_io) @@ -444,25 +447,101 @@ class NIST_QC2(_NIST_Ions): self.add_rtio(rtio_channels) +_sma_spi = [ + ("sma_spi", 0, + Subsignal("clk", Pins("Y23")), # user_sma_gpio_p + Subsignal("cs_n", Pins("Y24")), # user_sma_gpio_n + Subsignal("mosi", Pins("L25")), # user_sma_clk_p + Subsignal("miso", Pins("K25")), # user_sma_clk_n + IOStandard("LVCMOS25")), +] + + +class SMA_SPI(_Standalone_Base): + """ + SPI on 4 SMA for PDQ2 test/demo. + """ + def __init__(self, **kwargs): + _Standalone_Base.__init__(self, **kwargs) + + platform = self.platform + self.platform.add_extension(_sma_spi) + + rtio_channels = [] + + phy = ttl_simple.Output(platform.request("user_led", 2)) + self.submodules += phy + rtio_channels.append(rtio.Channel.from_phy(phy)) + + ams101_dac = self.platform.request("ams101_dac", 0) + phy = ttl_simple.Output(ams101_dac.ldac) + self.submodules += phy + rtio_channels.append(rtio.Channel.from_phy(phy)) + + phy = spi.SPIMaster(ams101_dac) + self.submodules += phy + rtio_channels.append(rtio.Channel.from_phy( + phy, ififo_depth=4)) + + phy = spi.SPIMaster(self.platform.request("sma_spi")) + self.submodules += phy + rtio_channels.append(rtio.Channel.from_phy( + phy, ififo_depth=128)) + + self.config["HAS_RTIO_LOG"] = None + self.config["RTIO_LOG_CHANNEL"] = len(rtio_channels) + rtio_channels.append(rtio.LogChannel()) + + self.add_rtio(rtio_channels) + + def add_rtio(self, rtio_channels): + self.submodules.rtio_crg = _RTIOCRG(self.platform, self.crg.cd_sys.clk, + use_sma=False) + self.csr_devices.append("rtio_crg") + self.submodules.rtio_core = rtio.Core(rtio_channels) + self.csr_devices.append("rtio_core") + self.submodules.rtio = rtio.KernelInitiator() + self.submodules.rtio_dma = ClockDomainsRenamer("sys_kernel")( + rtio.DMA(self.get_native_sdram_if())) + self.register_kernel_cpu_csrdevice("rtio") + self.register_kernel_cpu_csrdevice("rtio_dma") + self.submodules.cri_con = rtio.CRIInterconnectShared( + [self.rtio.cri, self.rtio_dma.cri], + [self.rtio_core.cri]) + self.submodules.rtio_moninj = rtio.MonInj(rtio_channels) + self.csr_devices.append("rtio_moninj") + + self.rtio_crg.cd_rtio.clk.attr.add("keep") + self.platform.add_period_constraint(self.rtio_crg.cd_rtio.clk, 8.) + self.platform.add_false_path_constraints( + self.crg.cd_sys.clk, + self.rtio_crg.cd_rtio.clk) + + self.submodules.rtio_analyzer = rtio.Analyzer(self.rtio_core.cri, + self.get_native_sdram_if()) + self.csr_devices.append("rtio_analyzer") + + def main(): parser = argparse.ArgumentParser( - description="ARTIQ device binary builder / single-FPGA KC705-based " - "systems with AD9 DDS (NIST Ions hardware)") + description="KC705 gateware and firmware builder") builder_args(parser) soc_kc705_args(parser) - parser.add_argument("-H", "--hw-adapter", default="nist_clock", - help="hardware adapter type: " - "nist_clock/nist_qc2 " + parser.add_argument("-V", "--variant", default="nist_clock", + help="variant: " + "nist_clock/nist_qc2/sma_spi " "(default: %(default)s)") args = parser.parse_args() - hw_adapter = args.hw_adapter.lower() - if hw_adapter == "nist_clock": + variant = args.variant.lower() + if variant == "nist_clock": cls = NIST_CLOCK - elif hw_adapter == "nist_qc2": + elif variant == "nist_qc2": cls = NIST_QC2 + elif variant == "sma_spi": + cls = SMA_SPI else: - raise SystemExit("Invalid hardware adapter string (-H/--hw-adapter)") + raise SystemExit("Invalid variant (-V/--variant)") soc = cls(**soc_kc705_argdict(args)) build_artiq_soc(soc, builder_argdict(args)) diff --git a/artiq/gateware/targets/kc705_sma_spi.py b/artiq/gateware/targets/kc705_sma_spi.py deleted file mode 100755 index cd1a705e5..000000000 --- a/artiq/gateware/targets/kc705_sma_spi.py +++ /dev/null @@ -1,157 +0,0 @@ -#!/usr/bin/env python3 - -import argparse - -from migen import * - -from migen.build.generic_platform import * -from migen.genlib.resetsync import AsyncResetSynchronizer -from migen.genlib.cdc import MultiReg -from misoc.targets.kc705 import soc_kc705_args, soc_kc705_argdict -from misoc.integration.builder import builder_args, builder_argdict -from misoc.interconnect.csr import * - -from artiq.gateware.amp import build_artiq_soc -from artiq.gateware import rtio -from artiq.gateware.rtio.phy import ttl_simple, spi - - -from .kc705_dds import _NIST_Ions - - -class _RTIOCRG(Module, AutoCSR): - def __init__(self, platform, rtio_internal_clk): - self._clock_sel = CSRStorage() - self._pll_reset = CSRStorage(reset=1) - self._pll_locked = CSRStatus() - self.clock_domains.cd_rtio = ClockDomain() - self.clock_domains.cd_rtiox4 = ClockDomain(reset_less=True) - - # 10 MHz when using 125MHz input - self.clock_domains.cd_ext_clkout = ClockDomain(reset_less=True) - - rtio_external_clk = Signal() - - pll_locked = Signal() - rtio_clk = Signal() - rtiox4_clk = Signal() - ext_clkout_clk = Signal() - self.specials += [ - Instance("PLLE2_ADV", - p_STARTUP_WAIT="FALSE", o_LOCKED=pll_locked, - - p_REF_JITTER1=0.01, - p_CLKIN1_PERIOD=8.0, p_CLKIN2_PERIOD=8.0, - i_CLKIN1=rtio_internal_clk, i_CLKIN2=rtio_external_clk, - # Warning: CLKINSEL=0 means CLKIN2 is selected - i_CLKINSEL=~self._clock_sel.storage, - - # VCO @ 1GHz when using 125MHz input - p_CLKFBOUT_MULT=8, p_DIVCLK_DIVIDE=1, - i_CLKFBIN=self.cd_rtio.clk, - i_RST=self._pll_reset.storage, - - o_CLKFBOUT=rtio_clk, - - p_CLKOUT0_DIVIDE=2, p_CLKOUT0_PHASE=0.0, - o_CLKOUT0=rtiox4_clk, - - p_CLKOUT1_DIVIDE=50, p_CLKOUT1_PHASE=0.0, - o_CLKOUT1=ext_clkout_clk), - Instance("BUFG", i_I=rtio_clk, o_O=self.cd_rtio.clk), - Instance("BUFG", i_I=rtiox4_clk, o_O=self.cd_rtiox4.clk), - Instance("BUFG", i_I=ext_clkout_clk, o_O=self.cd_ext_clkout.clk), - - AsyncResetSynchronizer(self.cd_rtio, ~pll_locked), - MultiReg(pll_locked, self._pll_locked.status) - ] - - -_sma_spi = [ - ("sma_spi", 0, - Subsignal("clk", Pins("Y23")), # user_sma_gpio_p - Subsignal("cs_n", Pins("Y24")), # user_sma_gpio_n - Subsignal("mosi", Pins("L25")), # user_sma_clk_p - Subsignal("miso", Pins("K25")), # user_sma_clk_n - IOStandard("LVCMOS25")), -] - - -class SMA_SPI(_NIST_Ions): - """ - SPI on 4 SMA for PDQ2 test/demo. - """ - def __init__(self, **kwargs): - _NIST_Ions.__init__(self, **kwargs) - - platform = self.platform - self.platform.add_extension(_sma_spi) - - rtio_channels = [] - - phy = ttl_simple.Output(platform.request("user_led", 2)) - self.submodules += phy - rtio_channels.append(rtio.Channel.from_phy(phy)) - - ams101_dac = self.platform.request("ams101_dac", 0) - phy = ttl_simple.Output(ams101_dac.ldac) - self.submodules += phy - rtio_channels.append(rtio.Channel.from_phy(phy)) - - phy = spi.SPIMaster(ams101_dac) - self.submodules += phy - rtio_channels.append(rtio.Channel.from_phy( - phy, ififo_depth=4)) - - phy = spi.SPIMaster(self.platform.request("sma_spi")) - self.submodules += phy - rtio_channels.append(rtio.Channel.from_phy( - phy, ififo_depth=128)) - - self.config["HAS_RTIO_LOG"] = None - self.config["RTIO_LOG_CHANNEL"] = len(rtio_channels) - rtio_channels.append(rtio.LogChannel()) - - self.add_rtio(rtio_channels) - - def add_rtio(self, rtio_channels): - self.submodules.rtio_crg = _RTIOCRG(self.platform, self.crg.cd_sys.clk) - self.csr_devices.append("rtio_crg") - self.submodules.rtio_core = rtio.Core(rtio_channels) - self.csr_devices.append("rtio_core") - self.submodules.rtio = rtio.KernelInitiator() - self.submodules.rtio_dma = ClockDomainsRenamer("sys_kernel")( - rtio.DMA(self.get_native_sdram_if())) - self.register_kernel_cpu_csrdevice("rtio") - self.register_kernel_cpu_csrdevice("rtio_dma") - self.submodules.cri_con = rtio.CRIInterconnectShared( - [self.rtio.cri, self.rtio_dma.cri], - [self.rtio_core.cri]) - self.submodules.rtio_moninj = rtio.MonInj(rtio_channels) - self.csr_devices.append("rtio_moninj") - - self.rtio_crg.cd_rtio.clk.attr.add("keep") - self.platform.add_period_constraint(self.rtio_crg.cd_rtio.clk, 8.) - self.platform.add_false_path_constraints( - self.crg.cd_sys.clk, - self.rtio_crg.cd_rtio.clk) - - self.submodules.rtio_analyzer = rtio.Analyzer(self.rtio_core.cri, - self.get_native_sdram_if()) - self.csr_devices.append("rtio_analyzer") - - -def main(): - parser = argparse.ArgumentParser( - description="ARTIQ device binary builder / " - "KC705 SMA SPI demo/test for PDQ2") - builder_args(parser) - soc_kc705_args(parser) - args = parser.parse_args() - - soc = SMA_SPI(**soc_kc705_argdict(args)) - build_artiq_soc(soc, builder_argdict(args)) - - -if __name__ == "__main__": - main() diff --git a/artiq/gateware/targets/sayma_amc_standalone.py b/artiq/gateware/targets/sayma_amc.py similarity index 54% rename from artiq/gateware/targets/sayma_amc_standalone.py rename to artiq/gateware/targets/sayma_amc.py index 5ef866d0a..27692219a 100755 --- a/artiq/gateware/targets/sayma_amc_standalone.py +++ b/artiq/gateware/targets/sayma_amc.py @@ -3,6 +3,7 @@ import argparse import os from collections import namedtuple +import warnings from migen import * from migen.genlib.resetsync import AsyncResetSynchronizer @@ -23,11 +24,14 @@ from jesd204b.phy import JESD204BPhyTX from jesd204b.core import JESD204BCoreTX from jesd204b.core import JESD204BCoreTXControl -from artiq.gateware.amp import AMPSoC, build_artiq_soc +from artiq.gateware.amp import AMPSoC from artiq.gateware import serwb from artiq.gateware import remote_csr from artiq.gateware import rtio from artiq.gateware.rtio.phy import ttl_simple, sawg +from artiq.gateware.drtio.transceiver import gth_ultrascale +from artiq.gateware.drtio import DRTIOMaster, DRTIOSatellite +from artiq.build_soc import build_artiq_soc from artiq import __version__ as artiq_version @@ -129,7 +133,7 @@ class Standalone(MiniSoC, AMPSoC): } mem_map.update(MiniSoC.mem_map) - def __init__(self, with_sawg=False, **kwargs): + def __init__(self, with_sawg, **kwargs): MiniSoC.__init__(self, cpu_type="or1k", sdram_controller_type="minicon", @@ -248,33 +252,223 @@ class Standalone(MiniSoC, AMPSoC): self.csr_devices.append("rtio_analyzer") +class Master(MiniSoC, AMPSoC): + mem_map = { + "cri_con": 0x10000000, + "rtio": 0x20000000, + "rtio_dma": 0x30000000, + "drtio_aux": 0x50000000, + "mailbox": 0x70000000 + } + mem_map.update(MiniSoC.mem_map) + + def __init__(self, **kwargs): + MiniSoC.__init__(self, + cpu_type="or1k", + sdram_controller_type="minicon", + l2_size=128*1024, + ident=artiq_version, + ethmac_nrxslots=4, + ethmac_ntxslots=4, + **kwargs) + AMPSoC.__init__(self) + + platform = self.platform + rtio_clk_freq = 150e6 + + self.submodules += Microscope(platform.request("serial", 1), + self.clk_freq) + + # Si5324 used as a free-running oscillator, to avoid dependency on RTM. + self.submodules.si5324_rst_n = gpio.GPIOOut(platform.request("si5324").rst_n) + self.csr_devices.append("si5324_rst_n") + i2c = self.platform.request("i2c") + self.submodules.i2c = gpio.GPIOTristate([i2c.scl, i2c.sda]) + self.csr_devices.append("i2c") + self.config["I2C_BUS_COUNT"] = 1 + self.config["HAS_SI5324"] = None + self.config["SI5324_FREE_RUNNING"] = None + + self.comb += platform.request("sfp_tx_disable_n", 0).eq(1) + self.submodules.transceiver = gth_ultrascale.GTH( + clock_pads=platform.request("si5324_clkout"), + data_pads=[platform.request("sfp", 0)], + sys_clk_freq=self.clk_freq, + rtio_clk_freq=rtio_clk_freq) + + self.submodules.drtio0 = ClockDomainsRenamer({"rtio_rx": "rtio_rx0"})( + DRTIOMaster(self.transceiver.channels[0])) + self.csr_devices.append("drtio0") + self.add_wb_slave(self.mem_map["drtio_aux"], 0x800, + self.drtio0.aux_controller.bus) + self.add_memory_region("drtio0_aux", self.mem_map["drtio_aux"] | self.shadow_base, 0x800) + self.config["HAS_DRTIO"] = None + self.add_csr_group("drtio", ["drtio0"]) + self.add_memory_group("drtio_aux", ["drtio0_aux"]) + + rtio_clk_period = 1e9/rtio_clk_freq + for gth in self.transceiver.gths: + platform.add_period_constraint(gth.txoutclk, rtio_clk_period) + platform.add_period_constraint(gth.rxoutclk, rtio_clk_period) + platform.add_false_path_constraints( + self.crg.cd_sys.clk, + gth.txoutclk, gth.rxoutclk) + + rtio_channels = [] + for i in range(4): + phy = ttl_simple.Output(platform.request("user_led", i)) + self.submodules += phy + rtio_channels.append(rtio.Channel.from_phy(phy)) + sma_io = platform.request("sma_io", 0) + self.comb += sma_io.direction.eq(1) + phy = ttl_simple.Output(sma_io.level) + self.submodules += phy + rtio_channels.append(rtio.Channel.from_phy(phy)) + sma_io = platform.request("sma_io", 1) + self.comb += sma_io.direction.eq(0) + phy = ttl_simple.InOut(sma_io.level) + self.submodules += phy + rtio_channels.append(rtio.Channel.from_phy(phy)) + + self.submodules.rtio_moninj = rtio.MonInj(rtio_channels) + self.csr_devices.append("rtio_moninj") + + self.submodules.rtio_core = rtio.Core(rtio_channels, glbl_fine_ts_width=3) + self.csr_devices.append("rtio_core") + + self.submodules.rtio = rtio.KernelInitiator() + self.submodules.rtio_dma = ClockDomainsRenamer("sys_kernel")( + rtio.DMA(self.get_native_sdram_if())) + self.register_kernel_cpu_csrdevice("rtio") + self.register_kernel_cpu_csrdevice("rtio_dma") + self.submodules.cri_con = rtio.CRIInterconnectShared( + [self.rtio.cri, self.rtio_dma.cri], + [self.rtio_core.cri, self.drtio0.cri]) + self.register_kernel_cpu_csrdevice("cri_con") + + +class Satellite(BaseSoC): + mem_map = { + "drtio_aux": 0x50000000, + } + mem_map.update(BaseSoC.mem_map) + + def __init__(self, with_sawg, **kwargs): + BaseSoC.__init__(self, + cpu_type="or1k", + sdram_controller_type="minicon", + l2_size=128*1024, + ident=artiq_version, + **kwargs) + + if with_sawg: + warnings.warn("SAWG is not implemented yet with DRTIO, ignoring.") + + platform = self.platform + rtio_clk_freq = 150e6 + + self.submodules += Microscope(platform.request("serial", 1), + self.clk_freq) + + rtio_channels = [] + for i in range(4): + phy = ttl_simple.Output(platform.request("user_led", i)) + self.submodules += phy + rtio_channels.append(rtio.Channel.from_phy(phy)) + sma_io = platform.request("sma_io", 0) + self.comb += sma_io.direction.eq(1) + phy = ttl_simple.Output(sma_io.level) + self.submodules += phy + rtio_channels.append(rtio.Channel.from_phy(phy)) + sma_io = platform.request("sma_io", 1) + self.comb += sma_io.direction.eq(0) + phy = ttl_simple.InOut(sma_io.level) + self.submodules += phy + rtio_channels.append(rtio.Channel.from_phy(phy)) + + self.submodules.rtio_moninj = rtio.MonInj(rtio_channels) + self.csr_devices.append("rtio_moninj") + + self.comb += platform.request("sfp_tx_disable_n", 0).eq(1) + self.submodules.transceiver = gth_ultrascale.GTH( + clock_pads=platform.request("si5324_clkout"), + data_pads=[platform.request("sfp", 0)], + sys_clk_freq=self.clk_freq, + rtio_clk_freq=rtio_clk_freq) + rx0 = ClockDomainsRenamer({"rtio_rx": "rtio_rx0"}) + self.submodules.drtio0 = rx0(DRTIOSatellite( + self.transceiver.channels[0], rtio_channels)) + self.csr_devices.append("drtio0") + self.add_wb_slave(self.mem_map["drtio_aux"], 0x800, + self.drtio0.aux_controller.bus) + self.add_memory_region("drtio0_aux", self.mem_map["drtio_aux"] | self.shadow_base, 0x800) + self.config["HAS_DRTIO"] = None + self.add_csr_group("drtio", ["drtio0"]) + self.add_memory_group("drtio_aux", ["drtio0_aux"]) + + self.config["RTIO_FREQUENCY"] = str(rtio_clk_freq/1e6) + si5324_clkin = platform.request("si5324_clkin") + self.specials += \ + Instance("OBUFDS", + i_I=ClockSignal("rtio_rx0"), + o_O=si5324_clkin.p, o_OB=si5324_clkin.n + ) + self.submodules.si5324_rst_n = gpio.GPIOOut(platform.request("si5324").rst_n) + self.csr_devices.append("si5324_rst_n") + i2c = self.platform.request("i2c") + self.submodules.i2c = gpio.GPIOTristate([i2c.scl, i2c.sda]) + self.csr_devices.append("i2c") + self.config["I2C_BUS_COUNT"] = 1 + self.config["HAS_SI5324"] = None + + rtio_clk_period = 1e9/rtio_clk_freq + gth = self.transceiver.gths[0] + platform.add_period_constraint(gth.txoutclk, rtio_clk_period) + platform.add_period_constraint(gth.rxoutclk, rtio_clk_period) + platform.add_false_path_constraints( + self.crg.cd_sys.clk, + gth.txoutclk, gth.rxoutclk) + + def main(): parser = argparse.ArgumentParser( - description="ARTIQ device binary builder / Sayma AMC stand-alone") + description="Sayma AMC gateware and firmware builder") builder_args(parser) soc_sdram_args(parser) + parser.add_argument("-V", "--variant", default="standalone", + help="variant: " + "standalone/master/satellite " + "(default: %(default)s)") parser.add_argument("--rtm-csr-csv", default=os.path.join("artiq_sayma_rtm", "sayma_rtm_csr.csv"), help="CSV file listing remote CSRs on RTM (default: %(default)s)") - parser.add_argument("--with-sawg", + parser.add_argument("--without-sawg", default=False, action="store_true", - help="Add SAWG RTIO channels feeding the JESD links. If not " - "specified, fixed sawtooth generators are used. " - "(default: %(default)s)") + help="Remove SAWG RTIO channels feeding the JESD links (speeds up " + "compilation time). Replaces them with fixed sawtooth generators.") args = parser.parse_args() - soc = Standalone(with_sawg=args.with_sawg, **soc_sdram_argdict(args)) + variant = args.variant.lower() + if variant == "standalone": + cls = Standalone + elif variant == "master": + cls = Master + elif variant == "satellite": + cls = Satellite + soc = cls(with_sawg=not args.without_sawg, **soc_sdram_argdict(args)) - remote_csr_regions = remote_csr.get_remote_csr_regions( - soc.mem_map["serwb"] | soc.shadow_base, - args.rtm_csr_csv) - for name, origin, busword, csrs in remote_csr_regions: - soc.add_csr_region(name, origin, busword, csrs) - # Configuration for RTM peripherals. Keep in sync with sayma_rtm.py! - soc.config["HAS_HMC830_7043"] = None - soc.config["CONVERTER_SPI_HMC830_CS"] = 0 - soc.config["CONVERTER_SPI_HMC7043_CS"] = 1 - soc.config["CONVERTER_SPI_FIRST_AD9154_CS"] = 2 + # DRTIO variants do not use the RTM yet. + if variant not in {"master", "satellite"}: + remote_csr_regions = remote_csr.get_remote_csr_regions( + soc.mem_map["serwb"] | soc.shadow_base, + args.rtm_csr_csv) + for name, origin, busword, csrs in remote_csr_regions: + soc.add_csr_region(name, origin, busword, csrs) + # Configuration for RTM peripherals. Keep in sync with sayma_rtm.py! + soc.config["HAS_HMC830_7043"] = None + soc.config["CONVERTER_SPI_HMC830_CS"] = 0 + soc.config["CONVERTER_SPI_HMC7043_CS"] = 1 + soc.config["CONVERTER_SPI_FIRST_AD9154_CS"] = 2 build_artiq_soc(soc, builder_argdict(args)) diff --git a/artiq/gateware/targets/sayma_amc_drtio_master.py b/artiq/gateware/targets/sayma_amc_drtio_master.py deleted file mode 100755 index 9bbb8db31..000000000 --- a/artiq/gateware/targets/sayma_amc_drtio_master.py +++ /dev/null @@ -1,131 +0,0 @@ -#!/usr/bin/env python3 - -import argparse - -from migen import * -from migen.build.generic_platform import * - -from misoc.cores import spi as spi_csr -from misoc.cores import gpio -from misoc.integration.soc_sdram import soc_sdram_args, soc_sdram_argdict -from misoc.integration.builder import builder_args, builder_argdict -from misoc.targets.sayma_amc import MiniSoC - -from microscope import * - -from artiq.gateware.amp import AMPSoC, build_artiq_soc -from artiq.gateware import rtio -from artiq.gateware.rtio.phy import ttl_simple -from artiq.gateware.drtio.transceiver import gth_ultrascale -from artiq.gateware.drtio import DRTIOMaster -from artiq import __version__ as artiq_version - - -class Master(MiniSoC, AMPSoC): - mem_map = { - "cri_con": 0x10000000, - "rtio": 0x20000000, - "rtio_dma": 0x30000000, - "drtio_aux": 0x50000000, - "mailbox": 0x70000000 - } - mem_map.update(MiniSoC.mem_map) - - def __init__(self, **kwargs): - MiniSoC.__init__(self, - cpu_type="or1k", - sdram_controller_type="minicon", - l2_size=128*1024, - ident=artiq_version, - ethmac_nrxslots=4, - ethmac_ntxslots=4, - **kwargs) - AMPSoC.__init__(self) - - platform = self.platform - rtio_clk_freq = 150e6 - - self.submodules += Microscope(platform.request("serial", 1), - self.clk_freq) - - # Si5324 used as a free-running oscillator, to avoid dependency on RTM. - self.submodules.si5324_rst_n = gpio.GPIOOut(platform.request("si5324").rst_n) - self.csr_devices.append("si5324_rst_n") - i2c = self.platform.request("i2c") - self.submodules.i2c = gpio.GPIOTristate([i2c.scl, i2c.sda]) - self.csr_devices.append("i2c") - self.config["I2C_BUS_COUNT"] = 1 - self.config["HAS_SI5324"] = None - self.config["SI5324_FREE_RUNNING"] = None - - self.comb += platform.request("sfp_tx_disable_n", 0).eq(1) - self.submodules.transceiver = gth_ultrascale.GTH( - clock_pads=platform.request("si5324_clkout"), - data_pads=[platform.request("sfp", 0)], - sys_clk_freq=self.clk_freq, - rtio_clk_freq=rtio_clk_freq) - - self.submodules.drtio0 = ClockDomainsRenamer({"rtio_rx": "rtio_rx0"})( - DRTIOMaster(self.transceiver.channels[0])) - self.csr_devices.append("drtio0") - self.add_wb_slave(self.mem_map["drtio_aux"], 0x800, - self.drtio0.aux_controller.bus) - self.add_memory_region("drtio0_aux", self.mem_map["drtio_aux"] | self.shadow_base, 0x800) - self.config["HAS_DRTIO"] = None - self.add_csr_group("drtio", ["drtio0"]) - self.add_memory_group("drtio_aux", ["drtio0_aux"]) - - rtio_clk_period = 1e9/rtio_clk_freq - for gth in self.transceiver.gths: - platform.add_period_constraint(gth.txoutclk, rtio_clk_period) - platform.add_period_constraint(gth.rxoutclk, rtio_clk_period) - platform.add_false_path_constraints( - self.crg.cd_sys.clk, - gth.txoutclk, gth.rxoutclk) - - rtio_channels = [] - for i in range(4): - phy = ttl_simple.Output(platform.request("user_led", i)) - self.submodules += phy - rtio_channels.append(rtio.Channel.from_phy(phy)) - sma_io = platform.request("sma_io", 0) - self.comb += sma_io.direction.eq(1) - phy = ttl_simple.Output(sma_io.level) - self.submodules += phy - rtio_channels.append(rtio.Channel.from_phy(phy)) - sma_io = platform.request("sma_io", 1) - self.comb += sma_io.direction.eq(0) - phy = ttl_simple.InOut(sma_io.level) - self.submodules += phy - rtio_channels.append(rtio.Channel.from_phy(phy)) - - self.submodules.rtio_moninj = rtio.MonInj(rtio_channels) - self.csr_devices.append("rtio_moninj") - - self.submodules.rtio_core = rtio.Core(rtio_channels, glbl_fine_ts_width=3) - self.csr_devices.append("rtio_core") - - self.submodules.rtio = rtio.KernelInitiator() - self.submodules.rtio_dma = ClockDomainsRenamer("sys_kernel")( - rtio.DMA(self.get_native_sdram_if())) - self.register_kernel_cpu_csrdevice("rtio") - self.register_kernel_cpu_csrdevice("rtio_dma") - self.submodules.cri_con = rtio.CRIInterconnectShared( - [self.rtio.cri, self.rtio_dma.cri], - [self.rtio_core.cri, self.drtio0.cri]) - self.register_kernel_cpu_csrdevice("cri_con") - - -def main(): - parser = argparse.ArgumentParser( - description="ARTIQ device binary builder / Sayma DRTIO master") - builder_args(parser) - soc_sdram_args(parser) - args = parser.parse_args() - - soc = Master(**soc_sdram_argdict(args)) - build_artiq_soc(soc, builder_argdict(args)) - - -if __name__ == "__main__": - main() diff --git a/artiq/gateware/targets/sayma_amc_drtio_satellite.py b/artiq/gateware/targets/sayma_amc_drtio_satellite.py deleted file mode 100755 index 20526e54b..000000000 --- a/artiq/gateware/targets/sayma_amc_drtio_satellite.py +++ /dev/null @@ -1,121 +0,0 @@ -#!/usr/bin/env python3 - -import argparse -import os - -from migen import * -from migen.build.generic_platform import * -from misoc.cores import spi as spi_csr -from misoc.cores import gpio -from misoc.integration.soc_sdram import soc_sdram_args, soc_sdram_argdict -from misoc.integration.builder import * -from misoc.targets.sayma_amc import BaseSoC - -from microscope import * - -from artiq.gateware import rtio -from artiq.gateware.rtio.phy import ttl_simple -from artiq.gateware.drtio.transceiver import gth_ultrascale -from artiq.gateware.drtio import DRTIOSatellite -from artiq import __version__ as artiq_version -from artiq import __artiq_dir__ as artiq_dir - - -class Satellite(BaseSoC): - mem_map = { - "drtio_aux": 0x50000000, - } - mem_map.update(BaseSoC.mem_map) - - def __init__(self, **kwargs): - BaseSoC.__init__(self, - cpu_type="or1k", - sdram_controller_type="minicon", - l2_size=128*1024, - ident=artiq_version, - **kwargs) - - platform = self.platform - rtio_clk_freq = 150e6 - - self.submodules += Microscope(platform.request("serial", 1), - self.clk_freq) - - rtio_channels = [] - for i in range(4): - phy = ttl_simple.Output(platform.request("user_led", i)) - self.submodules += phy - rtio_channels.append(rtio.Channel.from_phy(phy)) - sma_io = platform.request("sma_io", 0) - self.comb += sma_io.direction.eq(1) - phy = ttl_simple.Output(sma_io.level) - self.submodules += phy - rtio_channels.append(rtio.Channel.from_phy(phy)) - sma_io = platform.request("sma_io", 1) - self.comb += sma_io.direction.eq(0) - phy = ttl_simple.InOut(sma_io.level) - self.submodules += phy - rtio_channels.append(rtio.Channel.from_phy(phy)) - - self.submodules.rtio_moninj = rtio.MonInj(rtio_channels) - self.csr_devices.append("rtio_moninj") - - self.comb += platform.request("sfp_tx_disable_n", 0).eq(1) - self.submodules.transceiver = gth_ultrascale.GTH( - clock_pads=platform.request("si5324_clkout"), - data_pads=[platform.request("sfp", 0)], - sys_clk_freq=self.clk_freq, - rtio_clk_freq=rtio_clk_freq) - rx0 = ClockDomainsRenamer({"rtio_rx": "rtio_rx0"}) - self.submodules.drtio0 = rx0(DRTIOSatellite( - self.transceiver.channels[0], rtio_channels)) - self.csr_devices.append("drtio0") - self.add_wb_slave(self.mem_map["drtio_aux"], 0x800, - self.drtio0.aux_controller.bus) - self.add_memory_region("drtio0_aux", self.mem_map["drtio_aux"] | self.shadow_base, 0x800) - self.config["HAS_DRTIO"] = None - self.add_csr_group("drtio", ["drtio0"]) - self.add_memory_group("drtio_aux", ["drtio0_aux"]) - - self.config["RTIO_FREQUENCY"] = str(rtio_clk_freq/1e6) - si5324_clkin = platform.request("si5324_clkin") - self.specials += \ - Instance("OBUFDS", - i_I=ClockSignal("rtio_rx0"), - o_O=si5324_clkin.p, o_OB=si5324_clkin.n - ) - self.submodules.si5324_rst_n = gpio.GPIOOut(platform.request("si5324").rst_n) - self.csr_devices.append("si5324_rst_n") - i2c = self.platform.request("i2c") - self.submodules.i2c = gpio.GPIOTristate([i2c.scl, i2c.sda]) - self.csr_devices.append("i2c") - self.config["I2C_BUS_COUNT"] = 1 - self.config["HAS_SI5324"] = None - - rtio_clk_period = 1e9/rtio_clk_freq - gth = self.transceiver.gths[0] - platform.add_period_constraint(gth.txoutclk, rtio_clk_period) - platform.add_period_constraint(gth.rxoutclk, rtio_clk_period) - platform.add_false_path_constraints( - self.crg.cd_sys.clk, - gth.txoutclk, gth.rxoutclk) - - -def main(): - parser = argparse.ArgumentParser( - description="ARTIQ device binary builder / Sayma DRTIO satellite") - builder_args(parser) - soc_sdram_args(parser) - args = parser.parse_args() - - soc = Satellite(**soc_sdram_argdict(args)) - firmware_dir = os.path.join(artiq_dir, "firmware") - builder = Builder(soc, **builder_argdict(args)) - builder.software_packages = [] - builder.add_software_package("bootloader", os.path.join(firmware_dir, "bootloader")) - builder.add_software_package("satman", os.path.join(firmware_dir, "satman")) - builder.build() - - -if __name__ == "__main__": - main() diff --git a/conda/artiq-kasli-opticlock/build.sh b/conda/artiq-kasli-opticlock/build.sh index fcf6dc5ee..c69d49191 100644 --- a/conda/artiq-kasli-opticlock/build.sh +++ b/conda/artiq-kasli-opticlock/build.sh @@ -3,7 +3,7 @@ SOC_PREFIX=$PREFIX/lib/python3.5/site-packages/artiq/binaries/kasli-opticlock mkdir -p $SOC_PREFIX -V=1 $PYTHON -m artiq.gateware.targets.kasli --variant opticlock +V=1 $PYTHON -m artiq.gateware.targets.kasli -V opticlock cp misoc_opticlock_kasli/gateware/top.bit $SOC_PREFIX cp misoc_opticlock_kasli/software/bootloader/bootloader.bin $SOC_PREFIX cp misoc_opticlock_kasli/software/runtime/runtime.{elf,fbi} $SOC_PREFIX diff --git a/conda/artiq-kc705-nist_clock/build.sh b/conda/artiq-kc705-nist_clock/build.sh index e81da80f7..dcad86304 100644 --- a/conda/artiq-kc705-nist_clock/build.sh +++ b/conda/artiq-kc705-nist_clock/build.sh @@ -3,7 +3,7 @@ SOC_PREFIX=$PREFIX/lib/python3.5/site-packages/artiq/binaries/kc705-nist_clock mkdir -p $SOC_PREFIX -V=1 $PYTHON -m artiq.gateware.targets.kc705_dds -H nist_clock +V=1 $PYTHON -m artiq.gateware.targets.kc705 -V nist_clock cp misoc_nist_clock_kc705/gateware/top.bit $SOC_PREFIX cp misoc_nist_clock_kc705/software/bootloader/bootloader.bin $SOC_PREFIX cp misoc_nist_clock_kc705/software/runtime/runtime.{elf,fbi} $SOC_PREFIX diff --git a/conda/artiq-kc705-nist_qc2/build.sh b/conda/artiq-kc705-nist_qc2/build.sh index a36df210d..4610d14f6 100644 --- a/conda/artiq-kc705-nist_qc2/build.sh +++ b/conda/artiq-kc705-nist_qc2/build.sh @@ -3,7 +3,7 @@ SOC_PREFIX=$PREFIX/lib/python3.5/site-packages/artiq/binaries/kc705-nist_qc2 mkdir -p $SOC_PREFIX -V=1 $PYTHON -m artiq.gateware.targets.kc705_dds -H nist_qc2 +V=1 $PYTHON -m artiq.gateware.targets.kc705 -V nist_qc2 cp misoc_nist_qc2_kc705/gateware/top.bit $SOC_PREFIX cp misoc_nist_qc2_kc705/software/bootloader/bootloader.bin $SOC_PREFIX cp misoc_nist_qc2_kc705/software/runtime/runtime.{elf,fbi} $SOC_PREFIX diff --git a/conda/artiq-sayma_amc-standalone/build.sh b/conda/artiq-sayma_amc-standalone/build.sh index 512e14ad0..918638a50 100644 --- a/conda/artiq-sayma_amc-standalone/build.sh +++ b/conda/artiq-sayma_amc-standalone/build.sh @@ -3,7 +3,7 @@ SOC_PREFIX=$PREFIX/lib/python3.5/site-packages/artiq/binaries/sayma_amc-standalone mkdir -p $SOC_PREFIX -V=1 $PYTHON -m artiq.gateware.targets.sayma_amc_standalone --rtm-csr-csv $SP_DIR/artiq/binaries/sayma_rtm/sayma_rtm_csr.csv +V=1 $PYTHON -m artiq.gateware.targets.sayma_amc -V standalone --rtm-csr-csv $SP_DIR/artiq/binaries/sayma_rtm/sayma_rtm_csr.csv cp misoc_standalone_sayma_amc/gateware/top.bit $SOC_PREFIX cp misoc_standalone_sayma_amc/software/bootloader/bootloader.bin $SOC_PREFIX cp misoc_standalone_sayma_amc/software/runtime/runtime.{elf,fbi} $SOC_PREFIX diff --git a/doc/manual/developing.rst b/doc/manual/developing.rst index 90b6f0849..1f60335d1 100644 --- a/doc/manual/developing.rst +++ b/doc/manual/developing.rst @@ -217,7 +217,7 @@ These steps are required to generate gateware bitstream (``.bit``) files, build * For KC705:: - $ python3 -m artiq.gateware.targets.kc705_dds -H nist_clock # or nist_qc2 + $ python3 -m artiq.gateware.targets.kc705 -V nist_clock # or nist_qc2 .. note:: Add ``--toolchain ise`` if you wish to use ISE instead of Vivado. ISE needs a separate installation step.