From 347609d7651c5e7cf59e905c45b5b8973c34080d Mon Sep 17 00:00:00 2001 From: Robert Jordens Date: Sat, 19 Nov 2016 14:16:06 +0100 Subject: [PATCH 1/3] rtio: auto clear output event data and address This is to support channels where variable length event data is well-defined through zero-padding. E.g. in the case of `Spline` zero-padding of events naturally corresponds to low-order knots. Use timestamp change as trigger. This assumes that writes to the timestamp register always precede address and data writes. It does not break support for ganged writes of the same event timestamp and data/address to multiple channels or channel-addresses. --- artiq/gateware/rtio/core.py | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/artiq/gateware/rtio/core.py b/artiq/gateware/rtio/core.py index a248632da..4d5624684 100644 --- a/artiq/gateware/rtio/core.py +++ b/artiq/gateware/rtio/core.py @@ -334,9 +334,9 @@ class _KernelCSRs(AutoCSR): self.chan_sel = CSRStorage(chan_sel_width) if data_width: - self.o_data = CSRStorage(data_width) + self.o_data = CSRStorage(data_width, write_from_dev=True) if address_width: - self.o_address = CSRStorage(address_width) + self.o_address = CSRStorage(address_width, write_from_dev=True) self.o_timestamp = CSRStorage(full_ts_width) self.o_we = CSR() self.o_status = CSRStatus(5) @@ -498,5 +498,13 @@ class RTIO(Module): << fine_ts_width) ) + # Auto clear/zero pad event data + self.comb += [ + self.kcsrs.o_data.dat_w.eq(0), + self.kcsrs.o_data.we.eq(self.kcsrs.o_timestamp.re), + self.kcsrs.o_address.dat_w.eq(0), + self.kcsrs.o_address.we.eq(self.kcsrs.o_timestamp.re), + ] + def get_csrs(self): return self.kcsrs.get_csrs() From 8cce5d2fcdaa936bb47d708007f2b4bd755a583a Mon Sep 17 00:00:00 2001 From: Robert Jordens Date: Mon, 21 Nov 2016 23:12:16 +0100 Subject: [PATCH 2/3] runtime.rs: wide rtio data --- artiq/runtime.rs/libksupport/api.rs | 1 + artiq/runtime.rs/libksupport/rtio.rs | 45 +++++++++++++++++++++++++--- 2 files changed, 42 insertions(+), 4 deletions(-) diff --git a/artiq/runtime.rs/libksupport/api.rs b/artiq/runtime.rs/libksupport/api.rs index dbfbd759b..57b6302d8 100644 --- a/artiq/runtime.rs/libksupport/api.rs +++ b/artiq/runtime.rs/libksupport/api.rs @@ -102,6 +102,7 @@ static mut API: &'static [(&'static str, *const ())] = &[ api!(rtio_get_counter = ::rtio::get_counter), api!(rtio_log), api!(rtio_output = ::rtio::output), + api!(rtio_output_list = ::rtio::output_list), api!(rtio_input_timestamp = ::rtio::input_timestamp), api!(rtio_input_data = ::rtio::input_data), diff --git a/artiq/runtime.rs/libksupport/rtio.rs b/artiq/runtime.rs/libksupport/rtio.rs index 4363b255d..eaeb4d01c 100644 --- a/artiq/runtime.rs/libksupport/rtio.rs +++ b/artiq/runtime.rs/libksupport/rtio.rs @@ -1,4 +1,6 @@ use board::csr; +use core::ptr::{read_volatile, write_volatile}; +use core::slice; const RTIO_O_STATUS_FULL: u32 = 1; const RTIO_O_STATUS_UNDERFLOW: u32 = 2; @@ -23,6 +25,21 @@ pub extern fn get_counter() -> i64 { } } +#[inline(always)] +pub unsafe fn rtio_o_data_write(w: u32) { + write_volatile( + csr::rtio::O_DATA_ADDR.offset((csr::rtio::O_DATA_SIZE - 1) as isize), + w); +} + +#[inline(always)] +pub unsafe fn rtio_i_data_read() -> u32 { + read_volatile( + csr::rtio::I_DATA_ADDR.offset((csr::rtio::I_DATA_SIZE - 1) as isize) + ) +} + + #[inline(never)] unsafe fn process_exceptional_status(timestamp: i64, channel: u32, status: u32) { if status & RTIO_O_STATUS_FULL != 0 { @@ -59,7 +76,27 @@ pub extern fn output(timestamp: i64, channel: u32, addr: u32, data: u32) { csr::rtio::chan_sel_write(channel); csr::rtio::o_timestamp_write(timestamp as u64); csr::rtio::o_address_write(addr); - csr::rtio::o_data_write(data); + rtio_o_data_write(data); + csr::rtio::o_we_write(1); + let status = csr::rtio::o_status_read(); + if status != 0 { + process_exceptional_status(timestamp, channel, status); + } + } +} + +pub extern fn output_list(timestamp: i64, channel: u32, addr: u32, + &(len, ptr): &(usize, *const u32)) { + unsafe { + csr::rtio::chan_sel_write(channel); + csr::rtio::o_timestamp_write(timestamp as u64); + csr::rtio::o_address_write(addr); + let data = slice::from_raw_parts(ptr, len); + for i in 0..data.len() { + write_volatile( + csr::rtio::O_DATA_ADDR.offset((csr::rtio::O_DATA_SIZE - 1 - i) as isize), + data[i]); + } csr::rtio::o_we_write(1); let status = csr::rtio::o_status_read(); if status != 0 { @@ -119,7 +156,7 @@ pub extern fn input_data(channel: u32) -> u32 { } } - let data = csr::rtio::i_data_read(); + let data = rtio_i_data_read(); csr::rtio::i_re_write(1); data } @@ -136,14 +173,14 @@ pub fn log(timestamp: i64, data: &[u8]) { word <<= 8; word |= data[i] as u32; if i % 4 == 0 { - csr::rtio::o_data_write(word); + rtio_o_data_write(word); csr::rtio::o_we_write(1); word = 0; } } word <<= 8; - csr::rtio::o_data_write(word); + rtio_o_data_write(word); csr::rtio::o_we_write(1); } } From a964cf24f285849b9398fecab95a29372ec01547 Mon Sep 17 00:00:00 2001 From: Robert Jordens Date: Wed, 23 Nov 2016 14:56:20 +0100 Subject: [PATCH 3/3] runtime.rs/rtio.rs: style --- artiq/runtime.rs/libksupport/rtio.rs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/artiq/runtime.rs/libksupport/rtio.rs b/artiq/runtime.rs/libksupport/rtio.rs index eaeb4d01c..60dadc815 100644 --- a/artiq/runtime.rs/libksupport/rtio.rs +++ b/artiq/runtime.rs/libksupport/rtio.rs @@ -35,11 +35,9 @@ pub unsafe fn rtio_o_data_write(w: u32) { #[inline(always)] pub unsafe fn rtio_i_data_read() -> u32 { read_volatile( - csr::rtio::I_DATA_ADDR.offset((csr::rtio::I_DATA_SIZE - 1) as isize) - ) + csr::rtio::I_DATA_ADDR.offset((csr::rtio::I_DATA_SIZE - 1) as isize)) } - #[inline(never)] unsafe fn process_exceptional_status(timestamp: i64, channel: u32, status: u32) { if status & RTIO_O_STATUS_FULL != 0 {