Merge branch 'master' into nac3

This commit is contained in:
Sebastien Bourdeauducq 2022-02-23 11:07:26 +08:00
commit f7b315d661
7 changed files with 154 additions and 96 deletions

View File

@ -1,12 +1,12 @@
"""RTIO driver for the Fastino 32channel, 16 bit, 2.5 MS/s per channel, """RTIO driver for the Fastino 32channel, 16 bit, 2.5 MS/s per channel,
streaming DAC. streaming DAC.
""" """
from numpy import int32 from numpy import int32, int64
from artiq.language.core import kernel, portable, delay, delay_mu from artiq.language.core import kernel, portable, delay, delay_mu
from artiq.coredevice.rtio import (rtio_output, rtio_output_wide, from artiq.coredevice.rtio import (rtio_output, rtio_output_wide,
rtio_input_data) rtio_input_data)
from artiq.language.units import us from artiq.language.units import ns
from artiq.language.types import TInt32, TList from artiq.language.types import TInt32, TList
@ -41,24 +41,48 @@ class Fastino:
:param log2_width: Width of DAC channel group (logarithm base 2). :param log2_width: Width of DAC channel group (logarithm base 2).
Value must match the corresponding value in the RTIO PHY (gateware). Value must match the corresponding value in the RTIO PHY (gateware).
""" """
kernel_invariants = {"core", "channel", "width"} kernel_invariants = {"core", "channel", "width", "t_frame"}
def __init__(self, dmgr, channel, core_device="core", log2_width=0): def __init__(self, dmgr, channel, core_device="core", log2_width=0):
self.channel = channel << 8 self.channel = channel << 8
self.core = dmgr.get(core_device) self.core = dmgr.get(core_device)
self.width = 1 << log2_width self.width = 1 << log2_width
# frame duration in mu (14 words each 7 clock cycles each 4 ns)
# self.core.seconds_to_mu(14*7*4*ns) # unfortunately this may round wrong
assert self.core.ref_period == 1*ns
self.t_frame = int64(14*7*4)
@kernel @kernel
def init(self): def init(self):
"""Initialize the device. """Initialize the device.
This clears reset, unsets DAC_CLR, enables AFE_PWR, * disables RESET, DAC_CLR, enables AFE_PWR
clears error counters, then enables error counting * clears error counters, enables error counting
* turns LEDs off
* clears `hold` and `continuous` on all channels
* clear and resets interpolators to unit rate change on all
channels
It does not change set channel voltages and does not reset the PLLs or clock
domains.
Note: On Fastino gateware before v0.2 this may lead to 0 voltage being emitted
transiently.
""" """
self.set_cfg(reset=0, afe_power_down=0, dac_clr=0, clr_err=1) self.set_cfg(reset=0, afe_power_down=0, dac_clr=0, clr_err=1)
delay(1*us) delay_mu(self.t_frame)
self.set_cfg(reset=0, afe_power_down=0, dac_clr=0, clr_err=0) self.set_cfg(reset=0, afe_power_down=0, dac_clr=0, clr_err=0)
delay(1*us) delay_mu(self.t_frame)
self.set_continuous(0)
delay_mu(self.t_frame)
self.stage_cic(1)
delay_mu(self.t_frame)
self.apply_cic(0xffffffff)
delay_mu(self.t_frame)
self.set_leds(0)
delay_mu(self.t_frame)
self.set_hold(0)
delay_mu(self.t_frame)
@kernel @kernel
def write(self, addr, data): def write(self, addr, data):
@ -78,8 +102,9 @@ class Fastino:
:param addr: Address to read from. :param addr: Address to read from.
:return: The data read. :return: The data read.
""" """
rtio_output(self.channel | addr | 0x80) raise NotImplementedError
return rtio_input_data(self.channel >> 8) # rtio_output(self.channel | addr | 0x80)
# return rtio_input_data(self.channel >> 8)
@kernel @kernel
def set_dac_mu(self, dac, data): def set_dac_mu(self, dac, data):
@ -252,9 +277,12 @@ class Fastino:
def apply_cic(self, channel_mask): def apply_cic(self, channel_mask):
"""Apply the staged interpolator configuration on the specified channels. """Apply the staged interpolator configuration on the specified channels.
Each Fastino channel includes a fourth order (cubic) CIC interpolator with Each Fastino channel starting with gateware v0.2 includes a fourth order
variable rate change and variable output gain compensation (see (cubic) CIC interpolator with variable rate change and variable output
:meth:`stage_cic`). gain compensation (see :meth:`stage_cic`).
Fastino gateware before v0.2 does not include the interpolators and the
methods affecting the CICs should not be used.
Channels using non-unity interpolation rate should have Channels using non-unity interpolation rate should have
continous DAC updates enabled (see :meth:`set_continuous`) unless continous DAC updates enabled (see :meth:`set_continuous`) unless

