Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: m-labs/artiq
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: 646721d3e938
Choose a base ref
...
head repository: m-labs/artiq
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: d4f42e33e6ec
Choose a head ref
  • 3 commits
  • 5 files changed
  • 1 contributor

Commits on Aug 21, 2015

  1. typo

    sbourdeauducq committed Aug 21, 2015
    Copy the full SHA
    a8575fe View commit details
  2. doc: scans

    sbourdeauducq committed Aug 21, 2015
    Copy the full SHA
    ac5dd0a View commit details
  3. doc: clarify hw support

    sbourdeauducq committed Aug 21, 2015
    Copy the full SHA
    d4f42e3 View commit details
Showing with 49 additions and 6 deletions.
  1. +1 −1 artiq/language/environment.py
  2. +38 −0 artiq/language/scan.py
  3. +2 −1 doc/manual/core_device.rst
  4. +6 −0 doc/manual/core_language_reference.rst
  5. +2 −4 doc/manual/getting_started.rst
2 changes: 1 addition & 1 deletion artiq/language/environment.py
Original file line number Diff line number Diff line change
@@ -73,7 +73,7 @@ class NumberValue(_SimpleArgProcessor):
:param unit: A string representing the unit of the value, for user
interface (UI) purposes.
:param step: The step with with the value should be modified by up/down
:param step: The step with which the value should be modified by up/down
buttons in a UI.
:param min: The minimum value of the argument.
:param max: The maximum value of the argument.
38 changes: 38 additions & 0 deletions artiq/language/scan.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,23 @@
"""
Implementation and management of scan objects.
A scan object (e.g. :class:`artiq.language.scan.LinearScan`) represents a
one-dimensional sweep of a numerical range. Multi-dimensional scans are
constructed by combining several scan objects.
Iterate on a scan object to scan it, e.g. ::
for variable in self.scan:
do_something(variable)
Iterating multiple times on the same scan object is possible, with the scan
restarting at the minimum value each time. Iterating concurrently on the
same scan object (e.g. via nested loops) is also supported, and the
iterators are independent from each other.
Scan objects are supported both on the host and the core device.
"""

from random import Random, shuffle
import inspect

@@ -9,6 +29,7 @@


class NoScan:
"""A scan object that yields a single value."""
def __init__(self, value):
self.value = value

@@ -25,6 +46,8 @@ def describe(self):


class LinearScan:
"""A scan object that yields a fixed number of increasing evenly
spaced values in a range."""
def __init__(self, min, max, npoints):
self.min = min
self.max = max
@@ -47,6 +70,8 @@ def describe(self):


class RandomScan:
"""A scan object that yields a fixed number of randomly ordered evenly
spaced values in a range."""
def __init__(self, min, max, npoints, seed=0):
self.sequence = list(LinearScan(min, max, npoints))
shuffle(self.sequence, Random(seed).random)
@@ -61,6 +86,7 @@ def describe(self):


class ExplicitScan:
"""A scan object that yields values from a explicitly defined sequence."""
def __init__(self, sequence):
self.sequence = sequence

@@ -81,6 +107,18 @@ def describe(self):


class Scannable:
"""An argument (as defined in :class:`artiq.language.environment`) that
takes a scan object.
:param global_min: The minimum value taken by the scanned variable, common
to all scan modes. The user interface takes this value to set the
range of its input widgets.
:param global_max: Same as global_min, but for the maximum value.
:param global_step: The step with which the value should be modified by
up/down buttons in a user interface.
:param unit: A string representing the unit of the scanned variable, for user
interface purposes.
"""
def __init__(self, global_min=None, global_max=None, global_step=None,
unit="", default=NoDefault):
self.global_min = global_min
3 changes: 2 additions & 1 deletion doc/manual/core_device.rst
Original file line number Diff line number Diff line change
@@ -19,6 +19,7 @@ The flash storage area is one sector (typically 64 kB) large and is organized as

This flash storage space can be accessed by using ``artiq_coretool`` (see: :ref:`core-device-access-tool`).

.. _board-ports:

FPGA board ports
****************
@@ -49,7 +50,7 @@ With the QC1 hardware, the TTL lines are mapped as follows:
Pipistrello
-----------

The low-cost Pipistrello FPGA board can be used as a lower-cost but slower alternative.
The low-cost Pipistrello FPGA board can be used as a lower-cost but slower alternative. The current USB over serial protocol also suffers from limitations (no monitoring/injection, no idle experiment, no kernel interruptions, lack of robustness).

