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: 4df7941a9797
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: a964cf24f285
Choose a head ref
  • 3 commits
  • 3 files changed
  • 1 contributor

Commits on Nov 23, 2016

  1. 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.
    jordens committed Nov 23, 2016
    Copy the full SHA
    347609d View commit details
  2. runtime.rs: wide rtio data

    jordens committed Nov 23, 2016
    Copy the full SHA
    8cce5d2 View commit details
  3. runtime.rs/rtio.rs: style

    jordens committed Nov 23, 2016
    Copy the full SHA
    a964cf2 View commit details
Showing with 50 additions and 6 deletions.
  1. +10 −2 artiq/gateware/rtio/core.py
  2. +1 −0 artiq/runtime.rs/libksupport/api.rs
  3. +39 −4 artiq/runtime.rs/libksupport/rtio.rs
12 changes: 10 additions & 2 deletions artiq/gateware/rtio/core.py
Original file line number Diff line number Diff line change
@@ -334,9 +334,9 @@ def __init__(self, chan_sel_width,
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 @@ def __init__(self, channels, full_ts_width=63, guard_io_cycles=20):
<< 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()
1 change: 1 addition & 0 deletions artiq/runtime.rs/libksupport/api.rs
Original file line number Diff line number Diff line change
@@ -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),

43 changes: 39 additions & 4 deletions artiq/runtime.rs/libksupport/rtio.rs
Original file line number Diff line number Diff line change
@@ -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,19 @@ 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 +74,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 +154,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 +171,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);
}
}