View File

@ -159,7 +159,7 @@ class WaitingPanel(LayoutWidget):
class ExplorerDock(QtWidgets.QDockWidget): class ExplorerDock(QtWidgets.QDockWidget):
def __init__(self, exp_manager, d_shortcuts, def __init__(self, exp_manager, d_shortcuts,
explist_sub, explist_status_sub, explist_sub, explist_status_sub,
schedule_ctl, experiment_db_ctl): schedule_ctl, experiment_db_ctl, device_db_ctl):
QtWidgets.QDockWidget.__init__(self, "Explorer") QtWidgets.QDockWidget.__init__(self, "Explorer")
self.setObjectName("Explorer") self.setObjectName("Explorer")
self.setFeatures(QtWidgets.QDockWidget.DockWidgetMovable | self.setFeatures(QtWidgets.QDockWidget.DockWidgetMovable |
@ -251,6 +251,12 @@ class ExplorerDock(QtWidgets.QDockWidget):
scan_repository_action.triggered.connect(scan_repository) scan_repository_action.triggered.connect(scan_repository)
self.el.addAction(scan_repository_action) self.el.addAction(scan_repository_action)
scan_ddb_action = QtWidgets.QAction("Scan device database", self.el)
def scan_ddb():
asyncio.ensure_future(device_db_ctl.scan())
scan_ddb_action.triggered.connect(scan_ddb)
self.el.addAction(scan_ddb_action)
self.current_directory = "" self.current_directory = ""
open_file_action = QtWidgets.QAction("Open file outside repository", open_file_action = QtWidgets.QAction("Open file outside repository",
self.el) self.el)

View File

@ -115,6 +115,11 @@ static mut API: &'static [(&'static str, *const ())] = &[
/* exceptions */ /* exceptions */
api!(_Unwind_Resume = ::unwind::_Unwind_Resume), api!(_Unwind_Resume = ::unwind::_Unwind_Resume),
api!(__nac3_personality = ::eh_artiq::personality),
api!(__nac3_raise = ::eh_artiq::raise),
api!(__nac3_resume = ::eh_artiq::resume),
api!(__nac3_end_catch = ::eh_artiq::end_catch),
/* legacy exception symbols */
api!(__artiq_personality = ::eh_artiq::personality), api!(__artiq_personality = ::eh_artiq::personality),
api!(__artiq_raise = ::eh_artiq::raise), api!(__artiq_raise = ::eh_artiq::raise),
api!(__artiq_resume = ::eh_artiq::resume), api!(__artiq_resume = ::eh_artiq::resume),

View File

@ -109,7 +109,7 @@ def main():
# create connections to master # create connections to master
rpc_clients = dict() rpc_clients = dict()
for target in "schedule", "experiment_db", "dataset_db": for target in "schedule", "experiment_db", "dataset_db", "device_db":
client = AsyncioClient() client = AsyncioClient()
loop.run_until_complete(client.connect_rpc( loop.run_until_complete(client.connect_rpc(
args.server, args.port_control, "master_" + target)) args.server, args.port_control, "master_" + target))
@ -171,7 +171,8 @@ def main():
sub_clients["explist"], sub_clients["explist"],
sub_clients["explist_status"], sub_clients["explist_status"],
rpc_clients["schedule"], rpc_clients["schedule"],
rpc_clients["experiment_db"]) rpc_clients["experiment_db"],
rpc_clients["device_db"])
smgr.register(d_explorer) smgr.register(d_explorer)
d_datasets = datasets.DatasetsDock(sub_clients["datasets"], d_datasets = datasets.DatasetsDock(sub_clients["datasets"],

View File

@ -347,7 +347,10 @@ def main():
raise ValueError("the directory containing the binaries need to be specified using -d.") raise ValueError("the directory containing the binaries need to be specified using -d.")
binary_dir = args.dir binary_dir = args.dir
if binary_dir is not None:
rtm_binary_dir = os.path.join(binary_dir, "rtm") rtm_binary_dir = os.path.join(binary_dir, "rtm")
else:
rtm_binary_dir = None
if args.host is None: if args.host is None:
client = LocalClient() client = LocalClient()

View File

@ -1,3 +1,5 @@
.. _developing-artiq:
Developing ARTIQ Developing ARTIQ
^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^

View File

@ -14,91 +14,81 @@ In the current state of affairs, we recommend that Linux users install ARTIQ via
Installing via Nix (Linux) Installing via Nix (Linux)
-------------------------- --------------------------
.. note:: First, install the Nix package manager. Some distributions provide a package for the Nix package manager, otherwise, it can be installed via the script on the `Nix website <http://nixos.org/nix/>`_. Make sure you get Nix version 2.4 or higher.
Make sure you are using a 64-bit x86 Linux system. If you are using other systems, such as 32-bit x86, Nix will attempt to compile a number of dependencies from source on your machine. This may work, but the installation process will use a lot of CPU time, memory, and disk space.
First, install the Nix package manager. Some distributions provide a package for the Nix package manager, otherwise, it can be installed via the script on the `Nix website <http://nixos.org/nix/>`_. Once Nix is installed, enable Flakes: ::
Once Nix is installed, add the M-Labs package channel with: :: $ mkdir -p ~/.config/nix
$ echo "experimental-features = nix-command flakes" > ~/.config/nix/nix.conf
$ nix-channel --add https://nixbld.m-labs.hk/channel/custom/artiq/full-beta/artiq-full The easiest way to obtain ARTIQ is then to install it into the user environment with ``$ nix profile install git+https://github.com/m-labs/artiq.git``. Answer "Yes" to the questions about setting Nix configuration options. This provides a minimal installation of ARTIQ where the usual commands (``artiq_master``, ``artiq_dashboard``, ``artiq_run``, etc.) are available.
Those channels track `nixpkgs 21.05 <https://github.com/NixOS/nixpkgs/tree/release-21.05>`_. You can check the latest status through the `Hydra interface <https://nixbld.m-labs.hk>`_. As the Nix package manager default installation uses the development version of nixpkgs, we need to tell it to switch to the release: :: This installation is however quite limited, as Nix creates a dedicated Python environment for the ARTIQ commands alone. This means that other useful Python packages that you may want (pandas, matplotlib, ...) are not available to them.
$ nix-channel --remove nixpkgs Installing multiple packages and making them visible to the ARTIQ commands requires using the Nix language. Create an empty directory with a file ``flake.nix`` with the following contents:
$ nix-channel --add https://nixos.org/channels/nixos-21.05 nixpkgs
Finally, make all the channel changes effective: ::
$ nix-channel --update
Nix won't install packages without verifying their cryptographic signature. Add the M-Labs public key by creating the file ``~/.config/nix/nix.conf`` with the following contents:
::
substituters = https://cache.nixos.org https://nixbld.m-labs.hk
trusted-public-keys = cache.nixos.org-1:6NCHdD59X431o0gWypbMrAURkbJ16ZPMQFGspcDShjY= nixbld.m-labs.hk-1:5aSRVA5b320xbNvu30tqxVPXpld73bhtOeH6uAjRyHc=
The easiest way to obtain ARTIQ is then to install it into the user environment with ``$ nix-env -iA artiq-full.artiq-env``. This provides a minimal installation of ARTIQ where the usual commands (``artiq_master``, ``artiq_dashboard``, ``artiq_run``, etc.) are available.
This installation is however quite limited, as Nix creates a dedicated Python environment for the ARTIQ commands alone. This means that other useful Python packages that you may want (pandas, matplotlib, ...) are not available to them, and this restriction also applies to the M-Labs packages containing board binaries, which means that ``artiq_flash`` will not automatically find them.
Installing multiple packages and making them visible to the ARTIQ commands requires using the Nix language. Create a file ``my-artiq-env.nix`` with the following contents:
:: ::
{
inputs.artiq.url = "git+https://github.com/m-labs/artiq.git";
inputs.extrapkg.url = "git+https://git.m-labs.hk/M-Labs/artiq-extrapkg.git";
inputs.extrapkg.inputs.artiq.follows = "artiq";
outputs = { self, artiq, extrapkg }:
let let
# pkgs contains the NixOS package collection. ARTIQ depends on some of them, and pkgs = artiq.inputs.nixpkgs.legacyPackages.x86_64-linux;
# you may want some additional packages from there. aqmain = artiq.packages.x86_64-linux;
pkgs = import <nixpkgs> {}; aqextra = extrapkg.packages.x86_64-linux;
artiq-full = import <artiq-full> { inherit pkgs; }; in {
in defaultPackage.x86_64-linux = pkgs.buildEnv {
pkgs.mkShell { name = "artiq-env";
buildInputs = [ paths = [
# ========================================
# EDIT BELOW
# ========================================
(pkgs.python3.withPackages(ps: [ (pkgs.python3.withPackages(ps: [
# List desired Python packages here. # List desired Python packages here.
aqmain.artiq
# You probably want these two.
artiq-full.artiq
artiq-full.artiq-comtools
# You need a board support package if and only if you intend to flash
# a board (those packages contain only board firmware).
# The lines below are only examples, you need to select appropriate
# packages for your boards.
#artiq-full.artiq-board-kc705-nist_clock
#artiq-full.artiq-board-kasli-wipm
#ps.paramiko # needed if and only if flashing boards remotely (artiq_flash -H) #ps.paramiko # needed if and only if flashing boards remotely (artiq_flash -H)
#aqextra.flake8-artiq
# The NixOS package collection contains many other packages that you may find # The NixOS package collection contains many other packages that you may find
# interesting for your research. Here are some examples: # interesting. Here are some examples:
#ps.pandas #ps.pandas
#ps.numpy #ps.numpy
#ps.scipy #ps.scipy
#ps.numba #ps.numba
#ps.matplotlib
# or if you need Qt (will recompile):
#(ps.matplotlib.override { enableQt = true; }) #(ps.matplotlib.override { enableQt = true; })
#ps.bokeh #ps.bokeh
#ps.cirq #ps.cirq
#ps.qiskit #ps.qiskit
])) ]))
#aqextra.korad_ka3005p
#aqextra.novatech409b
# List desired non-Python packages here # List desired non-Python packages here
#artiq-full.openocd # needed if and only if flashing boards #aqmain.openocd-bscanspi # needed if and only if flashing boards
# Other potentially interesting packages from the NixOS package collection: # Other potentially interesting packages from the NixOS package collection:
#pkgs.gtkwave #pkgs.gtkwave
#pkgs.spyder #pkgs.spyder
#pkgs.R #pkgs.R
#pkgs.julia #pkgs.julia
# ========================================
# EDIT ABOVE
# ========================================
]; ];
};
};
} }
Then spawn a shell containing the packages with ``$ nix-shell my-artiq-env.nix``. The ARTIQ commands with all the additional packages should now be available.
You can exit the shell by typing Control-D. The next time ``$ nix-shell my-artiq-env.nix`` is invoked, Nix uses the cached packages so the shell startup is fast. Then spawn a shell containing the packages with ``$ nix shell``. The ARTIQ commands with all the additional packages should now be available.
You can edit this file according to your needs, and also create multiple ``.nix`` files that correspond to different sets of packages. If you are familiar with Conda, using Nix in this way is similar to having multiple Conda environments. You can exit the shell by typing Control-D. The next time ``$ nix shell`` is invoked, Nix uses the cached packages so the shell startup is fast.
If your favorite package is not available with Nix, contact us. You can create directories containing each a ``flake.nix`` that correspond to different sets of packages. If you are familiar with Conda, using Nix in this way is similar to having multiple Conda environments.
If your favorite package is not available with Nix, contact us using the helpdesk@ email.
Installing via Conda (Windows, Linux) Installing via Conda (Windows, Linux)
------------------------------------- -------------------------------------
@ -137,9 +127,9 @@ This activation has to be performed in every new shell you open to make the ARTI
Upgrading ARTIQ (with Nix) Upgrading ARTIQ (with Nix)
-------------------------- --------------------------
Run ``$ nix-channel --update`` to retrieve information about the latest versions, and then either reinstall ARTIQ into the user environment (``$ nix-env -i python3.6-artiq``) or re-run the ``nix-shell`` command. Run ``$ nix profile upgrade`` if you installed ARTIQ into your user profile. If you used a ``flake.nix`` shell environment, make a back-up copy of the ``flake.lock`` file to enable rollback, then run ``$ nix flake update`` and re-enter ``$ nix shell``.
To rollback to the previous version, use ``$ nix-channel --rollback`` and then re-do the second step. You can switch between versions by passing a parameter to ``--rollback`` (see the ``nix-channel`` documentation). To rollback to the previous version, respectively use ``$ nix profile rollback`` or restore the backed-up version of the ``flake.lock`` file.
You may need to reflash the gateware and firmware of the core device to keep it synchronized with the software. You may need to reflash the gateware and firmware of the core device to keep it synchronized with the software.
@ -165,20 +155,21 @@ Flashing gateware and firmware into the core device
.. note:: .. note::
If you have purchased a pre-assembled system from M-Labs or QUARTIQ, the gateware and firmware are already flashed and you can skip those steps, unless you want to replace them with a different version of ARTIQ. If you have purchased a pre-assembled system from M-Labs or QUARTIQ, the gateware and firmware are already flashed and you can skip those steps, unless you want to replace them with a different version of ARTIQ.
You now need to write three binary images onto the FPGA board: You need to write three binary images onto the FPGA board:
1. The FPGA gateware bitstream 1. The FPGA gateware bitstream
2. The bootloader 2. The bootloader
3. The ARTIQ runtime or satellite manager 3. The ARTIQ runtime or satellite manager
They are all shipped in the Nix and Conda packages, along with the required flash proxy gateware bitstreams.
Installing OpenOCD Installing OpenOCD
^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^
.. note::
This version of OpenOCD is not applicable to Kasli-SoC.
OpenOCD can be used to write the binary images into the core device FPGA board's flash memory. OpenOCD can be used to write the binary images into the core device FPGA board's flash memory.
With Nix, add ``artiq-full.openocd`` to the shell packages. Be careful not to add ``pkgs.openocd`` instead - this would install OpenOCD from the NixOS package collection, which does not support ARTIQ boards. With Nix, add ``aqmain.openocd-bscanspi`` to the shell packages. Be careful not to add ``pkgs.openocd`` instead - this would install OpenOCD from the NixOS package collection, which does not support ARTIQ boards.
With Conda, install ``openocd`` as follows:: With Conda, install ``openocd`` as follows::
@ -189,6 +180,9 @@ With Conda, install ``openocd`` as follows::
Configuring OpenOCD Configuring OpenOCD
^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^
.. note::
These instructions are not applicable to Kasli-SoC.
Some additional steps are necessary to ensure that OpenOCD can communicate with the FPGA board. Some additional steps are necessary to ensure that OpenOCD can communicate with the FPGA board.
On Linux, first ensure that the current user belongs to the ``plugdev`` group (i.e. ``plugdev`` shown when you run ``$ groups``). If it does not, run ``$ sudo adduser $USER plugdev`` and re-login. On Linux, first ensure that the current user belongs to the ``plugdev`` group (i.e. ``plugdev`` shown when you run ``$ groups``). If it does not, run ``$ sudo adduser $USER plugdev`` and re-login.
@ -218,6 +212,19 @@ On Windows, a third-party tool, `Zadig <http://zadig.akeo.ie/>`_, is necessary.
You may need to repeat these steps every time you plug the FPGA board into a port where it has not been plugged into previously on the same system. You may need to repeat these steps every time you plug the FPGA board into a port where it has not been plugged into previously on the same system.
Obtaining the board binaries
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
If you have an active firmware subscription with M-Labs or QUARTIQ, you can obtain firmware that corresponds to the currently installed version of ARTIQ using AFWS (ARTIQ firmware service). One year of subscription is included with most hardware purchases. You may purchase or extend firmware subscriptions by writing to the sales@ email.
Run the command::
$ afws_client [username] build [variant] [afws_directory]
Replace ``[username]`` with the login name that was given to you with the subscription, ``[variant]`` with the name of your system variant, and ``[afws_directory]`` with the name of an empty directory, which will be created by the command if it does not exist. Enter your password when prompted and wait for the build (if applicable) and download to finish. If you experience issues with the AFWS client, write to the helpdesk@ email.
Without a subscription, you may build the firmware yourself from the open source code. See the section :ref:`Developing ARTIQ <developing-artiq>`.
Writing the flash Writing the flash
^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^
@ -225,13 +232,19 @@ Then, you can write the flash:
* For Kasli:: * For Kasli::
$ artiq_flash -V [your system variant] $ artiq_flash -d [afws_directory]
The JTAG adapter is integrated into the Kasli board; for flashing (and debugging) you simply need to connect your computer to the micro-USB connector on the Kasli front panel. The JTAG adapter is integrated into the Kasli board; for flashing (and debugging) you simply need to connect your computer to the micro-USB connector on the Kasli front panel.
* For Kasli-SoC::
$ artiq_coremgmt [-D 192.168.1.75] config write -f boot [afws_directory]/boot.bin
If the Kasli-SoC won't boot due to corrupted firmware and ``artiq_coremgmt`` cannot access it, extract the SD card and replace ``boot.bin`` manually.
* For the KC705 board:: * For the KC705 board::
$ artiq_flash -t kc705 -V [nist_clock/nist_qc2] $ artiq_flash -t kc705 -d [afws_directory]
The SW13 switches need to be set to 00001. The SW13 switches need to be set to 00001.