diff --git a/artiq/gateware/nist_clock.py b/artiq/gateware/nist_clock.py new file mode 100644 index 000000000..363a339b5 --- /dev/null +++ b/artiq/gateware/nist_clock.py @@ -0,0 +1,76 @@ +from migen.build.generic_platform import * + + +fmc_adapter_io = [ + ("ttl", 0, Pins("LPC:LA00_CC_N"), IOStandard("LVTTL")), + ("ttl", 1, Pins("LPC:LA02_P"), IOStandard("LVTTL")), + ("ttl", 2, Pins("LPC:LA00_CC_P"), IOStandard("LVTTL")), + ("ttl", 3, Pins("LPC:LA02_N"), IOStandard("LVTTL")), + ("ttl", 4, Pins("LPC:LA01_CC_N"), IOStandard("LVTTL")), + ("ttl", 5, Pins("LPC:LA06_P"), IOStandard("LVTTL")), + ("ttl", 6, Pins("LPC:LA06_N"), IOStandard("LVTTL")), + ("ttl", 7, Pins("LPC:LA27_P"), IOStandard("LVTTL")), + ("ttl", 8, Pins("LPC:LA10_P"), IOStandard("LVTTL")), + ("ttl", 9, Pins("LPC:LA05_N"), IOStandard("LVTTL")), + ("ttl", 10, Pins("LPC:LA05_P"), IOStandard("LVTTL")), + ("ttl", 11, Pins("LPC:LA09_P"), IOStandard("LVTTL")), + ("ttl", 12, Pins("LPC:LA09_N"), IOStandard("LVTTL")), + ("ttl", 13, Pins("LPC:LA13_P"), IOStandard("LVTTL")), + ("ttl", 14, Pins("LPC:LA14_P"), IOStandard("LVTTL")), + ("ttl", 15, Pins("LPC:LA10_N"), IOStandard("LVTTL")), + + ("pmt", 0, Pins("LPC:CLK0_M2C_P"), IOStandard("LVTTL")), + ("pmt", 1, Pins("LPC:CLK0_M2C_N"), IOStandard("LVTTL")), + + ("dds", 0, + Subsignal("a", Pins("LPC:LA22_N LPC:LA21_P LPC:LA22_P LPC:LA19_N " + "LPC:LA20_N LPC:LA19_P LPC:LA20_P")), + Subsignal("d", Pins("LPC:LA15_N LPC:LA16_N LPC:LA15_P LPC:LA16_P " + "LPC:LA11_N LPC:LA12_N LPC:LA11_P LPC:LA12_P " + "LPC:LA07_N LPC:LA08_N LPC:LA07_P LPC:LA08_P " + "LPC:LA04_N LPC:LA03_N LPC:LA04_P LPC:LA03_P")), + Subsignal("sel_n", Pins("LPC:LA24_N LPC:LA29_P LPC:LA28_P LPC:LA29_N " + "LPC:LA28_N LPC:LA31_P LPC:LA30_P LPC:LA31_N " + "LPC:LA30_N LPC:LA33_P LPC:LA33_N")), + Subsignal("fud", Pins("LPC:LA21_N")), + Subsignal("wr_n", Pins("LPC:LA24_P")), + Subsignal("rd_n", Pins("LPC:LA25_N")), + Subsignal("rst", Pins("LPC:LA25_P")), + IOStandard("LVTTL")), + + ("i2c", 0, + Subsignal("scl", Pins("LPC:IIC_SLC")), + Subsignal("sda", Pins("LPC:IIC_SDA")), + IOStandard("LVCMOS25")), + + ("clk_m2c", 1, + Subsignal("p", Pins("LPC:CLK1_M2C_P")), + Subsignal("n", Pins("LPC:CLK1_M2C_N")), + IOStandard("LVDS")), + + ("la32", 0, + Subsignal("p", Pins("LPC:LA32_P")), + Subsignal("n", Pins("LPC:LA32_N")), + IOStandard("LVDS")), + + ("spi", 0, + Subsignal("clk", Pins("LPC:LA13_N")), + Subsignal("ce", Pins("LPC:LA14_N")), + Subsignal("mosi", Pins("LPC:LA17_CC_P")), + Subsignal("miso", Pins("LPC:LA17_CC_N")), + IOStandard("LVTTL")), + + ("spi", 1, + Subsignal("clk", Pins("LPC:LA23_N")), + Subsignal("ce", Pins("LPC:LA23_P")), + Subsignal("mosi", Pins("LPC:LA18_CC_N")), + Subsignal("miso", Pins("LPC:LA18_CC_P")), + IOStandard("LVTTL")), + + ("spi", 2, + Subsignal("clk", Pins("LPC:LA27_P")), + Subsignal("ce", Pins("LPC:LA26_P")), + Subsignal("mosi", Pins("LPC:LA27_N")), + Subsignal("miso", Pins("LPC:LA26_N")), + IOStandard("LVTTL")), +] diff --git a/artiq/gateware/nist_qc2.py b/artiq/gateware/nist_qc2.py index 3235c9846..442d66ee6 100644 --- a/artiq/gateware/nist_qc2.py +++ b/artiq/gateware/nist_qc2.py @@ -18,6 +18,19 @@ fmc_adapter_io = [ ("ttl", 13, Pins("LPC:LA09_N"), IOStandard("LVTTL")), ("ttl", 14, Pins("LPC:LA13_P"), IOStandard("LVTTL")), ("ttl", 15, Pins("LPC:LA14_P"), IOStandard("LVTTL")), + ("ttl", 16, Pins("LPC:LA13_N"), IOStandard("LVTTL")), + ("ttl", 17, Pins("LPC:LA14_N"), IOStandard("LVTTL")), + ("ttl", 18, Pins("LPC:LA17_CC_P"), IOStandard("LVTTL")), + ("ttl", 19, Pins("LPC:LA17_CC_N"), IOStandard("LVTTL")), + ("ttl", 20, Pins("LPC:LA18_CC_P"), IOStandard("LVTTL")), + ("ttl", 21, Pins("LPC:LA18_CC_N"), IOStandard("LVTTL")), + ("ttl", 22, Pins("LPC:LA23_P"), IOStandard("LVTTL")), + ("ttl", 23, Pins("LPC:LA23_N"), IOStandard("LVTTL")), + ("ttl", 24, Pins("LPC:LA27_P"), IOStandard("LVTTL")), + ("ttl", 25, Pins("LPC:LA26_P"), IOStandard("LVTTL")), + ("ttl", 26, Pins("LPC:LA27_N"), IOStandard("LVTTL")), + ("ttl", 27, Pins("LPC:LA26_N"), IOStandard("LVTTL")), + ("dds", 0, Subsignal("a", Pins("LPC:LA22_N LPC:LA21_P LPC:LA22_P LPC:LA19_N " @@ -28,7 +41,7 @@ fmc_adapter_io = [ "LPC:LA04_N LPC:LA03_N LPC:LA04_P LPC:LA03_P")), Subsignal("sel_n", Pins("LPC:LA24_N LPC:LA29_P LPC:LA28_P LPC:LA29_N " "LPC:LA28_N LPC:LA31_P LPC:LA30_P LPC:LA31_N " - "LPC:LA30_N LPC:LA33_P LPC:LA33_N")), + "LPC:LA30_N LPC:LA33_P LPC:LA33_N LPC:LA32_P")), Subsignal("fud", Pins("LPC:LA21_N")), Subsignal("wr_n", Pins("LPC:LA24_P")), Subsignal("rd_n", Pins("LPC:LA25_N")), @@ -36,7 +49,7 @@ fmc_adapter_io = [ IOStandard("LVTTL")), ("i2c", 0, - Subsignal("scl", Pins("LPC:IIC_SLC")), + Subsignal("scl", Pins("LPC:IIC_SCL")), Subsignal("sda", Pins("LPC:IIC_SDA")), IOStandard("LVCMOS25")), @@ -50,29 +63,4 @@ fmc_adapter_io = [ Subsignal("n", Pins("LPC:CLK1_M2C_N")), IOStandard("LVDS")), - ("la32", 0, - Subsignal("p", Pins("LPC:LA32_P")), - Subsignal("n", Pins("LPC:LA32_N")), - IOStandard("LVDS")), - - ("spi", 0, - Subsignal("clk", Pins("LPC:LA13_N")), - Subsignal("ce", Pins("LPC:LA14_N")), - Subsignal("mosi", Pins("LPC:LA17_CC_P")), - Subsignal("miso", Pins("LPC:LA17_CC_N")), - IOStandard("LVTTL")), - - ("spi", 1, - Subsignal("clk", Pins("LPC:LA18_CC_P")), - Subsignal("ce", Pins("LPC:LA18_CC_N")), - Subsignal("mosi", Pins("LPC:LA23_P")), - Subsignal("miso", Pins("LPC:LA23_N")), - IOStandard("LVTTL")), - - ("spi", 2, - Subsignal("clk", Pins("LPC:LA27_P")), - Subsignal("ce", Pins("LPC:LA26_P")), - Subsignal("mosi", Pins("LPC:LA27_N")), - Subsignal("miso", Pins("LPC:LA26_N")), - IOStandard("LVTTL")), ] diff --git a/artiq/gateware/targets/kc705.py b/artiq/gateware/targets/kc705.py index 6cefef172..e288dde71 100755 --- a/artiq/gateware/targets/kc705.py +++ b/artiq/gateware/targets/kc705.py @@ -18,7 +18,7 @@ from misoc.integration.builder import * from misoc.targets.kc705 import MiniSoC, soc_kc705_args, soc_kc705_argdict from artiq.gateware.soc import AMPSoC -from artiq.gateware import rtio, nist_qc1, nist_qc2 +from artiq.gateware import rtio, nist_qc1, nist_clock, nist_qc2 from artiq.gateware.rtio.phy import ttl_simple, ttl_serdes_7series, dds from artiq.tools import artiq_dir from artiq import __version__ as artiq_version @@ -94,7 +94,7 @@ class _RTIOCRG(Module, AutoCSR): ] -class _NIST_QCx(MiniSoC, AMPSoC): +class _NIST_Ions(MiniSoC, AMPSoC): csr_map = { "rtio": None, # mapped on Wishbone instead "rtio_crg": 13, @@ -161,9 +161,13 @@ TIMESPEC "TSfix_cdc2" = FROM "GRPrio_clk" TO "GRPrsys_clk" TIG; self.get_native_sdram_if()) -class NIST_QC1(_NIST_QCx): +class NIST_QC1(_NIST_Ions): + """ + NIST QC1 hardware, as used in the Penning lab, with FMC to SCSI cables + adapter. + """ def __init__(self, cpu_type="or1k", **kwargs): - _NIST_QCx.__init__(self, cpu_type, **kwargs) + _NIST_Ions.__init__(self, cpu_type, **kwargs) platform = self.platform platform.add_extension(nist_qc1.fmc_adapter_io) @@ -212,18 +216,18 @@ class NIST_QC1(_NIST_QCx): self.config["DDS_RTIO_CLK_RATIO"] = 8 >> self.rtio.fine_ts_width -class NIST_QC2(_NIST_QCx): +class NIST_CLOCK(_NIST_Ions): + """ + NIST clock hardware, with old backplane and 11 DDS channels + """ def __init__(self, cpu_type="or1k", **kwargs): - _NIST_QCx.__init__(self, cpu_type, **kwargs) + _NIST_Ions.__init__(self, cpu_type, **kwargs) platform = self.platform - platform.add_extension(nist_qc2.fmc_adapter_io) + platform.add_extension(nist_clock.fmc_adapter_io) rtio_channels = [] for i in range(16): - if i == 14: - # TTL14 is for the clock generator - continue if i % 4 == 3: phy = ttl_serdes_7series.Inout_8X(platform.request("ttl", i)) self.submodules += phy @@ -233,18 +237,20 @@ class NIST_QC2(_NIST_QCx): self.submodules += phy rtio_channels.append(rtio.Channel.from_phy(phy)) + for i in range(2): + phy = ttl_serdes_7series.Inout_8X(platform.request("pmt", i)) + self.submodules += phy + rtio_channels.append(rtio.Channel.from_phy(phy, ififo_depth=512)) + phy = ttl_simple.Inout(platform.request("user_sma_gpio_n")) self.submodules += phy rtio_channels.append(rtio.Channel.from_phy(phy)) + phy = ttl_simple.Output(platform.request("user_led", 2)) self.submodules += phy rtio_channels.append(rtio.Channel.from_phy(phy)) self.config["RTIO_REGULAR_TTL_COUNT"] = len(rtio_channels) - phy = ttl_simple.ClockGen(platform.request("ttl", 14)) - self.submodules += phy - rtio_channels.append(rtio.Channel.from_phy(phy)) - self.config["RTIO_DDS_CHANNEL"] = len(rtio_channels) self.config["DDS_CHANNEL_COUNT"] = 11 self.config["DDS_AD9914"] = True @@ -263,25 +269,81 @@ class NIST_QC2(_NIST_QCx): self.config["DDS_RTIO_CLK_RATIO"] = 24 >> self.rtio.fine_ts_width +class NIST_QC2(_NIST_Ions): + """ + NIST QC2 hardware, as used in Quantum I and Quantum II, with new backplane + and 12 DDS channels. Current implementation for single backplane. + """ + def __init__(self, cpu_type="or1k", **kwargs): + _NIST_Ions.__init__(self, cpu_type, **kwargs) + + platform = self.platform + platform.add_extension(nist_qc2.fmc_adapter_io) + + rtio_channels = [] + # TTL0-23 are In+Out capable + for i in range(24): + phy = ttl_serdes_7series.Inout_8X(platform.request("ttl", i)) + self.submodules += phy + rtio_channels.append(rtio.Channel.from_phy(phy, ififo_depth=512)) + # TTL24-26 are output only + for i in range(24, 27): + phy = ttl_serdes_7series.Output_8X(platform.request("ttl", i)) + self.submodules += phy + rtio_channels.append(rtio.Channel.from_phy(phy)) + + phy = ttl_simple.Inout(platform.request("user_sma_gpio_n")) + self.submodules += phy + rtio_channels.append(rtio.Channel.from_phy(phy)) + phy = ttl_simple.Output(platform.request("user_led", 2)) + self.submodules += phy + rtio_channels.append(rtio.Channel.from_phy(phy)) + self.config["RTIO_REGULAR_TTL_COUNT"] = len(rtio_channels) + + # TTL27 is for the clock generator + phy = ttl_simple.ClockGen(platform.request("ttl", 27)) + self.submodules += phy + rtio_channels.append(rtio.Channel.from_phy(phy)) + + self.config["RTIO_DDS_CHANNEL"] = len(rtio_channels) + self.config["DDS_CHANNEL_COUNT"] = 12 + self.config["DDS_AD9914"] = True + self.config["DDS_ONEHOT_SEL"] = True + phy = dds.AD9914(platform.request("dds"), 12, onehot=True) + self.submodules += phy + rtio_channels.append(rtio.Channel.from_phy(phy, + ofifo_depth=512, + ififo_depth=4)) + + self.config["RTIO_LOG_CHANNEL"] = len(rtio_channels) + rtio_channels.append(rtio.LogChannel()) + + self.add_rtio(rtio_channels) + assert self.rtio.fine_ts_width <= 3 + self.config["DDS_RTIO_CLK_RATIO"] = 24 >> self.rtio.fine_ts_width + + def main(): parser = argparse.ArgumentParser( description="ARTIQ core device builder / KC705 " - "+ NIST Ions QC1/QC2 hardware adapters") + "+ NIST Ions QC1/CLOCK/QC2 hardware adapters") builder_args(parser) soc_kc705_args(parser) parser.add_argument("-H", "--hw-adapter", default="qc1", - help="hardware adapter type: qc1/qc2 " + help="hardware adapter type: qc1/clock/qc2 " "(default: %(default)s)") args = parser.parse_args() hw_adapter = args.hw_adapter.lower() if hw_adapter == "qc1": cls = NIST_QC1 + elif hw_adapter == "clock": + cls = NIST_CLOCK elif hw_adapter == "qc2": cls = NIST_QC2 else: print("Invalid hardware adapter string (-H/--hw-adapter), " - "choose from qc1 or qc2") + "choose from qc1, clock or qc2") sys.exit(1) soc = cls(**soc_kc705_argdict(args)) diff --git a/artiq/gui/log.py b/artiq/gui/log.py index a73a8c590..4e068f623 100644 --- a/artiq/gui/log.py +++ b/artiq/gui/log.py @@ -25,7 +25,7 @@ class Model(QtCore.QAbstractTableModel): def __init__(self, init): QtCore.QAbstractTableModel.__init__(self) - self.headers = ["Level", "Source", "Time", "Message"] + self.headers = ["Source", "Message"] self.entries = list(map(_make_wrappable, init)) self.pending_entries = [] @@ -85,7 +85,7 @@ class Model(QtCore.QAbstractTableModel): def data(self, index, role): if index.isValid(): if (role == QtCore.Qt.FontRole - and index.column() == 3): + and index.column() == 1): return self.fixed_font elif role == QtCore.Qt.BackgroundRole: level = self.entries[index.row()][0] @@ -105,13 +105,13 @@ class Model(QtCore.QAbstractTableModel): v = self.entries[index.row()] column = index.column() if column == 0: - return log_level_to_name(v[0]) - elif column == 1: return v[1] - elif column == 2: - return time.strftime("%m/%d %H:%M:%S", time.localtime(v[2])) else: return v[3] + elif role == QtCore.Qt.ToolTipRole: + v = self.entries[index.row()] + return (log_level_to_name(v[0]) + ", " + + time.strftime("%m/%d %H:%M:%S", time.localtime(v[2]))) class _LogFilterProxyModel(QSortFilterProxyModel): @@ -123,15 +123,11 @@ class _LogFilterProxyModel(QSortFilterProxyModel): def filterAcceptsRow(self, sourceRow, sourceParent): model = self.sourceModel() - index = model.index(sourceRow, 0, sourceParent) - data = model.data(index, QtCore.Qt.DisplayRole) - accepted_level = getattr(logging, data) >= self.min_level + accepted_level = model.entries[sourceRow][0] >= self.min_level if self.freetext: - index = model.index(sourceRow, 1, sourceParent) - data_source = model.data(index, QtCore.Qt.DisplayRole) - index = model.index(sourceRow, 3, sourceParent) - data_message = model.data(index, QtCore.Qt.DisplayRole) + data_source = model.entries[sourceRow][1] + data_message = model.entries[sourceRow][3] accepted_freetext = (self.freetext in data_source or self.freetext in data_message) else: diff --git a/artiq/master/experiments.py b/artiq/master/experiments.py index e1fe67ee8..0edce0976 100644 --- a/artiq/master/experiments.py +++ b/artiq/master/experiments.py @@ -6,7 +6,8 @@ import logging from functools import partial from artiq.protocols.sync_struct import Notifier -from artiq.master.worker import Worker +from artiq.master.worker import (Worker, WorkerInternalException, + log_worker_exception) from artiq.tools import get_windows_drives, exc_to_warning @@ -17,10 +18,13 @@ async def _get_repository_entries(entry_dict, root, filename, get_device_db, log): worker = Worker({ "get_device_db": get_device_db, - "log": partial(log, "scan") + "log": partial(log, "scan", os.path.basename(filename)) }) try: description = await worker.examine(os.path.join(root, filename)) + except: + log_worker_exception() + raise finally: await worker.close() for class_name, class_desc in description.items(): @@ -55,8 +59,9 @@ async def _scan_experiments(root, get_device_db, log, subdir=""): try: await _get_repository_entries( entry_dict, root, filename, get_device_db, log) - except: - logger.warning("Skipping file '%s'", filename, exc_info=True) + except Exception as exc: + logger.warning("Skipping file '%s'", filename, + exc_info=not isinstance(exc, WorkerInternalException)) if de.is_dir(): subentries = await _scan_experiments( root, get_device_db, log, @@ -119,7 +124,7 @@ class ExperimentDB: filename = os.path.join(wd, filename) worker = Worker({ "get_device_db": self.get_device_db_fn, - "log": partial(self.log_fn, "examine") + "log": partial(self.log_fn, "examine", os.path.basename(filename)) }) try: description = await worker.examine(filename) diff --git a/artiq/master/log.py b/artiq/master/log.py index ae87e015d..78def9d21 100644 --- a/artiq/master/log.py +++ b/artiq/master/log.py @@ -29,11 +29,11 @@ class LogBufferHandler(logging.Handler): part) -def log_worker(rid, message): +def log_worker(rid, filename, message): level, name, message = parse_log_message(message) log_with_name(name, level, message, - extra={"source": "worker({})".format(rid)}) -log_worker.worker_pass_rid = True + extra={"source": "worker({},{})".format(rid, filename)}) +log_worker.worker_pass_runinfo = True def log_args(parser): diff --git a/artiq/master/scheduler.py b/artiq/master/scheduler.py index 9d14dc2f4..2e375a344 100644 --- a/artiq/master/scheduler.py +++ b/artiq/master/scheduler.py @@ -3,7 +3,7 @@ import logging from enum import Enum from time import time -from artiq.master.worker import Worker +from artiq.master.worker import Worker, log_worker_exception from artiq.tools import asyncio_wait_or_cancel, TaskObject, Condition from artiq.protocols.sync_struct import Notifier @@ -231,7 +231,7 @@ class PrepareStage(TaskObject): except: logger.error("got worker exception in prepare stage, " "deleting RID %d", run.rid) - logger.error("worker exception details", exc_info=True) + log_worker_exception() self.delete_cb(run.rid) else: run.status = RunStatus.prepare_done @@ -281,7 +281,7 @@ class RunStage(TaskObject): except: logger.error("got worker exception in run stage, " "deleting RID %d", run.rid) - logger.error("worker exception details", exc_info=True) + log_worker_exception() self.delete_cb(run.rid) else: if completed: @@ -319,7 +319,7 @@ class AnalyzeStage(TaskObject): except: logger.error("got worker exception in analyze stage, " "deleting RID %d", run.rid) - logger.error("worker exception details", exc_info=True) + log_worker_exception() self.delete_cb(run.rid) else: self.delete_cb(run.rid) diff --git a/artiq/master/worker.py b/artiq/master/worker.py index db8a2ca64..16b782a54 100644 --- a/artiq/master/worker.py +++ b/artiq/master/worker.py @@ -1,4 +1,5 @@ import sys +import os import asyncio import logging import subprocess @@ -25,12 +26,27 @@ class WorkerError(Exception): pass +class WorkerInternalException(Exception): + """Exception raised inside the worker, information has been printed + through logging.""" + pass + + +def log_worker_exception(): + exc, _, _ = sys.exc_info() + if exc is WorkerInternalException: + logger.debug("worker exception details", exc_info=True) + else: + logger.error("worker exception details", exc_info=True) + + class Worker: def __init__(self, handlers=dict(), send_timeout=0.5): self.handlers = handlers self.send_timeout = send_timeout self.rid = None + self.filename = None self.process = None self.watchdogs = dict() # wid -> expiration (using time.monotonic) @@ -167,6 +183,8 @@ class Worker: return True elif action == "pause": return False + elif action == "exception": + raise WorkerInternalException elif action == "create_watchdog": func = self.create_watchdog elif action == "delete_watchdog": @@ -175,8 +193,8 @@ class Worker: func = self.register_experiment else: func = self.handlers[action] - if getattr(func, "worker_pass_rid", False): - func = partial(func, self.rid) + if getattr(func, "worker_pass_runinfo", False): + func = partial(func, self.rid, self.filename) try: data = func(*obj["args"], **obj["kwargs"]) reply = {"status": "ok", "data": data} @@ -211,6 +229,7 @@ class Worker: async def build(self, rid, pipeline_name, wd, expid, priority, timeout=15.0): self.rid = rid + self.filename = os.path.basename(expid["file"]) await self._create_process(expid["log_level"]) await self._worker_action( {"action": "build", diff --git a/artiq/master/worker_impl.py b/artiq/master/worker_impl.py index a7b1323d1..d8bf5cb82 100644 --- a/artiq/master/worker_impl.py +++ b/artiq/master/worker_impl.py @@ -264,15 +264,17 @@ def main(): put_object({"action": "completed"}) elif action == "terminate": break - except CompileError: - pass except Exception as exc: - lines = ["Terminating with exception\n"] - lines += traceback.format_exception_only(type(exc), exc) - if hasattr(exc, "parent_traceback"): - lines += exc.parent_traceback - logging.error("".join(lines).rstrip(), - exc_info=not hasattr(exc, "parent_traceback")) + # When we get CompileError, a more suitable diagnostic has already + # been printed. + if not isinstance(exc, CompileError): + lines = ["Terminating with exception\n"] + lines += traceback.format_exception_only(type(exc), exc) + if hasattr(exc, "parent_traceback"): + lines += exc.parent_traceback + logging.error("".join(lines).rstrip(), + exc_info=not hasattr(exc, "parent_traceback")) + put_object({"action": "exception"}) finally: device_mgr.close_devices() diff --git a/artiq/test/worker.py b/artiq/test/worker.py index c74b6f46a..bd69d03b8 100644 --- a/artiq/test/worker.py +++ b/artiq/test/worker.py @@ -87,7 +87,7 @@ class WorkerCase(unittest.TestCase): _run_experiment("SimpleExperiment") def test_exception(self): - with self.assertRaises(WorkerError): + with self.assertRaises(WorkerInternalException): _run_experiment("ExceptionTermination") def test_watchdog_no_timeout(self): diff --git a/conda/artiq-kc705-nist_clock/build.sh b/conda/artiq-kc705-nist_clock/build.sh new file mode 100644 index 000000000..cf93c2d37 --- /dev/null +++ b/conda/artiq-kc705-nist_clock/build.sh @@ -0,0 +1,14 @@ +#!/bin/bash + +BUILD_SETTINGS_FILE=$HOME/.m-labs/build_settings.sh +[ -f $BUILD_SETTINGS_FILE ] && . $BUILD_SETTINGS_FILE + +SOC_PREFIX=$PREFIX/lib/python3.5/site-packages/artiq/binaries/kc705-clock +mkdir -p $SOC_PREFIX + +$PYTHON -m artiq.gateware.targets.kc705 -H clock --toolchain vivado $MISOC_EXTRA_VIVADO_CMDLINE +cp misoc_nist_clock_kc705/gateware/top.bit $SOC_PREFIX +cp misoc_nist_clock_kc705/software/bios/bios.bin $SOC_PREFIX +cp misoc_nist_clock_kc705/software/runtime/runtime.fbi $SOC_PREFIX + +wget -P $SOC_PREFIX https://raw.githubusercontent.com/jordens/bscan_spi_bitstreams/master/bscan_spi_xc7k325t.bit diff --git a/conda/artiq-kc705-nist_clock/meta.yaml b/conda/artiq-kc705-nist_clock/meta.yaml new file mode 100644 index 000000000..5b3e1a600 --- /dev/null +++ b/conda/artiq-kc705-nist_clock/meta.yaml @@ -0,0 +1,27 @@ +package: + name: artiq-kc705-nist_clock + version: {{ environ.get("GIT_DESCRIBE_TAG", "") }} + +source: + path: ../.. + +build: + noarch_python: true + number: {{ environ.get("GIT_DESCRIBE_NUMBER", 0) }} + string: py_{{ environ.get("GIT_DESCRIBE_NUMBER", 0) }}+git{{ environ.get("GIT_DESCRIBE_HASH", "")[1:] }} + +requirements: + build: + # We don't get meaningful GIT_DESCRIBE_* values until before conda installs build dependencies. + - artiq 0.0 + - migen 0.2 + - misoc 0.1 + - llvm-or1k + - binutils-or1k-linux + run: + - artiq {{ "{tag} py_{number}+git{hash}".format(tag=environ.get("GIT_DESCRIBE_TAG"), number=environ.get("GIT_DESCRIBE_NUMBER"), hash=environ.get("GIT_DESCRIBE_HASH")[1:]) if "GIT_DESCRIBE_TAG" in environ else "" }} + +about: + home: http://m-labs.hk/artiq + license: GPL + summary: 'Bitstream, BIOS and runtime for NIST_QC2 on the KC705 board' diff --git a/doc/manual/core_device.rst b/doc/manual/core_device.rst index fe22dd296..3aca6b31f 100644 --- a/doc/manual/core_device.rst +++ b/doc/manual/core_device.rst @@ -27,7 +27,7 @@ FPGA board ports KC705 ----- -The main target board for the ARTIQ core device is the KC705 development board from Xilinx. It supports the NIST QC1 hardware via an adapter, and the NIST QC2 hardware (FMC). +The main target board for the ARTIQ core device is the KC705 development board from Xilinx. It supports the NIST QC1 hardware via an adapter, and the NIST CLOCK and QC2 hardware (FMC). With the QC1 hardware, the TTL lines are mapped as follows: @@ -47,6 +47,25 @@ With the QC1 hardware, the TTL lines are mapped as follows: | 19 | TTL15 | Clock | +--------------+------------+--------------+ +With the CLOCK hardware, the TTL lines are mapped as follows: + ++--------------------+-----------------------+--------------+ +| RTIO channel | TTL line | Capability | ++====================+=======================+==============+ +| 3,7,11,15 | TTL3,7,11,15 | Input+Output | ++--------------------+-----------------------+--------------+ +| 0-2,4-6,8-10,12-14 | TTL0-2,4-6,8-10,12-14 | Output | ++--------------------+-----------------------+--------------+ +| 16 | PMT0 | Input | ++--------------------+-----------------------+--------------+ +| 17 | PMT1 | Input | ++--------------------+-----------------------+--------------+ +| 18 | SMA_GPIO_N | Input+Output | ++--------------------+-----------------------+--------------+ +| 19 | LED | Output | ++--------------------+-----------------------+--------------+ + + Pipistrello -----------