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:
Robert Jördens 2016-01-20 19:29:00 -07:00
commit 8cbb60b370
14 changed files with 119 additions and 62 deletions

23
RELEASES Normal file
View File

@ -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

View File

@ -41,7 +41,7 @@ def get_config():
cfg = VersioneerConfig() cfg = VersioneerConfig()
cfg.VCS = "git" cfg.VCS = "git"
cfg.style = "pep440" cfg.style = "pep440"
cfg.tag_prefix = "v" cfg.tag_prefix = ""
cfg.parentdir_prefix = "artiq-" cfg.parentdir_prefix = "artiq-"
cfg.versionfile_source = "artiq/_version.py" cfg.versionfile_source = "artiq/_version.py"
cfg.verbose = False cfg.verbose = False

View File

@ -1221,10 +1221,19 @@ class Inferencer(algorithm.Visitor):
if node.exc is not None: if node.exc is not None:
exc_type = node.exc.type exc_type = node.exc.type
if not types.is_var(exc_type) and not builtins.is_exception(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", diag = diagnostic.Diagnostic("error",
"cannot raise a value of type {type}, which is not an exception", "cannot raise a value of type {type}, which is not an exception",
{"type": types.TypePrinter().name(exc_type)}, {"type": types.TypePrinter().name(exc_type)},
node.exc.loc) node.loc,
notes=notes)
self.engine.process(diag) self.engine.process(diag)
def visit_Assert(self, node): def visit_Assert(self, node):

View File

@ -193,6 +193,8 @@ class Pdq2:
def program_frame(self, frame_data): def program_frame(self, frame_data):
segments = [c.new_segment() for c in self.channels] 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 for i, line in enumerate(frame_data): # segments are concatenated
dac_divider = line.get("dac_divider", 1) dac_divider = line.get("dac_divider", 1)
shift = int(log(dac_divider, 2)) shift = int(log(dac_divider, 2))
@ -209,9 +211,11 @@ class Pdq2:
shift=shift, duration=duration, trigger=trigger, shift=shift, duration=duration, trigger=trigger,
**target_data) **target_data)
# append an empty line to stall the memory reader before jumping # 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: 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 return segments
def program(self, program): def program(self, program):

View File

@ -45,9 +45,9 @@ class _Segment:
def add_line(self, duration, channel_data, dac_divider=1): def add_line(self, duration, channel_data, dac_divider=1):
if self.frame.invalidated: if self.frame.invalidated:
raise InvalidatedError raise InvalidatedError()
if self.frame.pdq.armed: if self.frame.pdq.armed:
raise ArmError raise ArmError()
self.lines.append((dac_divider, duration, channel_data)) self.lines.append((dac_divider, duration, channel_data))
def get_duration(self): def get_duration(self):
@ -59,13 +59,13 @@ class _Segment:
@kernel @kernel
def advance(self): def advance(self):
if self.frame.invalidated: if self.frame.invalidated:
raise InvalidatedError raise InvalidatedError()
if not self.frame.pdq.armed: if not self.frame.pdq.armed:
raise ArmError raise ArmError()
# If a frame is currently being played, check that we are next. # If a frame is currently being played, check that we are next.
if (self.frame.pdq.current_frame >= 0 if (self.frame.pdq.current_frame >= 0
and self.frame.pdq.next_segment != self.segment_number): and self.frame.pdq.next_segment != self.segment_number):
raise SegmentSequenceError raise SegmentSequenceError()
self.frame.advance() self.frame.advance()
@ -83,9 +83,9 @@ class _Frame:
def create_segment(self, name=None): def create_segment(self, name=None):
if self.invalidated: if self.invalidated:
raise InvalidatedError raise InvalidatedError()
if self.pdq.armed: if self.pdq.armed:
raise ArmError raise ArmError()
segment = _Segment(self, self.segment_count) segment = _Segment(self, self.segment_count)
if name is not None: if name is not None:
if hasattr(self, name): if hasattr(self, name):
@ -111,6 +111,7 @@ class _Frame:
"dac_divider": dac_divider, "dac_divider": dac_divider,
"duration": duration, "duration": duration,
"channel_data": channel_data, "channel_data": channel_data,
"trigger": False,
} for dac_divider, duration, channel_data in segment.lines] } for dac_divider, duration, channel_data in segment.lines]
segment_program[0]["trigger"] = True segment_program[0]["trigger"] = True
r += segment_program r += segment_program
@ -119,17 +120,17 @@ class _Frame:
@kernel @kernel
def advance(self): def advance(self):
if self.invalidated: if self.invalidated:
raise InvalidatedError raise InvalidatedError()
if not self.pdq.armed: if not self.pdq.armed:
raise ArmError raise ArmError()
call_t = now_mu() call_t = now_mu()
trigger_start_t = call_t - seconds_to_mu(trigger_duration/2) trigger_start_t = call_t - seconds_to_mu(trigger_duration/2)
if self.pdq.current_frame >= 0: if self.pdq.current_frame >= 0:
# PDQ is in the middle of a frame. Check it is us. # PDQ is in the middle of a frame. Check it is us.
if self.frame.pdq.current_frame != self.frame_number: if self.pdq.current_frame != self.frame_number:
raise FrameActiveError raise FrameActiveError()
else: else:
# PDQ is in the jump table - set the selection signals # PDQ is in the jump table - set the selection signals
# to play our first segment. # to play our first segment.
@ -156,7 +157,7 @@ class _Frame:
class CompoundPDQ2: class CompoundPDQ2:
def __init__(self, dmgr, pdq2_devices, trigger_device, frame_devices): def __init__(self, dmgr, pdq2_devices, trigger_device, frame_devices):
self.core = dmgr.get("core") 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.trigger = dmgr.get(trigger_device)
self.frame0 = dmgr.get(frame_devices[0]) self.frame0 = dmgr.get(frame_devices[0])
self.frame1 = dmgr.get(frame_devices[1]) self.frame1 = dmgr.get(frame_devices[1])
@ -175,7 +176,7 @@ class CompoundPDQ2:
def arm(self): def arm(self):
if self.armed: if self.armed:
raise ArmError raise ArmError()
for frame in self.frames: for frame in self.frames:
frame._arm() frame._arm()
self.armed = True self.armed = True
@ -199,7 +200,7 @@ class CompoundPDQ2:
def create_frame(self): def create_frame(self):
if self.armed: if self.armed:
raise ArmError raise ArmError()
r = _Frame(self, len(self.frames)) r = _Frame(self, len(self.frames))
self.frames.append(r) self.frames.append(r)
return r return r

