From 9a96387dfe1dd6012c6991719c20bfdba72e15b6 Mon Sep 17 00:00:00 2001 From: ciciwu <89900858+ciciwu213@users.noreply.github.com> Date: Tue, 8 Mar 2022 19:03:30 +0800 Subject: [PATCH 1/6] phaser: fix docstring formatting (#1866) --- artiq/coredevice/phaser.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/artiq/coredevice/phaser.py b/artiq/coredevice/phaser.py index 5f7cd7108..c9bf0c479 100644 --- a/artiq/coredevice/phaser.py +++ b/artiq/coredevice/phaser.py @@ -460,8 +460,7 @@ class Phaser: * :const:`PHASER_STA_TRF1_LD`: Quadrature upconverter 1 lock detect * :const:`PHASER_STA_TERM0`: ADC channel 0 termination indicator * :const:`PHASER_STA_TERM1`: ADC channel 1 termination indicator - * :const:`PHASER_STA_SPI_IDLE`: SPI machine is idle and data registers - can be read/written + * :const:`PHASER_STA_SPI_IDLE`: SPI machine is idle and data registers can be read/written :return: Status register """ @@ -750,10 +749,11 @@ class PhaserChannel: * multiple oscillators (in the coredevice phy), * an interpolation chain and digital upconverter (DUC) on Phaser, * several channel-specific settings in the DAC: + * quadrature modulation compensation QMC * numerically controlled oscillator NCO or coarse mixer CMIX, - * the analog quadrature upconverter (in the Phaser-Upconverter hardware - variant), and + + * the analog quadrature upconverter (in the Phaser-Upconverter hardware variant), and * a digitally controlled step attenuator. Attributes: From 67ca48fa8414c7316a10efc8359952f717487efa Mon Sep 17 00:00:00 2001 From: ciciwu <89900858+ciciwu213@users.noreply.github.com> Date: Tue, 8 Mar 2022 19:03:47 +0800 Subject: [PATCH 2/6] manual: fix formatting (#1865) --- doc/manual/core_device.rst | 2 ++ 1 file changed, 2 insertions(+) diff --git a/doc/manual/core_device.rst b/doc/manual/core_device.rst index fa3466d32..6ba064e52 100644 --- a/doc/manual/core_device.rst +++ b/doc/manual/core_device.rst @@ -165,10 +165,12 @@ Clocking ++++++++ The KC705 in standalone variants supports an internal 125 MHz RTIO clock (based on its crystal oscillator, or external reference for PLL for DRTIO variants) and an external clock, that can be selected using the ``rtio_clock`` configuration entry. Valid values are: + * ``int_125`` - internal crystal oscillator, 125 MHz output (default), * ``ext0_bypass`` - external clock. KC705 in DRTIO variants and Kasli generates the RTIO clock using a PLL locked either to an internal crystal or to an external frequency reference. Valid values are: + * ``int_125`` - internal crystal oscillator using PLL, 125 MHz output (default), * ``int_100`` - internal crystal oscillator using PLL, 100 MHz output, * ``int_150`` - internal crystal oscillator using PLL, 150 MHz output, From 8415151866ae7e82ffcb159a37d1309994615c89 Mon Sep 17 00:00:00 2001 From: Sebastien Bourdeauducq Date: Thu, 10 Mar 2022 11:56:16 +0800 Subject: [PATCH 3/6] update copyright year --- README.rst | 2 +- artiq/firmware/bootloader/main.rs | 2 +- doc/manual/conf.py | 2 +- doc/manual/introduction.rst | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/README.rst b/README.rst index 537745b9a..216c77ba1 100644 --- a/README.rst +++ b/README.rst @@ -29,7 +29,7 @@ Website: https://m-labs.hk/artiq License ======= -Copyright (C) 2014-2021 M-Labs Limited. +Copyright (C) 2014-2022 M-Labs Limited. ARTIQ is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by diff --git a/artiq/firmware/bootloader/main.rs b/artiq/firmware/bootloader/main.rs index 8c428bedb..555f8b0b6 100644 --- a/artiq/firmware/bootloader/main.rs +++ b/artiq/firmware/bootloader/main.rs @@ -493,7 +493,7 @@ pub extern fn main() -> i32 { println!(r"|_| |_|_|____/ \___/ \____|"); println!(""); println!("MiSoC Bootloader"); - println!("Copyright (c) 2017-2021 M-Labs Limited"); + println!("Copyright (c) 2017-2022 M-Labs Limited"); println!(""); #[cfg(has_ethmac)] diff --git a/doc/manual/conf.py b/doc/manual/conf.py index bc092928f..d6e6f9a6c 100644 --- a/doc/manual/conf.py +++ b/doc/manual/conf.py @@ -94,7 +94,7 @@ master_doc = 'index' # General information about the project. project = 'ARTIQ' -copyright = '2014-2021, M-Labs Limited' +copyright = '2014-2022, M-Labs Limited' # The version info for the project you're documenting, acts as replacement for # |version| and |release|, also used in various other places throughout the diff --git a/doc/manual/introduction.rst b/doc/manual/introduction.rst index 7dcc2f802..23eaa98a9 100644 --- a/doc/manual/introduction.rst +++ b/doc/manual/introduction.rst @@ -27,4 +27,4 @@ Website: https://m-labs.hk/artiq `Cite ARTIQ `_ as ``Bourdeauducq, Sébastien et al. (2016). ARTIQ 1.0. Zenodo. 10.5281/zenodo.51303``. -Copyright (C) 2014-2021 M-Labs Limited. Licensed under GNU LGPL version 3+. +Copyright (C) 2014-2022 M-Labs Limited. Licensed under GNU LGPL version 3+. From eb6817c8f1b76583eae92d700e2b42bf3f5e829e Mon Sep 17 00:00:00 2001 From: pca006132 Date: Thu, 10 Mar 2022 16:05:18 +0800 Subject: [PATCH 4/6] compiler/transforms/llvm_ir_generator: changed list representation The representation of TList(T) is changed from `{T*, u32}` to `{T*, u32}*`. The old representation forbids changing the length of a list when the list is passed as a parameter into functions, as the length is passed by value. The representation now matches with nac3. --- .../compiler/transforms/llvm_ir_generator.py | 61 ++++++++++++++++--- 1 file changed, 52 insertions(+), 9 deletions(-) diff --git a/artiq/compiler/transforms/llvm_ir_generator.py b/artiq/compiler/transforms/llvm_ir_generator.py index 8017981d3..197bc2cdf 100644 --- a/artiq/compiler/transforms/llvm_ir_generator.py +++ b/artiq/compiler/transforms/llvm_ir_generator.py @@ -253,7 +253,10 @@ class LLVMIRGenerator: return ll.LiteralStructType([llbufferty, llshapety]) elif builtins.is_listish(typ): lleltty = self.llty_of_type(builtins.get_iterable_elt(typ)) - return ll.LiteralStructType([lleltty.as_pointer(), lli32]) + lltyp = ll.LiteralStructType([lleltty.as_pointer(), lli32]) + if builtins.is_list(typ): + lltyp = lltyp.as_pointer() + return lltyp elif builtins.is_range(typ): lleltty = self.llty_of_type(builtins.get_iterable_elt(typ)) return ll.LiteralStructType([lleltty, lleltty, lleltty]) @@ -782,9 +785,20 @@ class LLVMIRGenerator: llalloc = self.llbuilder.alloca(lleltty, size=llsize) if types._is_pointer(insn.type): return llalloc - llvalue = ll.Constant(self.llty_of_type(insn.type), ll.Undefined) - llvalue = self.llbuilder.insert_value(llvalue, llalloc, 0, name=insn.name) - llvalue = self.llbuilder.insert_value(llvalue, llsize, 1) + if builtins.is_list(insn.type): + llvalue = self.llbuilder.alloca(self.llty_of_type(insn.type).pointee, size=1) + self.llbuilder.store(llalloc, self.llbuilder.gep(llvalue, + [self.llindex(0), + self.llindex(0)], + inbounds=True)) + self.llbuilder.store(llsize, self.llbuilder.gep(llvalue, + [self.llindex(0), + self.llindex(1)], + inbounds=True)) + else: + llvalue = ll.Constant(self.llty_of_type(insn.type), ll.Undefined) + llvalue = self.llbuilder.insert_value(llvalue, llalloc, 0) + llvalue = self.llbuilder.insert_value(llvalue, llsize, 1) return llvalue elif (not builtins.is_allocated(insn.type) or ir.is_keyword(insn.type) or builtins.is_array(insn.type)): @@ -988,9 +1002,15 @@ class LLVMIRGenerator: def process_Offset(self, insn): base, idx = insn.base(), insn.index() llelts, llidx = map(self.map, (base, idx)) - if not types._is_pointer(base.type): + if builtins.is_listish(base.type): # This is list-ish. - llelts = self.llbuilder.extract_value(llelts, 0) + if builtins.is_list(base.type): + llelts = self.llbuilder.load(self.llbuilder.gep(llelts, + [self.llindex(0), + self.llindex(0)], + inbounds=True)) + else: + llelts = self.llbuilder.extract_value(llelts, 0) llelt = self.llbuilder.gep(llelts, [llidx], inbounds=True) return llelt @@ -1004,9 +1024,15 @@ class LLVMIRGenerator: def process_SetElem(self, insn): base, idx = insn.base(), insn.index() llelts, llidx = map(self.map, (base, idx)) - if not types._is_pointer(base.type): + if builtins.is_listish(base.type): # This is list-ish. - llelts = self.llbuilder.extract_value(llelts, 0) + if builtins.is_list(base.type): + llelts = self.llbuilder.load(self.llbuilder.gep(llelts, + [self.llindex(0), + self.llindex(0)], + inbounds=True)) + else: + llelts = self.llbuilder.extract_value(llelts, 0) llelt = self.llbuilder.gep(llelts, [llidx], inbounds=True) return self.llbuilder.store(self.map(insn.value()), llelt) @@ -1152,6 +1178,11 @@ class LLVMIRGenerator: lllhs, llrhs = map(self.map, (insn.lhs(), insn.rhs())) assert lllhs.type == llrhs.type + if isinstance(lllhs.type, ll.PointerType) and \ + isinstance(lllhs.type.pointee, ll.LiteralStructType): + lllhs = self.llbuilder.load(lllhs) + llrhs = self.llbuilder.load(llrhs) + if isinstance(lllhs.type, ll.IntType): return self.llbuilder.icmp_signed(op, lllhs, llrhs, name=insn.name) @@ -1222,7 +1253,12 @@ class LLVMIRGenerator: shape = self.llbuilder.extract_value(self.map(collection), self.attr_index(collection.type, "shape")) return self.llbuilder.extract_value(shape, 0) - return self.llbuilder.extract_value(self.map(collection), 1) + elif builtins.is_list(collection.type): + return self.llbuilder.load(self.llbuilder.gep(self.map(collection), + [self.llindex(0), + self.llindex(1)])) + else: + return self.llbuilder.extract_value(self.map(collection), 1) elif insn.op in ("printf", "rtio_log"): # We only get integers, floats, pointers and strings here. lloperands = [] @@ -1677,6 +1713,13 @@ class LLVMIRGenerator: assert isinstance(value, (list, numpy.ndarray)), fail_msg elt_type = builtins.get_iterable_elt(typ) lleltsptr = self._quote_listish_to_llglobal(value, elt_type, path, typ.find().name) + if builtins.is_list(typ): + llconst = ll.Constant(llty.pointee, [lleltsptr, ll.Constant(lli32, len(value))]) + name = self.llmodule.scope.deduplicate("quoted.{}".format(typ.find().name)) + llglobal = ll.GlobalVariable(self.llmodule, llconst.type, name) + llglobal.initializer = llconst + llglobal.linkage = "private" + return llglobal llconst = ll.Constant(llty, [lleltsptr, ll.Constant(lli32, len(value))]) return llconst elif types.is_tuple(typ): From ebfeb1869fff1f11a40bba05e19a0b4e09cb02bd Mon Sep 17 00:00:00 2001 From: pca006132 Date: Thu, 10 Mar 2022 16:08:20 +0800 Subject: [PATCH 5/6] firmware: use &CSlice for lists --- artiq/firmware/ksupport/lib.rs | 7 ++- artiq/firmware/libproto_artiq/kernel_proto.rs | 3 +- artiq/firmware/libproto_artiq/rpc_proto.rs | 21 ++++---- artiq/firmware/runtime/cache.rs | 48 +++++++++++++++---- artiq/firmware/runtime/session.rs | 2 +- 5 files changed, 57 insertions(+), 24 deletions(-) diff --git a/artiq/firmware/ksupport/lib.rs b/artiq/firmware/ksupport/lib.rs index 1a1528494..2e7346c19 100644 --- a/artiq/firmware/ksupport/lib.rs +++ b/artiq/firmware/ksupport/lib.rs @@ -15,7 +15,7 @@ extern crate proto_artiq; extern crate riscv; use core::{mem, ptr, slice, str, convert::TryFrom}; -use cslice::{CSlice, AsCSlice}; +use cslice::CSlice; use io::Cursor; use dyld::Library; use board_artiq::{mailbox, rpc_queue}; @@ -190,13 +190,12 @@ fn terminate(exceptions: &'static [Option>], } #[unwind(aborts)] -extern fn cache_get<'a>(ret: &'a mut CSlice, key: &CSlice) -> &'a CSlice<'a, i32> { +extern fn cache_get<'a>(key: &CSlice) -> *const CSlice<'a, i32> { send(&CacheGetRequest { key: str::from_utf8(key.as_ref()).unwrap() }); recv!(&CacheGetReply { value } => { - *ret = value.as_c_slice(); - ret + value }) } diff --git a/artiq/firmware/libproto_artiq/kernel_proto.rs b/artiq/firmware/libproto_artiq/kernel_proto.rs index 3021447ec..8b07ea46b 100644 --- a/artiq/firmware/libproto_artiq/kernel_proto.rs +++ b/artiq/firmware/libproto_artiq/kernel_proto.rs @@ -1,4 +1,5 @@ use core::fmt; +use cslice::CSlice; use dyld; pub const KERNELCPU_EXEC_ADDRESS: usize = 0x45000000; @@ -53,7 +54,7 @@ pub enum Message<'a> { RpcFlush, CacheGetRequest { key: &'a str }, - CacheGetReply { value: &'static [i32] }, + CacheGetReply { value: *const CSlice<'static, i32> }, CachePutRequest { key: &'a str, value: &'a [i32] }, CachePutReply { succeeded: bool }, diff --git a/artiq/firmware/libproto_artiq/rpc_proto.rs b/artiq/firmware/libproto_artiq/rpc_proto.rs index a93a0e82c..5750d524e 100644 --- a/artiq/firmware/libproto_artiq/rpc_proto.rs +++ b/artiq/firmware/libproto_artiq/rpc_proto.rs @@ -70,16 +70,17 @@ unsafe fn recv_value(reader: &mut R, tag: Tag, data: &mut *mut (), Tag::List(it) => { #[repr(C)] struct List { elements: *mut (), length: u32 } - consume_value!(List, |ptr| { - (*ptr).length = reader.read_u32()?; - let length = (*ptr).length as usize; - + consume_value!(*mut List, |ptr| { let tag = it.clone().next().expect("truncated tag"); let padding = if let Tag::Int64 | Tag::Float64 = tag { 4 } else { 0 }; - let mut data = alloc(tag.size() * length + padding)?; - data = data.offset(alignment_offset(tag.alignment() as isize, data as isize)); + let length = reader.read_u32()? as usize; + let data = alloc(tag.size() * length + padding + 8)? as *mut u8; + *ptr = data as *mut List; + let ptr = data as *mut List; + let mut data = data.offset(8 + alignment_offset(tag.alignment() as isize, data as isize)) as *mut (); + (*ptr).length = length as u32; (*ptr).elements = data; match tag { Tag::Bool => { @@ -221,11 +222,11 @@ unsafe fn send_value(writer: &mut W, tag: Tag, data: &mut *const ()) Tag::List(it) => { #[repr(C)] struct List { elements: *const (), length: u32 } - consume_value!(List, |ptr| { - let length = (*ptr).length as usize; - writer.write_u32((*ptr).length)?; + consume_value!(&List, |ptr| { + let length = (**ptr).length as usize; + writer.write_u32((**ptr).length)?; let tag = it.clone().next().expect("truncated tag"); - let mut data = (*ptr).elements; + let mut data = (**ptr).elements; writer.write_u8(tag.as_u8())?; match tag { // we cannot use NativeEndian::from_slice_i32 as the data is not mutable, diff --git a/artiq/firmware/runtime/cache.rs b/artiq/firmware/runtime/cache.rs index a950fab3b..ba6898653 100644 --- a/artiq/firmware/runtime/cache.rs +++ b/artiq/firmware/runtime/cache.rs @@ -1,27 +1,50 @@ use alloc::{vec::Vec, string::String, collections::btree_map::BTreeMap}; +use cslice::{CSlice, AsCSlice}; +use core::mem::transmute; -#[derive(Debug)] struct Entry { data: Vec, + slice: CSlice<'static, i32>, borrowed: bool } -#[derive(Debug)] +impl core::fmt::Debug for Entry { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + f.debug_struct("Entry") + .field("data", &self.data) + .field("borrowed", &self.borrowed) + .finish() + } +} + pub struct Cache { - entries: BTreeMap + entries: BTreeMap, + empty: CSlice<'static, i32>, +} + +impl core::fmt::Debug for Cache { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + f.debug_struct("Cache") + .field("entries", &self.entries) + .finish() + } } impl Cache { pub fn new() -> Cache { - Cache { entries: BTreeMap::new() } + let empty_vec = vec![]; + let empty = unsafe { + transmute::, CSlice<'static, i32>>(empty_vec.as_c_slice()) + }; + Cache { entries: BTreeMap::new(), empty } } - pub fn get(&mut self, key: &str) -> *const [i32] { + pub fn get(&mut self, key: &str) -> *const CSlice<'static, i32> { match self.entries.get_mut(key) { - None => &[], + None => &self.empty, Some(ref mut entry) => { entry.borrowed = true; - &entry.data[..] + &entry.slice } } } @@ -32,12 +55,21 @@ impl Cache { Some(ref mut entry) => { if entry.borrowed { return Err(()) } entry.data = Vec::from(data); + unsafe { + entry.slice = transmute::, CSlice<'static, i32>>( + entry.data.as_c_slice()); + } return Ok(()) } } + let data = Vec::from(data); + let slice = unsafe { + transmute::, CSlice<'static, i32>>(data.as_c_slice()) + }; self.entries.insert(String::from(key), Entry { - data: Vec::from(data), + data, + slice, borrowed: false }); Ok(()) diff --git a/artiq/firmware/runtime/session.rs b/artiq/firmware/runtime/session.rs index bf374eb5d..aec47afe1 100644 --- a/artiq/firmware/runtime/session.rs +++ b/artiq/firmware/runtime/session.rs @@ -418,7 +418,7 @@ fn process_kern_message(io: &Io, aux_mutex: &Mutex, kern_send(io, &kern::CacheGetReply { // Zing! This transmute is only safe because we dynamically track // whether the kernel has borrowed any values from the cache. - value: unsafe { mem::transmute::<*const [i32], &'static [i32]>(value) } + value: unsafe { mem::transmute(value) } }) } From 71e8b49246de34890db6529dfbe80ab38ce15f75 Mon Sep 17 00:00:00 2001 From: Sebastien Bourdeauducq Date: Thu, 10 Mar 2022 17:04:28 +0800 Subject: [PATCH 6/6] update nix dependencies --- flake.lock | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/flake.lock b/flake.lock index 38f992b86..3cb5b834f 100644 --- a/flake.lock +++ b/flake.lock @@ -26,11 +26,11 @@ "mozilla-overlay": { "flake": false, "locked": { - "lastModified": 1643634764, - "narHash": "sha256-EcFlgzZnZSHwZixELYV1pa267t+u5mCeLhSNBeAA/+c=", + "lastModified": 1645464064, + "narHash": "sha256-YeN4bpPvHkVOpQzb8APTAfE7/R+MFMwJUMkqmfvytSk=", "owner": "mozilla", "repo": "nixpkgs-mozilla", - "rev": "f233fdc4ff6ba2ffeb1e3e3cd6d63bb1297d6996", + "rev": "15b7a05f20aab51c4ffbefddb1b448e862dccb7d", "type": "github" }, "original": { @@ -41,11 +41,11 @@ }, "nixpkgs": { "locked": { - "lastModified": 1644472683, - "narHash": "sha256-sP6iM4NksOYO6NFfTJ96cg+ClPnq6cdY30xKA1iYtyU=", + "lastModified": 1646588256, + "narHash": "sha256-ZHljmNlt19nSm0Mz8fx6QEhddKUkU4hhwFmfNmGn+EY=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "7adc9c14ec74b27358a8df9b973087e351425a79", + "rev": "2ebb6c1e5ae402ba35cca5eec58385e5f1adea04", "type": "github" }, "original": {