When plugged to an adapter, the NIST QC1 hardware can be used. The TTL lines are mapped to RTIO channels as follows:

6 changes: 6 additions & 0 deletions doc/manual/core_language_reference.rst
Original file line number Diff line number Diff line change
@@ -15,6 +15,12 @@ The most commonly used features from those modules can be imported with ``from a
.. automodule:: artiq.language.environment
:members:

:mod:`artiq.language.scan` module
----------------------------------------

.. automodule:: artiq.language.scan
:members:

:mod:`artiq.language.units` module
----------------------------------

6 changes: 2 additions & 4 deletions doc/manual/getting_started.rst
Original file line number Diff line number Diff line change
@@ -23,7 +23,7 @@ As a very first step, we will turn on a LED on the core device. Create a file ``

The central part of our code is our ``LED`` class, that derives from :class:`artiq.language.environment.EnvExperiment`. Among other features, ``EnvExperiment`` calls our ``build`` method and provides the ``attr_device`` method that interfaces to the device database to create the appropriate device drivers and make those drivers accessible as ``self.core`` and ``self.led``. The ``@kernel`` decorator tells the system that the ``run`` method must be executed on the core device (instead of the host). The decorator uses ``self.core`` internally, which is why we request the core device using ``attr_device`` like any other.

Copy the files ``ddb.pyon`` and ``pdb.pyon`` (containing the device and parameter databases) from the ``examples`` folder of ARTIQ into the same directory as ``led.py`` (alternatively, you can use the ``-d`` and ``-p`` options of ``artiq_run.py``). You can open the database files using a text editor - their contents are in a human-readable format. You will probably want to set the IP address of the core device in ``ddb.pyon`` so that the computer can connect to it (it is the ``host`` parameter of the ``comm`` entry). See :ref:`ddb` for more information.
Copy the files ``ddb.pyon`` and ``pdb.pyon`` (containing the device and parameter databases) from the ``examples`` folder of ARTIQ into the same directory as ``led.py`` (alternatively, you can use the ``-d`` and ``-p`` options of ``artiq_run.py``). You can open the database files using a text editor - their contents are in a human-readable format. You will probably want to set the IP address of the core device in ``ddb.pyon`` so that the computer can connect to it (it is the ``host`` parameter of the ``comm`` entry). See :ref:`ddb` for more information. The example device database is designed for the NIST QC1 hardware on the KC705; see :ref:`board-ports` for RTIO channel assignments if you need to adapt the device database to a different hardware platform.

Run your code using ``artiq_run``, which is part of the ARTIQ front-end tools: ::

@@ -102,7 +102,7 @@ Create a new file ``rtio.py`` containing the following: ::
delay(2*us)


Connect an oscilloscope or logic analyzer to TTL0 (pin C11 on the Pipistrello) and run ``artiq_run.py led.py``. Notice that the generated signal's period is precisely 4 microseconds, and that it has a duty cycle of precisely 50%. This is not what you would expect if the delay and the pulse were implemented with CPU-controlled GPIO: overhead from the loop management, function calls, etc. would increase the signal's period, and asymmetry in the overhead would cause duty cycle distortion.
Connect an oscilloscope or logic analyzer to TTL0 and run ``artiq_run.py led.py``. Notice that the generated signal's period is precisely 4 microseconds, and that it has a duty cycle of precisely 50%. This is not what you would expect if the delay and the pulse were implemented with CPU-controlled GPIO: overhead from the loop management, function calls, etc. would increase the signal's period, and asymmetry in the overhead would cause duty cycle distortion.

Instead, inside the core device, output timing is generated by the gateware and the CPU only programs switching commands with certain timestamps that the CPU computes. This guarantees precise timing as long as the CPU can keep generating timestamps that are increasing fast enough. In case it fails to do that (and attempts to program an event with a timestamp in the past), the :class:`artiq.coredevice.runtime_exceptions.RTIOUnderflow` exception is raised. The kernel causing it may catch it (using a regular ``try... except...`` construct), or it will be propagated to the host.

@@ -140,8 +140,6 @@ Try the following code and observe the generated pulses on a 2-channel oscillosc
self.ttl1.pulse(4*us)
delay(4*us)

TTL1 is assigned to the pin C10 of the Pipistrello. The name of the attributes (``ttl0`` and ``ttl1``) is used to look up hardware in the device database.

Within a parallel block, some statements can be made sequential again using a ``with sequential`` construct. Observe the pulses generated by this code: ::

for i in range(1000000):