mirror of
https://github.com/m-labs/artiq.git
synced 2024-12-25 11:18:27 +08:00
Merge branch 'master' into nac3
This commit is contained in:
commit
7b56a72da0
@ -5,3 +5,4 @@ include versioneer.py
|
||||
include artiq/_version.py
|
||||
include artiq/coredevice/coredevice_generic.schema.json
|
||||
include artiq/compiler/kernel.ld
|
||||
include artiq/afws.pem
|
||||
|
@ -23,7 +23,7 @@ Highlights:
|
||||
* On Kasli, the number of FIFO lanes in the scalable events dispatcher (SED) can now be configured in
|
||||
the JSON hardware description file.
|
||||
* ``artiq_ddb_template`` generates edge-counter keys that start with the key of the corresponding
|
||||
TTL device (e.g. ``"ttl_0_counter"`` for the edge counter on TTL device``"ttl_0"``)
|
||||
TTL device (e.g. ``ttl_0_counter`` for the edge counter on TTL device ``ttl_0``).
|
||||
* ``artiq_master`` now has an ``--experiment-subdir`` option to scan only a subdirectory of the
|
||||
repository when building the list of experiments.
|
||||
* The configuration entry ``rtio_clock`` supports multiple clocking settings, deprecating the usage
|
||||
|
23
artiq/afws.pem
Normal file
23
artiq/afws.pem
Normal file
@ -0,0 +1,23 @@
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIID0zCCArugAwIBAgIUPkNfEUx/uau3z8SD4mgMbCK/DEgwDQYJKoZIhvcNAQEL
|
||||
BQAweTELMAkGA1UEBhMCSEsxEzARBgNVBAgMClNvbWUtU3RhdGUxFzAVBgNVBAoM
|
||||
Dk0tTGFicyBMaW1pdGVkMRkwFwYDVQQDDBBuaXhibGQubS1sYWJzLmhrMSEwHwYJ
|
||||
KoZIhvcNAQkBFhJoZWxwZGVza0BtLWxhYnMuaGswHhcNMjIwMjA2MTA1ODQ0WhcN
|
||||
MjUwMjA1MTA1ODQ0WjB5MQswCQYDVQQGEwJISzETMBEGA1UECAwKU29tZS1TdGF0
|
||||
ZTEXMBUGA1UECgwOTS1MYWJzIExpbWl0ZWQxGTAXBgNVBAMMEG5peGJsZC5tLWxh
|
||||
YnMuaGsxITAfBgkqhkiG9w0BCQEWEmhlbHBkZXNrQG0tbGFicy5oazCCASIwDQYJ
|
||||
KoZIhvcNAQEBBQADggEPADCCAQoCggEBAPWetZhoggPR2ae7waGzv1AQ8NQO3noW
|
||||
8DofVjusNpX5i/YB0waAr1bm1tALLJoHV2r/gTxujlXCe/L/WG1DLseCf6NO9sHg
|
||||
t0FLhDpF9kPMWBgauVVLepd2Y2yU1G8eFuEVGnsiQSu0IzsZP5FQBJSyxvxJ+V/L
|
||||
EW9ox91VGOP9VZR9jqdlYjGhcwClHA/nHe0q1fZq42+9rG466I5yIlNSoa7ilhTU
|
||||
2C2doxy6Sr6VJYnLEMQqoIF65t3MkKi9iaqN7az0OCrj6XR0P5iKBzUhIgMUd2qs
|
||||
7Id0XUdbQvaoaRI67vhGkNr+f4rdAUNCDGcbbokuBnmE7/gva6BAABUCAwEAAaNT
|
||||
MFEwHQYDVR0OBBYEFM2e2FmcytXhKyfC1KEjVJ2mPSy3MB8GA1UdIwQYMBaAFM2e
|
||||
2FmcytXhKyfC1KEjVJ2mPSy3MA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEL
|
||||
BQADggEBAKH0z5vlbfTghjYWwd2yEEFBbZx5XxaLHboFQpFpxu9sZoidVs047tco
|
||||
MOr1py9juiNGGM8G35sw9306f+thDFwqlQfSExUwp5pRQNq+mxglMSF05HWDqBwb
|
||||
wnItKi/WXpkMQXgpQJFVeflz4B4ZFNlH1UQl5bwacXOM9NM9zO7duCjVXmGE0yxi
|
||||
VQyApfPQYu9whCSowDYYaA0toJeikMzGfWxhlAH79/2Qmit8KcSCbX1fK/QoRZLa
|
||||
5NeUi/OlJbBpkgTrfzfMLphmsPWPAVMeUKzqd/vXfG6ZBOZZm6e6sl8RBycBezII
|
||||
15WekikTE5+T54/E0xiu+zIW/Xhhk14=
|
||||
-----END CERTIFICATE-----
|
@ -119,6 +119,18 @@ class ADF5356:
|
||||
else:
|
||||
self.sync()
|
||||
|
||||
@kernel
|
||||
def set_att(self, att: float):
|
||||
"""Set digital step attenuator in SI units.
|
||||
|
||||
This method will write the attenuator settings of the channel.
|
||||
|
||||
.. seealso:: :meth:`artiq.coredevice.mirny.Mirny.set_att`
|
||||
|
||||
:param att: Attenuation in dB.
|
||||
"""
|
||||
self.cpld.set_att(self.channel, att)
|
||||
|
||||
@kernel
|
||||
def set_att_mu(self, att: int32):
|
||||
"""Set digital step attenuator in machine units.
|
||||
|
@ -2,7 +2,7 @@ import asyncio
|
||||
import logging
|
||||
import struct
|
||||
from enum import Enum
|
||||
|
||||
from .comm import set_keepalive
|
||||
|
||||
__all__ = ["TTLProbe", "TTLOverride", "CommMonInj"]
|
||||
|
||||
@ -29,6 +29,8 @@ class CommMonInj:
|
||||
|
||||
async def connect(self, host, port=1383):
|
||||
self._reader, self._writer = await asyncio.open_connection(host, port)
|
||||
set_keepalive(self._writer.transport.get_extra_info('socket'), 1, 1, 3)
|
||||
|
||||
try:
|
||||
self._writer.write(b"ARTIQ moninj\n")
|
||||
# get device endian
|
||||
|
@ -1,7 +1,7 @@
|
||||
"""RTIO driver for Mirny (4 channel GHz PLLs)
|
||||
"""
|
||||
|
||||
from artiq.language.core import nac3, Kernel, KernelInvariant, kernel
|
||||
from artiq.language.core import nac3, Kernel, KernelInvariant, kernel, portable
|
||||
from artiq.language.units import us
|
||||
|
||||
from numpy import int32
|
||||
@ -144,6 +144,18 @@ class Mirny:
|
||||
self.write_reg(1, (self.clk_sel << 4))
|
||||
self.core.delay(1000. * us)
|
||||
|
||||
@portable
|
||||
def att_to_mu(self, att: float) -> int32:
|
||||
"""Convert an attenuation setting in dB to machine units.
|
||||
|
||||
:param att: Attenuation setting in dB.
|
||||
:return: Digital attenuation setting.
|
||||
"""
|
||||
code = int32(255) - int32(round(att * 8.))
|
||||
if code < 0 or code > 255:
|
||||
raise ValueError("Invalid Mirny attenuation!")
|
||||
return code
|
||||
|
||||
@kernel
|
||||
def set_att_mu(self, channel: int32, att: int32):
|
||||
"""Set digital step attenuator in machine units.
|
||||
@ -153,6 +165,21 @@ class Mirny:
|
||||
self.bus.set_config_mu(SPI_CONFIG | SPI_END, 16, SPIT_WR, SPI_CS)
|
||||
self.bus.write(((channel | 8) << 25) | (att << 16))
|
||||
|
||||
@kernel
|
||||
def set_att(self, channel: int32, att: float):
|
||||
"""Set digital step attenuator in SI units.
|
||||
|
||||
This method will write the attenuator settings of the selected channel.
|
||||
|
||||
.. seealso:: :meth:`set_att_mu`
|
||||
|
||||
:param channel: Attenuator channel (0-3).
|
||||
:param att: Attenuation setting in dB. Higher value is more
|
||||
attenuation. Minimum attenuation is 0*dB, maximum attenuation is
|
||||
31.5*dB.
|
||||
"""
|
||||
self.set_att_mu(channel, self.att_to_mu(att))
|
||||
|
||||
@kernel
|
||||
def write_ext(self, addr: int32, length: int32, data: int32, ext_div: int32 = SPIT_WR):
|
||||
"""Perform SPI write to a prefixed address"""
|
||||
|
@ -65,8 +65,8 @@ fn memory_test(total: &mut usize, wrong: &mut usize) -> bool {
|
||||
})
|
||||
}
|
||||
|
||||
fn prng32(seed: &mut u32) -> u32 { *seed = 1664525 * *seed + 1013904223; *seed }
|
||||
fn prng16(seed: &mut u16) -> u16 { *seed = 25173 * *seed + 13849; *seed }
|
||||
fn prng32(seed: &mut u32) -> u32 { *seed = u32::wrapping_add(u32::wrapping_mul(1664525, *seed), 1013904223); *seed }
|
||||
fn prng16(seed: &mut u16) -> u16 { *seed = u16::wrapping_add(u16::wrapping_mul(25173, *seed), 13849); *seed }
|
||||
|
||||
for _ in 0..4 {
|
||||
// Test data bus
|
||||
|
@ -211,9 +211,10 @@ mod ddr {
|
||||
|
||||
// Generate pseudo-random sequence
|
||||
let mut prs = [0; DFII_NPHASES * DFII_PIX_DATA_SIZE];
|
||||
let mut prv = 42;
|
||||
let mut prv: u32 = 42;
|
||||
for b in prs.iter_mut() {
|
||||
prv = 1664525 * prv + 1013904223;
|
||||
|
||||
prv = u32::wrapping_add(u32::wrapping_mul(1664525, prv), 1013904223);
|
||||
*b = prv as u8;
|
||||
}
|
||||
|
||||
@ -296,7 +297,7 @@ mod ddr {
|
||||
let mut prs = [0; DFII_NPHASES * DFII_PIX_DATA_SIZE];
|
||||
let mut prv = 42;
|
||||
for b in prs.iter_mut() {
|
||||
prv = 1664525 * prv + 1013904223;
|
||||
prv = u32::wrapping_add(u32::wrapping_mul(1664525, prv), 1013904223);
|
||||
*b = prv as u8;
|
||||
}
|
||||
|
||||
|
@ -5,15 +5,20 @@ use byteorder::{NativeEndian, ByteOrder};
|
||||
use io::{ProtoRead, Read, Write, ProtoWrite, Error};
|
||||
use self::tag::{Tag, TagIterator, split_tag};
|
||||
|
||||
#[inline]
|
||||
fn alignment_offset(alignment: isize, ptr: isize) -> isize {
|
||||
(-ptr).rem_euclid(alignment)
|
||||
}
|
||||
|
||||
unsafe fn align_ptr<T>(ptr: *const ()) -> *const T {
|
||||
let alignment = core::mem::align_of::<T>() as isize;
|
||||
let fix = (alignment - (ptr as isize) % alignment) % alignment;
|
||||
let fix = alignment_offset(alignment as isize, ptr as isize);
|
||||
((ptr as isize) + fix) as *const T
|
||||
}
|
||||
|
||||
unsafe fn align_ptr_mut<T>(ptr: *mut ()) -> *mut T {
|
||||
let alignment = core::mem::align_of::<T>() as isize;
|
||||
let fix = (alignment - (ptr as isize) % alignment) % alignment;
|
||||
let fix = alignment_offset(alignment as isize, ptr as isize);
|
||||
((ptr as isize) + fix) as *mut T
|
||||
}
|
||||
|
||||
@ -54,6 +59,7 @@ unsafe fn recv_value<R, E>(reader: &mut R, tag: Tag, data: &mut *mut (),
|
||||
})
|
||||
}
|
||||
Tag::Tuple(it, arity) => {
|
||||
*data = data.offset(alignment_offset(tag.alignment() as isize, *data as isize));
|
||||
let mut it = it.clone();
|
||||
for _ in 0..arity {
|
||||
let tag = it.next().expect("truncated tag");
|
||||
@ -69,9 +75,12 @@ unsafe fn recv_value<R, E>(reader: &mut R, tag: Tag, data: &mut *mut (),
|
||||
let length = (*ptr).length as usize;
|
||||
|
||||
let tag = it.clone().next().expect("truncated tag");
|
||||
(*ptr).elements = alloc(tag.size() * (*ptr).length as usize)?;
|
||||
let padding = if let Tag::Int64 | Tag::Float64 = tag { 4 } else { 0 };
|
||||
let mut data = alloc(tag.size() * length + padding)?;
|
||||
|
||||
let mut data = (*ptr).elements;
|
||||
data = data.offset(alignment_offset(tag.alignment() as isize, data as isize));
|
||||
|
||||
(*ptr).elements = data;
|
||||
match tag {
|
||||
Tag::Bool => {
|
||||
let dest = slice::from_raw_parts_mut(data as *mut u8, length);
|
||||
@ -109,9 +118,11 @@ unsafe fn recv_value<R, E>(reader: &mut R, tag: Tag, data: &mut *mut (),
|
||||
let length = total_len as usize;
|
||||
|
||||
let elt_tag = it.clone().next().expect("truncated tag");
|
||||
*buffer = alloc(elt_tag.size() * total_len as usize)?;
|
||||
let padding = if let Tag::Int64 | Tag::Float64 = tag { 4 } else { 0 };
|
||||
let mut data = alloc(elt_tag.size() * length + padding)?;
|
||||
data = data.offset(alignment_offset(tag.alignment() as isize, data as isize));
|
||||
|
||||
let mut data = *buffer;
|
||||
*buffer = data;
|
||||
match elt_tag {
|
||||
Tag::Bool => {
|
||||
let dest = slice::from_raw_parts_mut(data as *mut u8, length);
|
||||
@ -139,6 +150,7 @@ unsafe fn recv_value<R, E>(reader: &mut R, tag: Tag, data: &mut *mut (),
|
||||
})
|
||||
}
|
||||
Tag::Range(it) => {
|
||||
*data = data.offset(alignment_offset(tag.alignment() as isize, *data as isize));
|
||||
let tag = it.clone().next().expect("truncated tag");
|
||||
recv_value(reader, tag, data, alloc)?;
|
||||
recv_value(reader, tag, data, alloc)?;
|
||||
@ -336,6 +348,7 @@ pub fn send_args<W>(writer: &mut W, service: u32, tag_bytes: &[u8], data: *const
|
||||
|
||||
mod tag {
|
||||
use core::fmt;
|
||||
use super::alignment_offset;
|
||||
|
||||
pub fn split_tag(tag_bytes: &[u8]) -> (&[u8], &[u8]) {
|
||||
let tag_separator =
|
||||
@ -385,6 +398,33 @@ mod tag {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn alignment(self) -> usize {
|
||||
use cslice::CSlice;
|
||||
match self {
|
||||
Tag::None => 1,
|
||||
Tag::Bool => core::mem::align_of::<u8>(),
|
||||
Tag::Int32 => core::mem::align_of::<i32>(),
|
||||
Tag::Int64 => core::mem::align_of::<i64>(),
|
||||
Tag::Float64 => core::mem::align_of::<f64>(),
|
||||
// struct type: align to largest element
|
||||
Tag::Tuple(it, arity) => {
|
||||
let it = it.clone();
|
||||
it.take(arity.into()).map(|t| t.alignment()).max().unwrap()
|
||||
},
|
||||
Tag::Range(it) => {
|
||||
let it = it.clone();
|
||||
it.take(3).map(|t| t.alignment()).max().unwrap()
|
||||
}
|
||||
// CSlice basically
|
||||
Tag::Bytes | Tag::String | Tag::ByteArray | Tag::List(_) =>
|
||||
core::mem::align_of::<CSlice<()>>(),
|
||||
// array buffer is allocated, so no need for alignment first
|
||||
Tag::Array(_, _) => 1,
|
||||
// will not be sent from the host
|
||||
_ => unreachable!("unexpected tag from host")
|
||||
}
|
||||
}
|
||||
|
||||
pub fn size(self) -> usize {
|
||||
match self {
|
||||
Tag::None => 0,
|
||||
@ -401,6 +441,7 @@ mod tag {
|
||||
for _ in 0..arity {
|
||||
let tag = it.next().expect("truncated tag");
|
||||
size += tag.size();
|
||||
size += alignment_offset(tag.alignment() as isize, size as isize) as usize;
|
||||
}
|
||||
size
|
||||
}
|
||||
@ -469,6 +510,13 @@ mod tag {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> Iterator for TagIterator<'a> {
|
||||
type Item = Tag<'a>;
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
(self as &mut TagIterator<'a>).next()
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> fmt::Display for TagIterator<'a> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
let mut it = self.clone();
|
||||
|
164
artiq/frontend/afws_client.py
Executable file
164
artiq/frontend/afws_client.py
Executable file
@ -0,0 +1,164 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
import sys
|
||||
import argparse
|
||||
import os
|
||||
import socket
|
||||
import ssl
|
||||
import io
|
||||
import zipfile
|
||||
from getpass import getpass
|
||||
|
||||
|
||||
def get_artiq_cert():
|
||||
try:
|
||||
import artiq
|
||||
except ImportError:
|
||||
return None
|
||||
filename = os.path.join(os.path.dirname(artiq.__file__), "afws.pem")
|
||||
if not os.path.isfile(filename):
|
||||
return None
|
||||
return filename
|
||||
|
||||
|
||||
def get_artiq_rev():
|
||||
try:
|
||||
import artiq
|
||||
except ImportError:
|
||||
return None
|
||||
return artiq._version.get_rev()
|
||||
|
||||
|
||||
def zip_unarchive(data, directory):
|
||||
buf = io.BytesIO(data)
|
||||
with zipfile.ZipFile(buf) as archive:
|
||||
archive.extractall(directory)
|
||||
|
||||
|
||||
class Client:
|
||||
def __init__(self, server, port, cafile):
|
||||
self.ssl_context = ssl.create_default_context(cafile=cafile)
|
||||
self.raw_socket = socket.create_connection((server, port))
|
||||
try:
|
||||
self.socket = self.ssl_context.wrap_socket(self.raw_socket, server_hostname=server)
|
||||
except:
|
||||
self.raw_socket.close()
|
||||
raise
|
||||
self.fsocket = self.socket.makefile("rwb")
|
||||
|
||||
def close(self):
|
||||
self.socket.close()
|
||||
self.raw_socket.close()
|
||||
|
||||
def send_command(self, *command):
|
||||
self.fsocket.write((" ".join(command) + "\n").encode())
|
||||
self.fsocket.flush()
|
||||
|
||||
def read_reply(self):
|
||||
return self.fsocket.readline().decode("ascii").split()
|
||||
|
||||
def login(self, username, password):
|
||||
self.send_command("LOGIN", username, password)
|
||||
return self.read_reply() == ["HELLO"]
|
||||
|
||||
def build(self, rev, variant):
|
||||
self.send_command("BUILD", rev, variant)
|
||||
reply = self.read_reply()[0]
|
||||
if reply != "BUILDING":
|
||||
return reply, None
|
||||
print("Build in progress. This may take 10-15 minutes.")
|
||||
reply, status = self.read_reply()
|
||||
if reply != "DONE":
|
||||
raise ValueError("Unexpected server reply: expected 'DONE', got '{}'".format(reply))
|
||||
if status != "done":
|
||||
return status, None
|
||||
print("Build completed. Downloading...")
|
||||
reply, length = self.read_reply()
|
||||
if reply != "PRODUCT":
|
||||
raise ValueError("Unexpected server reply: expected 'PRODUCT', got '{}'".format(reply))
|
||||
contents = self.fsocket.read(int(length))
|
||||
print("Download completed.")
|
||||
return "OK", contents
|
||||
|
||||
def passwd(self, password):
|
||||
self.send_command("PASSWD", password)
|
||||
return self.read_reply() == ["OK"]
|
||||
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument("--server", default="nixbld.m-labs.hk", help="server to connect to (default: %(default)s)")
|
||||
parser.add_argument("--port", default=7402, type=int, help="port to connect to (default: %(default)d)")
|
||||
parser.add_argument("--cert", default=None, help="SSL certificate file used to authenticate server (default: afws.pem in ARTIQ)")
|
||||
parser.add_argument("username", help="user name for logging into AFWS")
|
||||
action = parser.add_subparsers(dest="action")
|
||||
action.required = True
|
||||
act_build = action.add_parser("build", help="build and download firmware")
|
||||
act_build.add_argument("--rev", default=None, help="revision to build (default: currently installed ARTIQ revision)")
|
||||
act_build.add_argument("variant", help="variant to build")
|
||||
act_build.add_argument("directory", help="output directory")
|
||||
act_passwd = action.add_parser("passwd", help="change password")
|
||||
args = parser.parse_args()
|
||||
|
||||
cert = args.cert
|
||||
if cert is None:
|
||||
cert = get_artiq_cert()
|
||||
if cert is None:
|
||||
print("SSL certificate not found in ARTIQ. Specify manually using --cert.")
|
||||
sys.exit(1)
|
||||
|
||||
if args.action == "passwd":
|
||||
password = getpass("Current password: ")
|
||||
else:
|
||||
password = getpass()
|
||||
|
||||
client = Client(args.server, args.port, cert)
|
||||
try:
|
||||
if not client.login(args.username, password):
|
||||
print("Login failed")
|
||||
sys.exit(1)
|
||||
print("Logged in successfully.")
|
||||
if args.action == "passwd":
|
||||
print("Password must made of alphanumeric characters (a-z, A-Z, 0-9) and be at least 8 characters long.")
|
||||
password = getpass("New password: ")
|
||||
password_confirm = getpass("New password (again): ")
|
||||
while password != password_confirm:
|
||||
print("Passwords do not match")
|
||||
password = getpass("New password: ")
|
||||
password_confirm = getpass("New password (again): ")
|
||||
if not client.passwd(password):
|
||||
print("Failed to change password")
|
||||
sys.exit(1)
|
||||
elif args.action == "build":
|
||||
try:
|
||||
os.mkdir(args.directory)
|
||||
except FileExistsError:
|
||||
try:
|
||||
if any(os.scandir(args.directory)):
|
||||
print("Output directory already exists and is not empty. Please remove it and try again.")
|
||||
sys.exit(1)
|
||||
except NotADirectoryError:
|
||||
print("A file with the same name as the output directory already exists. Please remove it and try again.")
|
||||
sys.exit(1)
|
||||
rev = args.rev
|
||||
if rev is None:
|
||||
rev = get_artiq_rev()
|
||||
if rev is None:
|
||||
print("Unable to determine currently installed ARTIQ revision. Specify manually using --rev.")
|
||||
sys.exit(1)
|
||||
result, contents = client.build(rev, args.variant)
|
||||
if result != "OK":
|
||||
if result == "UNAUTHORIZED":
|
||||
print("You are not authorized to build this variant. Your firmware subscription may have expired. Contact helpdesk\x40m-labs.hk.")
|
||||
else:
|
||||
print("Build failed: {}".format(result))
|
||||
sys.exit(1)
|
||||
zip_unarchive(contents, args.directory)
|
||||
else:
|
||||
raise ValueError
|
||||
finally:
|
||||
client.close()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
@ -13,7 +13,6 @@ from collections import defaultdict
|
||||
from sipyco import common_args
|
||||
|
||||
from artiq import __version__ as artiq_version
|
||||
from artiq import __artiq_dir__ as artiq_dir
|
||||
from artiq.remoting import SSHClient, LocalClient
|
||||
from artiq.frontend.bit2bin import bit2bin
|
||||
|
||||
@ -63,13 +62,11 @@ Prerequisites:
|
||||
parser.add_argument("-t", "--target", default="kasli",
|
||||
help="target board, default: %(default)s, one of: "
|
||||
"kasli sayma metlino kc705")
|
||||
parser.add_argument("-V", "--variant", default=None,
|
||||
help="board variant. Autodetected if only one is installed.")
|
||||
parser.add_argument("-I", "--preinit-command", default=[], action="append",
|
||||
help="add a pre-initialization OpenOCD command. "
|
||||
"Useful for selecting a board when several are connected.")
|
||||
parser.add_argument("-f", "--storage", help="write file to storage area")
|
||||
parser.add_argument("-d", "--dir", help="look for board binaries in this directory")
|
||||
parser.add_argument("-d", "--dir", default=None, help="look for board binaries in this directory")
|
||||
parser.add_argument("--srcbuild", help="board binaries directory is laid out as a source build tree",
|
||||
default=False, action="store_true")
|
||||
parser.add_argument("--no-rtm-jtag", help="do not attempt JTAG to the RTM",
|
||||
@ -338,56 +335,19 @@ def main():
|
||||
},
|
||||
}[args.target]
|
||||
|
||||
bin_dir = args.dir
|
||||
if bin_dir is None:
|
||||
bin_dir = os.path.join(artiq_dir, "board-support")
|
||||
|
||||
needs_artifacts = not args.action or any(
|
||||
action in args.action
|
||||
for action in ["gateware", "rtm_gateware", "bootloader", "firmware", "load", "rtm_load"])
|
||||
variant = args.variant
|
||||
if needs_artifacts and variant is None:
|
||||
variants = []
|
||||
if args.srcbuild:
|
||||
for entry in os.scandir(bin_dir):
|
||||
if entry.is_dir():
|
||||
variants.append(entry.name)
|
||||
else:
|
||||
prefix = args.target + "-"
|
||||
for entry in os.scandir(bin_dir):
|
||||
if entry.is_dir() and entry.name.startswith(prefix):
|
||||
variants.append(entry.name[len(prefix):])
|
||||
if args.target == "sayma":
|
||||
try:
|
||||
variants.remove("rtm")
|
||||
except ValueError:
|
||||
pass
|
||||
if all(action in ["rtm_gateware", "storage", "rtm_load", "erase", "start"]
|
||||
for action in args.action) and args.action:
|
||||
pass
|
||||
elif len(variants) == 0:
|
||||
raise FileNotFoundError("no variants found, did you install a board binary package?")
|
||||
elif len(variants) == 1:
|
||||
variant = variants[0]
|
||||
else:
|
||||
raise ValueError("more than one variant found for selected board, specify -V. "
|
||||
"Found variants: {}".format(" ".join(sorted(variants))))
|
||||
if needs_artifacts:
|
||||
if args.srcbuild:
|
||||
variant_dir = variant
|
||||
else:
|
||||
variant_dir = args.target + "-" + variant
|
||||
if args.target == "sayma":
|
||||
if args.srcbuild:
|
||||
rtm_variant_dir = "rtm"
|
||||
else:
|
||||
rtm_variant_dir = "sayma-rtm"
|
||||
|
||||
if not args.action:
|
||||
if args.target == "sayma" and variant != "simplesatellite" and variant != "master":
|
||||
if args.target == "sayma":
|
||||
args.action = "gateware rtm_gateware bootloader firmware start".split()
|
||||
else:
|
||||
args.action = "gateware bootloader firmware start".split()
|
||||
needs_artifacts = any(
|
||||
action in args.action
|
||||
for action in ["gateware", "rtm_gateware", "bootloader", "firmware", "load", "rtm_load"])
|
||||
if needs_artifacts and args.dir is None:
|
||||
raise ValueError("the directory containing the binaries need to be specified using -d.")
|
||||
|
||||
binary_dir = args.dir
|
||||
rtm_binary_dir = os.path.join(binary_dir, "rtm")
|
||||
|
||||
if args.host is None:
|
||||
client = LocalClient()
|
||||
@ -400,14 +360,14 @@ def main():
|
||||
programmer_cls = config["programmer"]
|
||||
programmer = programmer_cls(client, preinit_script=args.preinit_command)
|
||||
|
||||
def artifact_path(this_variant_dir, *path_filename):
|
||||
def artifact_path(this_binary_dir, *path_filename):
|
||||
if args.srcbuild:
|
||||
# source tree - use path elements to locate file
|
||||
return os.path.join(bin_dir, this_variant_dir, *path_filename)
|
||||
return os.path.join(this_binary_dir, *path_filename)
|
||||
else:
|
||||
# flat tree - all files in the same directory, discard path elements
|
||||
*_, filename = path_filename
|
||||
return os.path.join(bin_dir, this_variant_dir, filename)
|
||||
return os.path.join(this_binary_dir, filename)
|
||||
|
||||
def convert_gateware(bit_filename, header=False):
|
||||
bin_handle, bin_filename = tempfile.mkstemp(
|
||||
@ -429,15 +389,15 @@ def main():
|
||||
for action in args.action:
|
||||
if action == "gateware":
|
||||
gateware_bin = convert_gateware(
|
||||
artifact_path(variant_dir, "gateware", "top.bit"))
|
||||
artifact_path(binary_dir, "gateware", "top.bit"))
|
||||
programmer.write_binary(*config["gateware"], gateware_bin)
|
||||
elif action == "rtm_gateware":
|
||||
rtm_gateware_bin = convert_gateware(
|
||||
artifact_path(rtm_variant_dir, "gateware", "top.bit"), header=True)
|
||||
artifact_path(rtm_binary_dir, "gateware", "top.bit"), header=True)
|
||||
programmer.write_binary(*config["rtm_gateware"],
|
||||
rtm_gateware_bin)
|
||||
elif action == "bootloader":
|
||||
bootloader_bin = artifact_path(variant_dir, "software", "bootloader", "bootloader.bin")
|
||||
bootloader_bin = artifact_path(binary_dir, "software", "bootloader", "bootloader.bin")
|
||||
programmer.write_binary(*config["bootloader"], bootloader_bin)
|
||||
elif action == "storage":
|
||||
storage_img = args.storage
|
||||
@ -445,7 +405,7 @@ def main():
|
||||
elif action == "firmware":
|
||||
firmware_fbis = []
|
||||
for firmware in "satman", "runtime":
|
||||
filename = artifact_path(variant_dir, "software", firmware, firmware + ".fbi")
|
||||
filename = artifact_path(binary_dir, "software", firmware, firmware + ".fbi")
|
||||
if os.path.exists(filename):
|
||||
firmware_fbis.append(filename)
|
||||
if not firmware_fbis:
|
||||
@ -456,13 +416,13 @@ def main():
|
||||
programmer.write_binary(*config["firmware"], firmware_fbis[0])
|
||||
elif action == "load":
|
||||
if args.target == "sayma":
|
||||
gateware_bit = artifact_path(variant_dir, "gateware", "top.bit")
|
||||
gateware_bit = artifact_path(binary_dir, "gateware", "top.bit")
|
||||
programmer.load(gateware_bit, 1)
|
||||
else:
|
||||
gateware_bit = artifact_path(variant_dir, "gateware", "top.bit")
|
||||
gateware_bit = artifact_path(binary_dir, "gateware", "top.bit")
|
||||
programmer.load(gateware_bit, 0)
|
||||
elif action == "rtm_load":
|
||||
rtm_gateware_bit = artifact_path(rtm_variant_dir, "gateware", "top.bit")
|
||||
rtm_gateware_bit = artifact_path(rtm_binary_dir, "gateware", "top.bit")
|
||||
programmer.load(rtm_gateware_bit, 0)
|
||||
elif action == "start":
|
||||
programmer.start()
|
||||
|
@ -331,7 +331,7 @@ class SinaraTester(EnvExperiment):
|
||||
self.core.break_realtime()
|
||||
channel.init()
|
||||
|
||||
channel.set_att_mu(160)
|
||||
channel.set_att(11.5*dB)
|
||||
channel.sw.on()
|
||||
self.core.break_realtime()
|
||||
|
||||
|
@ -100,6 +100,17 @@ class NumberEntryInt(QtWidgets.QSpinBox):
|
||||
if "default" in procdesc:
|
||||
return procdesc["default"]
|
||||
else:
|
||||
have_max = "max" in procdesc and procdesc["max"] is not None
|
||||
have_min = "min" in procdesc and procdesc["min"] is not None
|
||||
if have_max and have_min:
|
||||
if procdesc["min"] <= 0 < procdesc["max"]:
|
||||
return 0
|
||||
elif have_min and not have_max:
|
||||
if procdesc["min"] >= 0:
|
||||
return procdesc["min"]
|
||||
elif not have_min and have_max:
|
||||
if procdesc["max"] < 0:
|
||||
return procdesc["max"]
|
||||
return 0
|
||||
|
||||
|
||||
|
@ -515,3 +515,26 @@ class NumpyBoolTest(ExperimentCase):
|
||||
def test_numpy_bool(self):
|
||||
"""Test NumPy bools decay to ARTIQ compiler builtin bools as expected"""
|
||||
self.create(_NumpyBool).run()
|
||||
|
||||
|
||||
class _Alignment(EnvExperiment):
|
||||
def build(self):
|
||||
self.setattr_device("core")
|
||||
|
||||
@rpc
|
||||
def a_tuple(self) -> TList(TTuple([TBool, TFloat, TBool])):
|
||||
return [(True, 1234.5678, True)]
|
||||
|
||||
@kernel
|
||||
def run(self):
|
||||
a, b, c = self.a_tuple()[0]
|
||||
d, e, f = self.a_tuple()[0]
|
||||
assert a == d
|
||||
assert b == e
|
||||
assert c == f
|
||||
return 0
|
||||
|
||||
|
||||
class AlignmentTest(ExperimentCase):
|
||||
def test_tuple(self):
|
||||
self.create(_Alignment).run()
|
||||
|
@ -1,9 +1,8 @@
|
||||
ARTIQ documentation
|
||||
===================
|
||||
|
||||
Contents:
|
||||
|
||||
.. toctree::
|
||||
:caption: Contents
|
||||
:maxdepth: 2
|
||||
|
||||
introduction
|
||||
|
104
flake.lock
generated
104
flake.lock
generated
@ -1,5 +1,29 @@
|
||||
{
|
||||
"nodes": {
|
||||
"artiq-comtools": {
|
||||
"inputs": {
|
||||
"nixpkgs": [
|
||||
"nac3",
|
||||
"nixpkgs"
|
||||
],
|
||||
"sipyco": [
|
||||
"sipyco"
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1644743100,
|
||||
"narHash": "sha256-XqxMq2l2DXSovV7r2k/FXjYRM3bvVl3Mjy+C1koVAx4=",
|
||||
"owner": "m-labs",
|
||||
"repo": "artiq-comtools",
|
||||
"rev": "8a126dd7d0a3f2d50ae151ec633cd52587d98796",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "m-labs",
|
||||
"repo": "artiq-comtools",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"mozilla-overlay": {
|
||||
"flake": false,
|
||||
"locked": {
|
||||
@ -16,6 +40,24 @@
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"nac3": {
|
||||
"inputs": {
|
||||
"nixpkgs": "nixpkgs"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1644759922,
|
||||
"narHash": "sha256-3hNFahCeHp0seppVONSlAMXIzn0vjCJGrJj6CySLLxw=",
|
||||
"ref": "master",
|
||||
"rev": "21d9182ba2924cf9cc555a201e661d2ea474eed9",
|
||||
"revCount": 594,
|
||||
"type": "git",
|
||||
"url": "https://git.m-labs.hk/M-Labs/nac3.git"
|
||||
},
|
||||
"original": {
|
||||
"type": "git",
|
||||
"url": "https://git.m-labs.hk/M-Labs/nac3.git"
|
||||
}
|
||||
},
|
||||
"nixpkgs": {
|
||||
"locked": {
|
||||
"lastModified": 1644472683,
|
||||
@ -34,11 +76,33 @@
|
||||
},
|
||||
"root": {
|
||||
"inputs": {
|
||||
"artiq-comtools": "artiq-comtools",
|
||||
"mozilla-overlay": "mozilla-overlay",
|
||||
"nac3": "nac3",
|
||||
"sipyco": "sipyco",
|
||||
"src-migen": "src-migen",
|
||||
"src-misoc": "src-misoc",
|
||||
"src-nac3": "src-nac3",
|
||||
"src-sipyco": "src-sipyco"
|
||||
"src-misoc": "src-misoc"
|
||||
}
|
||||
},
|
||||
"sipyco": {
|
||||
"inputs": {
|
||||
"nixpkgs": [
|
||||
"nac3",
|
||||
"nixpkgs"
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1644649772,
|
||||
"narHash": "sha256-LE9L5bDSunCPEnuf5Ed8enTAXA2vkTSmjvqPX9ILO0Y=",
|
||||
"owner": "m-labs",
|
||||
"repo": "sipyco",
|
||||
"rev": "8e4382352bc64bd01c9db35d9c9b0ef42b8b9d3b",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "m-labs",
|
||||
"repo": "sipyco",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"src-migen": {
|
||||
@ -74,40 +138,6 @@
|
||||
"type": "git",
|
||||
"url": "https://github.com/m-labs/misoc.git"
|
||||
}
|
||||
},
|
||||
"src-nac3": {
|
||||
"inputs": {
|
||||
"nixpkgs": "nixpkgs"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1644723702,
|
||||
"narHash": "sha256-2pLJHYvQmoXhdy3WDZpfU7kDMpgH/G7uREZOyql7R10=",
|
||||
"ref": "master",
|
||||
"rev": "4b8e70f7462b139e388f098d42f9f47e4915f431",
|
||||
"revCount": 589,
|
||||
"type": "git",
|
||||
"url": "https://git.m-labs.hk/M-Labs/nac3.git"
|
||||
},
|
||||
"original": {
|
||||
"type": "git",
|
||||
"url": "https://git.m-labs.hk/M-Labs/nac3.git"
|
||||
}
|
||||
},
|
||||
"src-sipyco": {
|
||||
"flake": false,
|
||||
"locked": {
|
||||
"lastModified": 1644649772,
|
||||
"narHash": "sha256-LE9L5bDSunCPEnuf5Ed8enTAXA2vkTSmjvqPX9ILO0Y=",
|
||||
"owner": "m-labs",
|
||||
"repo": "sipyco",
|
||||
"rev": "8e4382352bc64bd01c9db35d9c9b0ef42b8b9d3b",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "m-labs",
|
||||
"repo": "sipyco",
|
||||
"type": "github"
|
||||
}
|
||||
}
|
||||
},
|
||||
"root": "root",
|
||||
|
122
flake.nix
122
flake.nix
@ -2,20 +2,25 @@
|
||||
description = "A leading-edge control system for quantum information experiments";
|
||||
|
||||
inputs.mozilla-overlay = { url = github:mozilla/nixpkgs-mozilla; flake = false; };
|
||||
inputs.src-sipyco = { url = github:m-labs/sipyco; flake = false; };
|
||||
inputs.src-nac3 = { type = "git"; url = "https://git.m-labs.hk/M-Labs/nac3.git"; };
|
||||
inputs.sipyco.url = github:m-labs/sipyco;
|
||||
inputs.sipyco.inputs.nixpkgs.follows = "nac3/nixpkgs";
|
||||
inputs.nac3 = { type = "git"; url = "https://git.m-labs.hk/M-Labs/nac3.git"; };
|
||||
inputs.artiq-comtools.url = github:m-labs/artiq-comtools;
|
||||
inputs.artiq-comtools.inputs.nixpkgs.follows = "nac3/nixpkgs";
|
||||
inputs.artiq-comtools.inputs.sipyco.follows = "sipyco";
|
||||
|
||||
inputs.src-migen = { url = github:m-labs/migen; flake = false; };
|
||||
inputs.src-misoc = { type = "git"; url = "https://github.com/m-labs/misoc.git"; submodules = true; flake = false; };
|
||||
|
||||
outputs = { self, mozilla-overlay, src-sipyco, src-nac3, src-migen, src-misoc }:
|
||||
outputs = { self, mozilla-overlay, sipyco, nac3, artiq-comtools, src-migen, src-misoc }:
|
||||
let
|
||||
pkgs = import src-nac3.inputs.nixpkgs { system = "x86_64-linux"; overlays = [ (import mozilla-overlay) ]; };
|
||||
pkgs = import nac3.inputs.nixpkgs { system = "x86_64-linux"; overlays = [ (import mozilla-overlay) ]; };
|
||||
|
||||
artiqVersionMajor = 8;
|
||||
artiqVersionMinor = self.sourceInfo.revCount or 0;
|
||||
artiqVersionId = self.sourceInfo.shortRev or "unknown";
|
||||
artiqVersion = (builtins.toString artiqVersionMajor) + "." + (builtins.toString artiqVersionMinor) + "-" + artiqVersionId + "-beta";
|
||||
artiqVersion = (builtins.toString artiqVersionMajor) + "." + (builtins.toString artiqVersionMinor) + "." + artiqVersionId + ".beta";
|
||||
artiqRev = self.sourceInfo.rev or "unknown";
|
||||
|
||||
rustManifest = pkgs.fetchurl {
|
||||
url = "https://static.rust-lang.org/dist/2021-01-29/channel-rust-nightly.toml";
|
||||
@ -51,12 +56,6 @@
|
||||
fontconfig
|
||||
];
|
||||
|
||||
sipyco = pkgs.python3Packages.buildPythonPackage {
|
||||
name = "sipyco";
|
||||
src = src-sipyco;
|
||||
propagatedBuildInputs = with pkgs.python3Packages; [ pybase64 numpy ];
|
||||
};
|
||||
|
||||
qasync = pkgs.python3Packages.buildPythonPackage rec {
|
||||
pname = "qasync";
|
||||
version = "0.19.0";
|
||||
@ -78,11 +77,15 @@
|
||||
version = artiqVersion;
|
||||
src = self;
|
||||
|
||||
preBuild = "export VERSIONEER_OVERRIDE=${version}";
|
||||
preBuild =
|
||||
''
|
||||
export VERSIONEER_OVERRIDE=${version}
|
||||
export VERSIONEER_REV=${artiqRev}
|
||||
'';
|
||||
|
||||
nativeBuildInputs = [ pkgs.qt5.wrapQtAppsHook ];
|
||||
# keep llvm_x and lld_x in sync with nac3
|
||||
propagatedBuildInputs = [ pkgs.llvm_13 pkgs.lld_13 src-nac3.packages.x86_64-linux.nac3artiq sipyco ]
|
||||
propagatedBuildInputs = [ pkgs.llvm_13 pkgs.lld_13 nac3.packages.x86_64-linux.nac3artiq sipyco.packages.x86_64-linux.sipyco artiq-comtools.packages.x86_64-linux.artiq-comtools ]
|
||||
++ (with pkgs.python3Packages; [ pyqtgraph pygit2 numpy dateutil scipy prettytable pyserial h5py pyqt5 qasync ]);
|
||||
|
||||
dontWrapQtApps = true;
|
||||
@ -183,7 +186,7 @@
|
||||
};
|
||||
|
||||
makeArtiqBoardPackage = { target, variant, buildCommand ? "python -m artiq.gateware.targets.${target} -V ${variant}" }:
|
||||
pkgs.python3Packages.toPythonModule (pkgs.stdenv.mkDerivation {
|
||||
pkgs.stdenv.mkDerivation {
|
||||
name = "artiq-board-${target}-${variant}";
|
||||
phases = [ "buildPhase" "checkPhase" "installPhase" ];
|
||||
cargoDeps = rustPlatform.fetchCargoTarball {
|
||||
@ -192,7 +195,7 @@
|
||||
sha256 = "sha256-YyycMsDzR+JRcMZJd6A/CRi2J9nKmaWY/KXUnAQaZ00=";
|
||||
};
|
||||
nativeBuildInputs = [
|
||||
(pkgs.python3.withPackages(ps: [ migen misoc artiq ]))
|
||||
(pkgs.python3.withPackages(ps: [ ps.jsonschema migen misoc artiq]))
|
||||
rustPlatform.rust.rustc
|
||||
rustPlatform.rust.cargo
|
||||
pkgs.llvmPackages_13.clang-unwrapped
|
||||
@ -222,7 +225,7 @@
|
||||
'';
|
||||
installPhase =
|
||||
''
|
||||
TARGET_DIR=$out/${pkgs.python3Packages.python.sitePackages}/artiq/board-support/${target}-${variant}
|
||||
TARGET_DIR=$out
|
||||
mkdir -p $TARGET_DIR
|
||||
cp artiq_${target}/${variant}/gateware/top.bit $TARGET_DIR
|
||||
if [ -e artiq_${target}/${variant}/software/bootloader/bootloader.bin ]
|
||||
@ -235,7 +238,7 @@
|
||||
'';
|
||||
# don't mangle ELF files as they are not for NixOS
|
||||
dontFixup = true;
|
||||
});
|
||||
};
|
||||
|
||||
openocd-bscanspi = let
|
||||
bscan_spi_bitstreams-pkg = pkgs.stdenv.mkDerivation {
|
||||
@ -275,36 +278,79 @@
|
||||
name = "openocd-bscanspi";
|
||||
paths = [ openocd-fixed bscan_spi_bitstreams-pkg ];
|
||||
};
|
||||
|
||||
sphinxcontrib-wavedrom = pkgs.python3Packages.buildPythonPackage rec {
|
||||
pname = "sphinxcontrib-wavedrom";
|
||||
version = "3.0.2";
|
||||
src = pkgs.python3Packages.fetchPypi {
|
||||
inherit pname version;
|
||||
sha256 = "sha256-ukZd3ajt0Sx3LByof4R80S31F5t1yo+L8QUADrMMm2A=";
|
||||
};
|
||||
buildInputs = [ pkgs.python3Packages.setuptools_scm ];
|
||||
propagatedBuildInputs = [ pkgs.nodejs pkgs.nodePackages.wavedrom-cli ] ++ (with pkgs.python3Packages; [ wavedrom sphinx xcffib cairosvg ]);
|
||||
};
|
||||
latex-artiq-manual = pkgs.texlive.combine {
|
||||
inherit (pkgs.texlive)
|
||||
scheme-basic latexmk cmap collection-fontsrecommended fncychap
|
||||
titlesec tabulary varwidth framed fancyvrb float wrapfig parskip
|
||||
upquote capt-of needspace etoolbox;
|
||||
};
|
||||
in rec {
|
||||
packages.x86_64-linux = rec {
|
||||
inherit migen misoc vivadoEnv vivado openocd-bscanspi artiq;
|
||||
inherit (src-nac3.packages.x86_64-linux) python3-mimalloc;
|
||||
inherit (nac3.packages.x86_64-linux) python3-mimalloc;
|
||||
inherit qasync openocd-bscanspi artiq;
|
||||
inherit migen misoc asyncserial microscope vivadoEnv vivado;
|
||||
artiq-board-kc705-nist_clock = makeArtiqBoardPackage {
|
||||
target = "kc705";
|
||||
variant = "nist_clock";
|
||||
};
|
||||
artiq-board-kc705-nist_qc2 = makeArtiqBoardPackage {
|
||||
target = "kc705";
|
||||
variant = "nist_qc2";
|
||||
inherit sphinxcontrib-wavedrom latex-artiq-manual;
|
||||
artiq-manual-html = pkgs.stdenvNoCC.mkDerivation rec {
|
||||
name = "artiq-manual-html-${version}";
|
||||
version = artiqVersion;
|
||||
src = self;
|
||||
buildInputs = [
|
||||
pkgs.python3Packages.sphinx pkgs.python3Packages.sphinx_rtd_theme
|
||||
pkgs.python3Packages.sphinx-argparse sphinxcontrib-wavedrom
|
||||
];
|
||||
buildPhase = ''
|
||||
export VERSIONEER_OVERRIDE=${artiqVersion}
|
||||
export SOURCE_DATE_EPOCH=${builtins.toString self.sourceInfo.lastModified}
|
||||
cd doc/manual
|
||||
make html
|
||||
'';
|
||||
installPhase = ''
|
||||
cp -r _build/html $out
|
||||
mkdir $out/nix-support
|
||||
echo doc manual $out index.html >> $out/nix-support/hydra-build-products
|
||||
'';
|
||||
};
|
||||
artiq-board-kc705-nist_clock_master = makeArtiqBoardPackage {
|
||||
target = "kc705";
|
||||
variant = "nist_clock_master";
|
||||
};
|
||||
artiq-board-kc705-nist_qc2_master = makeArtiqBoardPackage {
|
||||
target = "kc705";
|
||||
variant = "nist_qc2_master";
|
||||
};
|
||||
artiq-board-kc705-nist_clock_satellite = makeArtiqBoardPackage {
|
||||
target = "kc705";
|
||||
variant = "nist_clock";
|
||||
};
|
||||
artiq-board-kc705-nist_qc2_satellite = makeArtiqBoardPackage {
|
||||
target = "kc705";
|
||||
variant = "nist_qc2";
|
||||
artiq-manual-pdf = pkgs.stdenvNoCC.mkDerivation rec {
|
||||
name = "artiq-manual-pdf-${version}";
|
||||
version = artiqVersion;
|
||||
src = self;
|
||||
buildInputs = [
|
||||
pkgs.python3Packages.sphinx pkgs.python3Packages.sphinx_rtd_theme
|
||||
pkgs.python3Packages.sphinx-argparse sphinxcontrib-wavedrom
|
||||
latex-artiq-manual
|
||||
];
|
||||
buildPhase = ''
|
||||
export VERSIONEER_OVERRIDE=${artiq.version}
|
||||
export SOURCE_DATE_EPOCH=${builtins.toString self.sourceInfo.lastModified}
|
||||
cd doc/manual
|
||||
make latexpdf
|
||||
'';
|
||||
installPhase = ''
|
||||
mkdir $out
|
||||
cp _build/latex/ARTIQ.pdf $out
|
||||
mkdir $out/nix-support
|
||||
echo doc-pdf manual $out ARTIQ.pdf >> $out/nix-support/hydra-build-products
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
inherit makeArtiqBoardPackage;
|
||||
|
||||
defaultPackage.x86_64-linux = packages.x86_64-linux.python3-mimalloc.withPackages(ps: [ packages.x86_64-linux.artiq ]);
|
||||
|
||||
devShell.x86_64-linux = pkgs.mkShell {
|
||||
@ -321,6 +367,8 @@
|
||||
packages.x86_64-linux.vivadoEnv
|
||||
packages.x86_64-linux.vivado
|
||||
packages.x86_64-linux.openocd-bscanspi
|
||||
pkgs.python3Packages.sphinx pkgs.python3Packages.sphinx_rtd_theme
|
||||
pkgs.python3Packages.sphinx-argparse sphinxcontrib-wavedrom latex-artiq-manual
|
||||
];
|
||||
};
|
||||
|
||||
|
1
setup.py
1
setup.py
@ -35,6 +35,7 @@ console_scripts = [
|
||||
"artiq_run = artiq.frontend.artiq_run:main",
|
||||
"artiq_flash = artiq.frontend.artiq_flash:main",
|
||||
"aqctl_corelog = artiq.frontend.aqctl_corelog:main",
|
||||
"afws_client = artiq.frontend.afws_client:main",
|
||||
]
|
||||
|
||||
gui_scripts = [
|
||||
|
@ -1,9 +1,13 @@
|
||||
import os
|
||||
import sys
|
||||
|
||||
|
||||
VERSION_FILE = """
|
||||
def get_version():
|
||||
return "{version}"
|
||||
|
||||
def get_rev():
|
||||
return "{rev}"
|
||||
"""
|
||||
|
||||
def get_version():
|
||||
@ -18,10 +22,13 @@ def get_version():
|
||||
version += ".beta"
|
||||
return version
|
||||
|
||||
def write_to_version_file(filename, version):
|
||||
def get_rev():
|
||||
return os.getenv("VERSIONEER_REV", default="unknown")
|
||||
|
||||
def write_to_version_file(filename, version, rev):
|
||||
os.unlink(filename)
|
||||
with open(filename, "w") as f:
|
||||
f.write(VERSION_FILE.format(version=version))
|
||||
f.write(VERSION_FILE.format(version=version, rev=rev))
|
||||
|
||||
|
||||
def get_cmdclass():
|
||||
@ -36,11 +43,12 @@ def get_cmdclass():
|
||||
class cmd_build_py(_build_py):
|
||||
def run(self):
|
||||
version = get_version()
|
||||
rev = get_rev()
|
||||
_build_py.run(self)
|
||||
target_versionfile = os.path.join(self.build_lib,
|
||||
"artiq", "_version.py")
|
||||
print("UPDATING %s" % target_versionfile)
|
||||
write_to_version_file(target_versionfile, version)
|
||||
write_to_version_file(target_versionfile, version, rev)
|
||||
cmds["build_py"] = cmd_build_py
|
||||
|
||||
|
||||
@ -54,6 +62,7 @@ def get_cmdclass():
|
||||
def run(self):
|
||||
version = get_version()
|
||||
self._versioneer_generated_version = version
|
||||
self._versioneer_rev = get_rev()
|
||||
# unless we update this, the command will keep using the old
|
||||
# version
|
||||
self.distribution.metadata.version = version
|
||||
@ -64,7 +73,8 @@ def get_cmdclass():
|
||||
target_versionfile = os.path.join(base_dir, "artiq", "_version.py")
|
||||
print("UPDATING %s" % target_versionfile)
|
||||
write_to_version_file(target_versionfile,
|
||||
self._versioneer_generated_version)
|
||||
self._versioneer_generated_version,
|
||||
self._versioneer_rev)
|
||||
cmds["sdist"] = cmd_sdist
|
||||
|
||||
return cmds
|
||||
|
Loading…
Reference in New Issue
Block a user