View File

@ -10,7 +10,7 @@ import artiq
from artiq.frontend.bit2bin import bit2bin from artiq.frontend.bit2bin import bit2bin
def main(): def get_argparser():
parser = argparse.ArgumentParser( parser = argparse.ArgumentParser(
formatter_class=argparse.RawDescriptionHelpFormatter, formatter_class=argparse.RawDescriptionHelpFormatter,
description="ARTIQ flashing/deployment tool", description="ARTIQ flashing/deployment tool",
@ -43,6 +43,11 @@ Prerequisites:
parser.add_argument("ACTION", nargs="*", parser.add_argument("ACTION", nargs="*",
default="proxy bitstream bios runtime start".split(), default="proxy bitstream bios runtime start".split(),
help="actions to perform, default: %(default)s") help="actions to perform, default: %(default)s")
return parser
def main():
parser = get_argparser()
opts = parser.parse_args() opts = parser.parse_args()
config = { config = {

View File

@ -133,8 +133,6 @@ class _NIST_QCx(MiniSoC, AMPSoC):
self.submodules.rtio_crg = _RTIOCRG(self.platform, self.crg.cd_sys.clk) self.submodules.rtio_crg = _RTIOCRG(self.platform, self.crg.cd_sys.clk)
self.submodules.rtio = rtio.RTIO(rtio_channels) self.submodules.rtio = rtio.RTIO(rtio_channels)
self.config["RTIO_FINE_TS_WIDTH"] = self.rtio.fine_ts_width 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) self.submodules.rtio_moninj = rtio.MonInj(rtio_channels)
if isinstance(self.platform.toolchain, XilinxVivadoToolchain): if isinstance(self.platform.toolchain, XilinxVivadoToolchain):
@ -210,6 +208,8 @@ class NIST_QC1(_NIST_QCx):
rtio_channels.append(rtio.LogChannel()) rtio_channels.append(rtio.LogChannel())
self.add_rtio(rtio_channels) 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): class NIST_QC2(_NIST_QCx):
@ -259,6 +259,8 @@ class NIST_QC2(_NIST_QCx):
rtio_channels.append(rtio.LogChannel()) rtio_channels.append(rtio.LogChannel())
self.add_rtio(rtio_channels) 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(): def main():

View File

@ -13,13 +13,13 @@ import sys, os, argparse, importlib
def main(): def main():
parser = argparse.ArgumentParser(description=__doc__) parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument('-m', metavar='mod', type=str, parser.add_argument("-m", metavar="mod", type=str,
help='run library module as a script') help="run library module as a script")
parser.add_argument('args', type=str, nargs='+', parser.add_argument("args", type=str, nargs="+",
help='arguments passed to program in sys.argv[1:]') help="arguments passed to program in sys.argv[1:]")
args = parser.parse_args(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) sys.path.insert(1, artiq_path)
if args.m: if args.m:
@ -28,7 +28,7 @@ def main():
else: else:
sys.argv[1:] = args.args[1:] sys.argv[1:] = args.args[1:]
with open(args.args[0]) as f: 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()) exec(code, globals())
if __name__ == "__main__": if __name__ == "__main__":

View File

@ -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

View File

@ -143,14 +143,12 @@ class CoefficientSource:
return build_segment(durations, coefficients, target=target, return build_segment(durations, coefficients, target=target,
variable=variable) variable=variable)
def extend_segment(self, segment, trigger=True, *args, **kwargs): def extend_segment(self, segment, *args, **kwargs):
"""Extend a wavesynth segment. """Extend a wavesynth segment.
See `get_segment()` for arguments. See `get_segment()` for arguments.
""" """
for i, line in enumerate(self.get_segment_data(*args, **kwargs)): for i, line in enumerate(self.get_segment_data(*args, **kwargs)):
if i == 0:
line["trigger"] = trigger
segment.add_line(**line) segment.add_line(**line)

View File

@ -36,7 +36,9 @@ for module in mock_modules:
# If extensions (or modules to document with autodoc) are in another directory, # 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 # 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. # 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 ------------------------------------------------ # -- General configuration ------------------------------------------------
@ -73,9 +75,11 @@ copyright = '2014-2016, M-Labs Limited'
# built documents. # built documents.
# #
# The short X.Y version. # The short X.Y version.
version = 'prerelease' # version = 'prerelease'
# The full version, including alpha/beta/rc tags. # 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 # The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages. # 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 # The theme to use for HTML and HTML Help pages. See the documentation for
# a list of builtin themes. # 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 # 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 # further. For a list of options available for each theme, see the

View File

@ -1,6 +1,10 @@
Utilities Utilities
========= =========
.. Sort these tool by some subjective combination of their
typical sequence and expected frequency of use.
Local running tool 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 :ref: artiq.frontend.artiq_mkfs.get_argparser
:prog: artiq_mkfs :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:
Core device configuration tool Core device configuration tool

View File

@ -4,11 +4,11 @@ import numpy as np
from artiq import * from artiq import *
from artiq.wavesynth.coefficients import SplineSource
# data is usually precomputed offline transport = SplineSource(
transport_data = dict( x=np.linspace(0, 10, 101), # waveform time
t=np.linspace(0, 10, 101), # waveform time y=np.random.rand(4*3*3, 101)*1e-6, # waveform data,
u=np.random.randn(101, 4*3*3), # waveform data,
# 4 devices, 3 board each, 3 dacs each # 4 devices, 3 board each, 3 dacs each
) )
@ -16,37 +16,33 @@ class Transport(EnvExperiment):
"""Transport""" """Transport"""
def build(self): def build(self):
self.setattr_device("core") self.core = self.get_device("core")
self.setattr_device("bd") self.bd_sw = self.get_device("bd_sw")
self.setattr_device("bdd") self.pmt = self.get_device("pmt")
self.setattr_device("pmt") self.electrodes = self.get_device("electrodes")
self.setattr_device("electrodes")
self.setattr_argument("wait_at_stop", NumberValue(100*us)) self.wait_at_stop = self.get_argument("wait_at_stop",
self.setattr_argument("speed", NumberValue(1.5)) NumberValue(100*us))
self.setattr_argument("repeats", NumberValue(100)) self.speed = self.get_argument("speed", NumberValue(1.5))
self.setattr_argument("nbins", NumberValue(100)) self.repeats = self.get_argument("repeats", NumberValue(100))
self.nbins = self.get_argument("nbins", NumberValue(100))
def calc_waveforms(self, stop): def calc_waveforms(self, stop):
t = transport_data["t"][:stop]*self.speed
u = transport_data["u"][:stop]
self.electrodes.disarm() self.electrodes.disarm()
self.tf = self.electrodes.create_frame() 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) # append the reverse transport (from stop to 0)
# both durations are the same in this case # 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 # distributes frames to the sub-devices in CompoundPDQ2
# and uploads them # and uploads them
self.electrodes.arm() self.electrodes.arm()
@kernel @kernel
def cool(self): def cool(self):
with parallel: self.bd_sw.pulse(1*ms)
self.bd.pulse(200*MHz, 1*ms)
self.bdd.pulse(300*MHz, 1*ms)
self.bd.pulse(210*MHz, 100*us)
@kernel @kernel
def transport(self): def transport(self):
@ -65,10 +61,9 @@ class Transport(EnvExperiment):
@kernel @kernel
def detect(self): def detect(self):
with parallel: with parallel:
self.bd.pulse(220*MHz, 100*us) self.bd_sw.pulse(100*us)
self.pmt.gate_rising(100*us) self.pmt.gate_rising(100*us)
self.bd.on(200*MHz) self.bd_sw.on()
self.bdd.on(300*MHz)
return self.pmt.count() return self.pmt.count()
@kernel @kernel
@ -79,7 +74,7 @@ class Transport(EnvExperiment):
@kernel @kernel
def repeat(self): 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): for i in range(self.repeats):
n = self.one() n = self.one()
@ -100,5 +95,5 @@ class Transport(EnvExperiment):
def run(self): def run(self):
# scan transport endpoint # scan transport endpoint
stops = range(10, len(transport_data["t"]), 10) stops = range(10, len(transport.x), 10)
self.scan(stops) self.scan(stops)

View File

@ -3,5 +3,5 @@ VCS = git
style = pep440 style = pep440
versionfile_source = artiq/_version.py versionfile_source = artiq/_version.py
versionfile_build = artiq/_version.py versionfile_build = artiq/_version.py
tag_prefix = v tag_prefix =
parentdir_prefix = artiq- parentdir_prefix = artiq-