forked from M-Labs/artiq
Merge branch 'master' into ppp2
* master:
add release notes/process
targets/kc705: fix e664fe3
targets/kc705: fix DDS_RTIO_CLK_RATIO for AD9914. Closes #238
transforms.inferencer: give a suggestion on "raise Exception".
pdq2/mediator: raise instances, not classes
pdq2: wire up more of the pipeline
doc: use actual version
Fix formatting.
doc: add artiq_flash
versioneer: remote tag_prefix = v
This commit is contained in:
commit
8cbb60b370
|
@ -0,0 +1,23 @@
|
|||
Release process
|
||||
===============
|
||||
|
||||
Maintain the release notes in this file with a list of new features and API changes in each major release.
|
||||
|
||||
Major releases:
|
||||
1. Create branch release-X from master.
|
||||
2. Remove any unfinished features.
|
||||
3. Test and fix any problems found.
|
||||
4. Tag X.0.
|
||||
|
||||
Minor (bugfix) releases:
|
||||
1. Backport bugfixes from the master branch or fix bugs specific to old releases into the currently maintained release-X branch(es).
|
||||
2. When significant bugs have been fixed, tag X.Y+1.
|
||||
3. To help dealing with regressions, no new features or refactorings should be implemented in release-X branches. Those happen in the master branch, and then a new release-X+1 branch is created.
|
||||
|
||||
|
||||
Release notes
|
||||
=============
|
||||
|
||||
1.0
|
||||
---
|
||||
* First release
|
|
@ -41,7 +41,7 @@ def get_config():
|
|||
cfg = VersioneerConfig()
|
||||
cfg.VCS = "git"
|
||||
cfg.style = "pep440"
|
||||
cfg.tag_prefix = "v"
|
||||
cfg.tag_prefix = ""
|
||||
cfg.parentdir_prefix = "artiq-"
|
||||
cfg.versionfile_source = "artiq/_version.py"
|
||||
cfg.verbose = False
|
||||
|
|
|
@ -1221,10 +1221,19 @@ class Inferencer(algorithm.Visitor):
|
|||
if node.exc is not None:
|
||||
exc_type = node.exc.type
|
||||
if not types.is_var(exc_type) and not builtins.is_exception(exc_type):
|
||||
if types.is_exn_constructor(exc_type):
|
||||
notes = [diagnostic.Diagnostic("note",
|
||||
"this value is an exception constructor; use {suggestion} instead",
|
||||
{"suggestion": node.exc.loc.source() + "()"},
|
||||
node.exc.loc)]
|
||||
else:
|
||||
notes = []
|
||||
|
||||
diag = diagnostic.Diagnostic("error",
|
||||
"cannot raise a value of type {type}, which is not an exception",
|
||||
{"type": types.TypePrinter().name(exc_type)},
|
||||
node.exc.loc)
|
||||
node.loc,
|
||||
notes=notes)
|
||||
self.engine.process(diag)
|
||||
|
||||
def visit_Assert(self, node):
|
||||
|
|
|
@ -193,6 +193,8 @@ class Pdq2:
|
|||
|
||||
def program_frame(self, frame_data):
|
||||
segments = [c.new_segment() for c in self.channels]
|
||||
for segment in segments:
|
||||
segment.line(typ=3, data=b"", trigger=True, duration=10, aux=1)
|
||||
for i, line in enumerate(frame_data): # segments are concatenated
|
||||
dac_divider = line.get("dac_divider", 1)
|
||||
shift = int(log(dac_divider, 2))
|
||||
|
@ -209,9 +211,11 @@ class Pdq2:
|
|||
shift=shift, duration=duration, trigger=trigger,
|
||||
**target_data)
|
||||
# append an empty line to stall the memory reader before jumping
|
||||
# through the frame table
|
||||
# through the frame table (`wait` does not prevent reading
|
||||
# the next line)
|
||||
for segment in segments:
|
||||
segment.line(typ=3, data=b"", trigger=True, duration=10)
|
||||
segment.line(typ=3, data=b"", trigger=True, duration=1,
|
||||
jump=True, aux=1)
|
||||
return segments
|
||||
|
||||
def program(self, program):
|
||||
|
|
|
@ -45,9 +45,9 @@ class _Segment:
|
|||
|
||||
def add_line(self, duration, channel_data, dac_divider=1):
|
||||
if self.frame.invalidated:
|
||||
raise InvalidatedError
|
||||
raise InvalidatedError()
|
||||
if self.frame.pdq.armed:
|
||||
raise ArmError
|
||||
raise ArmError()
|
||||
self.lines.append((dac_divider, duration, channel_data))
|
||||
|
||||
def get_duration(self):
|
||||
|
@ -59,13 +59,13 @@ class _Segment:
|
|||
@kernel
|
||||
def advance(self):
|
||||
if self.frame.invalidated:
|
||||
raise InvalidatedError
|
||||
raise InvalidatedError()
|
||||
if not self.frame.pdq.armed:
|
||||
raise ArmError
|
||||
raise ArmError()
|
||||
# If a frame is currently being played, check that we are next.
|
||||
if (self.frame.pdq.current_frame >= 0
|
||||
and self.frame.pdq.next_segment != self.segment_number):
|
||||
raise SegmentSequenceError
|
||||
raise SegmentSequenceError()
|
||||
self.frame.advance()
|
||||
|
||||
|
||||
|
@ -83,9 +83,9 @@ class _Frame:
|
|||
|
||||
def create_segment(self, name=None):
|
||||
if self.invalidated:
|
||||
raise InvalidatedError
|
||||
raise InvalidatedError()
|
||||
if self.pdq.armed:
|
||||
raise ArmError
|
||||
raise ArmError()
|
||||
segment = _Segment(self, self.segment_count)
|
||||
if name is not None:
|
||||
if hasattr(self, name):
|
||||
|
@ -111,6 +111,7 @@ class _Frame:
|
|||
"dac_divider": dac_divider,
|
||||
"duration": duration,
|
||||
"channel_data": channel_data,
|
||||
"trigger": False,
|
||||
} for dac_divider, duration, channel_data in segment.lines]
|
||||
segment_program[0]["trigger"] = True
|
||||
r += segment_program
|
||||
|
@ -119,17 +120,17 @@ class _Frame:
|
|||
@kernel
|
||||
def advance(self):
|
||||
if self.invalidated:
|
||||
raise InvalidatedError
|
||||
raise InvalidatedError()
|
||||
if not self.pdq.armed:
|
||||
raise ArmError
|
||||
raise ArmError()
|
||||
|
||||
call_t = now_mu()
|
||||
trigger_start_t = call_t - seconds_to_mu(trigger_duration/2)
|
||||
|
||||
if self.pdq.current_frame >= 0:
|
||||
# PDQ is in the middle of a frame. Check it is us.
|
||||
if self.frame.pdq.current_frame != self.frame_number:
|
||||
raise FrameActiveError
|
||||
if self.pdq.current_frame != self.frame_number:
|
||||
raise FrameActiveError()
|
||||
else:
|
||||
# PDQ is in the jump table - set the selection signals
|
||||
# to play our first segment.
|
||||
|
@ -156,7 +157,7 @@ class _Frame:
|
|||
class CompoundPDQ2:
|
||||
def __init__(self, dmgr, pdq2_devices, trigger_device, frame_devices):
|
||||
self.core = dmgr.get("core")
|
||||
self.pdq2s = [dmgr.get(d) for d in self.pdq2_devices]
|
||||
self.pdq2s = [dmgr.get(d) for d in pdq2_devices]
|
||||
self.trigger = dmgr.get(trigger_device)
|
||||
self.frame0 = dmgr.get(frame_devices[0])
|
||||
self.frame1 = dmgr.get(frame_devices[1])
|
||||
|
@ -175,7 +176,7 @@ class CompoundPDQ2:
|
|||
|
||||
def arm(self):
|
||||
if self.armed:
|
||||
raise ArmError
|
||||
raise ArmError()
|
||||
for frame in self.frames:
|
||||
frame._arm()
|
||||
self.armed = True
|
||||
|
@ -199,7 +200,7 @@ class CompoundPDQ2:
|
|||
|
||||
def create_frame(self):
|
||||
if self.armed:
|
||||
raise ArmError
|
||||
raise ArmError()
|
||||
r = _Frame(self, len(self.frames))
|
||||
self.frames.append(r)
|
||||
return r
|
||||
|
|
|
@ -10,7 +10,7 @@ import artiq
|
|||
from artiq.frontend.bit2bin import bit2bin
|
||||
|
||||
|
||||
def main():
|
||||
def get_argparser():
|
||||
parser = argparse.ArgumentParser(
|
||||
formatter_class=argparse.RawDescriptionHelpFormatter,
|
||||
description="ARTIQ flashing/deployment tool",
|
||||
|
@ -43,6 +43,11 @@ Prerequisites:
|
|||
parser.add_argument("ACTION", nargs="*",
|
||||
default="proxy bitstream bios runtime start".split(),
|
||||
help="actions to perform, default: %(default)s")
|
||||
return parser
|
||||
|
||||
|
||||
def main():
|
||||
parser = get_argparser()
|
||||
opts = parser.parse_args()
|
||||
|
||||
config = {
|
||||
|
|
|
@ -133,8 +133,6 @@ class _NIST_QCx(MiniSoC, AMPSoC):
|
|||
self.submodules.rtio_crg = _RTIOCRG(self.platform, self.crg.cd_sys.clk)
|
||||
self.submodules.rtio = rtio.RTIO(rtio_channels)
|
||||
self.config["RTIO_FINE_TS_WIDTH"] = self.rtio.fine_ts_width
|
||||
assert self.rtio.fine_ts_width <= 3
|
||||
self.config["DDS_RTIO_CLK_RATIO"] = 8 >> self.rtio.fine_ts_width
|
||||
self.submodules.rtio_moninj = rtio.MonInj(rtio_channels)
|
||||
|
||||
if isinstance(self.platform.toolchain, XilinxVivadoToolchain):
|
||||
|
@ -210,6 +208,8 @@ class NIST_QC1(_NIST_QCx):
|
|||
rtio_channels.append(rtio.LogChannel())
|
||||
|
||||
self.add_rtio(rtio_channels)
|
||||
assert self.rtio.fine_ts_width <= 3
|
||||
self.config["DDS_RTIO_CLK_RATIO"] = 8 >> self.rtio.fine_ts_width
|
||||
|
||||
|
||||
class NIST_QC2(_NIST_QCx):
|
||||
|
@ -259,6 +259,8 @@ class NIST_QC2(_NIST_QCx):
|
|||
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():
|
||||
|
|
|
@ -13,13 +13,13 @@ import sys, os, argparse, importlib
|
|||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(description=__doc__)
|
||||
parser.add_argument('-m', metavar='mod', type=str,
|
||||
help='run library module as a script')
|
||||
parser.add_argument('args', type=str, nargs='+',
|
||||
help='arguments passed to program in sys.argv[1:]')
|
||||
parser.add_argument("-m", metavar="mod", type=str,
|
||||
help="run library module as a script")
|
||||
parser.add_argument("args", type=str, nargs="+",
|
||||
help="arguments passed to program in sys.argv[1:]")
|
||||
args = parser.parse_args(sys.argv[1:])
|
||||
|
||||
artiq_path = os.path.abspath(os.path.join(os.path.dirname(__file__), '..'))
|
||||
artiq_path = os.path.abspath(os.path.join(os.path.dirname(__file__), ".."))
|
||||
sys.path.insert(1, artiq_path)
|
||||
|
||||
if args.m:
|
||||
|
@ -28,7 +28,7 @@ def main():
|
|||
else:
|
||||
sys.argv[1:] = args.args[1:]
|
||||
with open(args.args[0]) as f:
|
||||
code = compile(f.read(), args.args[0], 'exec')
|
||||
code = compile(f.read(), args.args[0], "exec")
|
||||
exec(code, globals())
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
# RUN: %python -m artiq.compiler.testbench.signature +diag %s >%t
|
||||
# RUN: OutputCheck %s --file-to-check=%t
|
||||
|
||||
# CHECK-L: ${LINE:+1}: note: this value is an exception constructor; use IndexError() instead
|
||||
raise IndexError
|
|
@ -143,14 +143,12 @@ class CoefficientSource:
|
|||
return build_segment(durations, coefficients, target=target,
|
||||
variable=variable)
|
||||
|
||||
def extend_segment(self, segment, trigger=True, *args, **kwargs):
|
||||
def extend_segment(self, segment, *args, **kwargs):
|
||||
"""Extend a wavesynth segment.
|
||||
|
||||
See `get_segment()` for arguments.
|
||||
"""
|
||||
for i, line in enumerate(self.get_segment_data(*args, **kwargs)):
|
||||
if i == 0:
|
||||
line["trigger"] = trigger
|
||||
segment.add_line(**line)
|
||||
|
||||
|
||||
|
|
|
@ -36,7 +36,9 @@ for module in mock_modules:
|
|||
# If extensions (or modules to document with autodoc) are in another directory,
|
||||
# add these directories to sys.path here. If the directory is relative to the
|
||||
# documentation root, use os.path.abspath to make it absolute, like shown here.
|
||||
#sys.path.insert(0, os.path.abspath('.'))
|
||||
sys.path.insert(0, os.path.abspath('..'))
|
||||
|
||||
from artiq._version import get_versions
|
||||
|
||||
# -- General configuration ------------------------------------------------
|
||||
|
||||
|
@ -73,9 +75,11 @@ copyright = '2014-2016, M-Labs Limited'
|
|||
# built documents.
|
||||
#
|
||||
# The short X.Y version.
|
||||
version = 'prerelease'
|
||||
# version = 'prerelease'
|
||||
# The full version, including alpha/beta/rc tags.
|
||||
release = 'prerelease'
|
||||
# release = 'prerelease'
|
||||
release = get_versions()['version']
|
||||
version = release.split('+', 1)[0]
|
||||
|
||||
# The language for content autogenerated by Sphinx. Refer to documentation
|
||||
# for a list of supported languages.
|
||||
|
@ -120,7 +124,7 @@ pygments_style = 'sphinx'
|
|||
|
||||
# The theme to use for HTML and HTML Help pages. See the documentation for
|
||||
# a list of builtin themes.
|
||||
html_theme = 'default'
|
||||
html_theme = 'classic'
|
||||
|
||||
# Theme options are theme-specific and customize the look and feel of a theme
|
||||
# further. For a list of options available for each theme, see the
|
||||
|
|
|
@ -1,6 +1,10 @@
|
|||
Utilities
|
||||
=========
|
||||
|
||||
.. Sort these tool by some subjective combination of their
|
||||
typical sequence and expected frequency of use.
|
||||
|
||||
|
||||
Local running tool
|
||||
------------------
|
||||
|
||||
|
@ -93,6 +97,13 @@ This tool compiles key/value pairs into a binary image suitable for flashing int
|
|||
:ref: artiq.frontend.artiq_mkfs.get_argparser
|
||||
:prog: artiq_mkfs
|
||||
|
||||
Flashing/Loading tool
|
||||
---------------------
|
||||
|
||||
.. argparse::
|
||||
:ref: artiq.frontend.artiq_flash.get_argparser
|
||||
:prog: artiq_flash
|
||||
|
||||
.. _core-device-configuration-tool:
|
||||
|
||||
Core device configuration tool
|
||||
|
|
|
@ -4,11 +4,11 @@ import numpy as np
|
|||
|
||||
from artiq import *
|
||||
|
||||
from artiq.wavesynth.coefficients import SplineSource
|
||||
|
||||
# data is usually precomputed offline
|
||||
transport_data = dict(
|
||||
t=np.linspace(0, 10, 101), # waveform time
|
||||
u=np.random.randn(101, 4*3*3), # waveform data,
|
||||
transport = SplineSource(
|
||||
x=np.linspace(0, 10, 101), # waveform time
|
||||
y=np.random.rand(4*3*3, 101)*1e-6, # waveform data,
|
||||
# 4 devices, 3 board each, 3 dacs each
|
||||
)
|
||||
|
||||
|
@ -16,37 +16,33 @@ class Transport(EnvExperiment):
|
|||
"""Transport"""
|
||||
|
||||
def build(self):
|
||||
self.setattr_device("core")
|
||||
self.setattr_device("bd")
|
||||
self.setattr_device("bdd")
|
||||
self.setattr_device("pmt")
|
||||
self.setattr_device("electrodes")
|
||||
self.core = self.get_device("core")
|
||||
self.bd_sw = self.get_device("bd_sw")
|
||||
self.pmt = self.get_device("pmt")
|
||||
self.electrodes = self.get_device("electrodes")
|
||||
|
||||
self.setattr_argument("wait_at_stop", NumberValue(100*us))
|
||||
self.setattr_argument("speed", NumberValue(1.5))
|
||||
self.setattr_argument("repeats", NumberValue(100))
|
||||
self.setattr_argument("nbins", NumberValue(100))
|
||||
self.wait_at_stop = self.get_argument("wait_at_stop",
|
||||
NumberValue(100*us))
|
||||
self.speed = self.get_argument("speed", NumberValue(1.5))
|
||||
self.repeats = self.get_argument("repeats", NumberValue(100))
|
||||
self.nbins = self.get_argument("nbins", NumberValue(100))
|
||||
|
||||
def calc_waveforms(self, stop):
|
||||
t = transport_data["t"][:stop]*self.speed
|
||||
u = transport_data["u"][:stop]
|
||||
|
||||
self.electrodes.disarm()
|
||||
self.tf = self.electrodes.create_frame()
|
||||
self.tf.create_segment(t, u, name="to_stop")
|
||||
to_stop = self.tf.create_segment("to_stop")
|
||||
from_stop = self.tf.create_segment("from_stop")
|
||||
transport.extend_segment(to_stop, 0, stop, scale=self.speed)
|
||||
# append the reverse transport (from stop to 0)
|
||||
# both durations are the same in this case
|
||||
self.tf.create_segment(t[-1] - t[::-1], u[::-1], name="from_stop")
|
||||
transport.extend_segment(from_stop, 0, stop, scale=self.speed)
|
||||
# distributes frames to the sub-devices in CompoundPDQ2
|
||||
# and uploads them
|
||||
self.electrodes.arm()
|
||||
|
||||
@kernel
|
||||
def cool(self):
|
||||
with parallel:
|
||||
self.bd.pulse(200*MHz, 1*ms)
|
||||
self.bdd.pulse(300*MHz, 1*ms)
|
||||
self.bd.pulse(210*MHz, 100*us)
|
||||
self.bd_sw.pulse(1*ms)
|
||||
|
||||
@kernel
|
||||
def transport(self):
|
||||
|
@ -65,10 +61,9 @@ class Transport(EnvExperiment):
|
|||
@kernel
|
||||
def detect(self):
|
||||
with parallel:
|
||||
self.bd.pulse(220*MHz, 100*us)
|
||||
self.bd_sw.pulse(100*us)
|
||||
self.pmt.gate_rising(100*us)
|
||||
self.bd.on(200*MHz)
|
||||
self.bdd.on(300*MHz)
|
||||
self.bd_sw.on()
|
||||
return self.pmt.count()
|
||||
|
||||
@kernel
|
||||
|
@ -79,7 +74,7 @@ class Transport(EnvExperiment):
|
|||
|
||||
@kernel
|
||||
def repeat(self):
|
||||
self.histogram = [0 for _ in range(self.nbins)]
|
||||
self.histogram[:] = [0 for _ in range(self.nbins)]
|
||||
|
||||
for i in range(self.repeats):
|
||||
n = self.one()
|
||||
|
@ -100,5 +95,5 @@ class Transport(EnvExperiment):
|
|||
|
||||
def run(self):
|
||||
# scan transport endpoint
|
||||
stops = range(10, len(transport_data["t"]), 10)
|
||||
stops = range(10, len(transport.x), 10)
|
||||
self.scan(stops)
|
||||
|
|
Loading…
Reference in New Issue