gateware,runtime: optimize RTIO kernel interface further

* now pinning (TODO: atomicity)
* for inputs, merge request and timeout registers
pull/1212/head
Sebastien Bourdeauducq 2018-11-08 18:29:24 +08:00
parent aadf5112b7
commit 8caea0e6d3
26 changed files with 99 additions and 100 deletions

View File

@ -1946,8 +1946,7 @@ class ARTIQIRGenerator(algorithm.Visitor):
def printf(format_string, *args):
format = ir.Constant(format_string, builtins.TStr())
if as_rtio:
now_mu = self.append(ir.Builtin("now_mu", [], builtins.TInt64()))
self.append(ir.Builtin("rtio_log", [now_mu, format, *args], builtins.TNone()))
self.append(ir.Builtin("rtio_log", [format, *args], builtins.TNone()))
else:
self.append(ir.Builtin("printf", [format, *args], builtins.TNone()))

View File

@ -336,7 +336,7 @@ class LLVMIRGenerator:
elif name == self.target.print_function:
llty = ll.FunctionType(llvoid, [llptr], var_arg=True)
elif name == "rtio_log":
llty = ll.FunctionType(llvoid, [lli64, llptr], var_arg=True)
llty = ll.FunctionType(llvoid, [llptr], var_arg=True)
elif name == "__artiq_personality":
llty = ll.FunctionType(lli32, [], var_arg=True)
elif name == "__artiq_raise":
@ -1137,7 +1137,7 @@ class LLVMIRGenerator:
lloperands = []
for i, operand in enumerate(insn.operands):
lloperand = self.map(operand)
if i == 0 and insn.op == "printf" or i == 1 and insn.op == "rtio_log":
if i == 0 and (insn.op == "printf" or insn.op == "rtio_log"):
lloperands.append(self.llbuilder.extract_value(lloperand, 0))
elif builtins.is_str(operand.type) or builtins.is_bytes(operand.type):
lloperands.append(self.llbuilder.extract_value(lloperand, 1))

View File

@ -3,13 +3,12 @@ from artiq.language.types import TInt64, TInt32, TNone, TList
@syscall(flags={"nowrite"})
def rtio_output(time_mu: TInt64, target: TInt32, data: TInt32) -> TNone:
def rtio_output(target: TInt32, data: TInt32) -> TNone:
raise NotImplementedError("syscall not simulated")
@syscall(flags={"nowrite"})
def rtio_output_wide(time_mu: TInt64, target: TInt32,
data: TList(TInt32)) -> TNone:
def rtio_output_wide(target: TInt32, data: TList(TInt32)) -> TNone:
raise NotImplementedError("syscall not simulated")

View File

@ -42,7 +42,7 @@ class TTLOut:
@kernel
def set_o(self, o):
rtio_output(now_mu(), self.target_o, 1 if o else 0)
rtio_output(self.target_o, 1 if o else 0)
@kernel
def on(self):
@ -120,7 +120,7 @@ class TTLInOut:
@kernel
def set_oe(self, oe):
rtio_output(now_mu(), self.target_oe, 1 if oe else 0)
rtio_output(self.target_oe, 1 if oe else 0)
@kernel
def output(self):
@ -142,7 +142,7 @@ class TTLInOut:
@kernel
def set_o(self, o):
rtio_output(now_mu(), self.target_o, 1 if o else 0)
rtio_output(self.target_o, 1 if o else 0)
@kernel
def on(self):
@ -187,7 +187,7 @@ class TTLInOut:
# Input API: gating
@kernel
def _set_sensitivity(self, value):
rtio_output(now_mu(), self.target_sens, value)
rtio_output(self.target_sens, value)
@kernel
def gate_rising_mu(self, duration):
@ -361,7 +361,7 @@ class TTLInOut:
position of the time cursor.
The time cursor is not modified by this function."""
rtio_output(now_mu(), self.target_sample, 0)
rtio_output(self.target_sample, 0)
@kernel
def sample_get(self):
@ -398,13 +398,13 @@ class TTLInOut:
The time cursor is not modified by this function.
"""
rtio_output(now_mu(), self.target_sample, 2) # gate falling
rtio_output(self.target_sample, 2) # gate falling
return rtio_input_data(self.channel) == 1
@kernel
def watch_stay_off(self):
"""Like :meth:`watch_stay_on`, but for low levels."""
rtio_output(now_mu(), self.target_sample, 1) # gate rising
rtio_output(self.target_sample, 1) # gate rising
return rtio_input_data(self.channel) == 0
@kernel
@ -417,7 +417,7 @@ class TTLInOut:
The time cursor is not modified by this function. This function
always makes the slack negative.
"""
rtio_output(now_mu(), self.target_sens, 0)
rtio_output(self.target_sens, 0)
success = True
try:
while rtio_input_timestamp(now_mu(), self.channel) != -1:
@ -479,7 +479,7 @@ class TTLClockGen:
Due to the way the clock generator operates, frequency tuning words
that are not powers of two cause jitter of one RTIO clock cycle at the
output."""
rtio_output(now_mu(), self.target, frequency)
rtio_output(self.target, frequency)
@kernel
def set(self, frequency):

View File

@ -1,3 +1,5 @@
use board_misoc::csr;
macro_rules! api {
($i:ident) => ({
extern { static $i: u8; }
@ -78,7 +80,7 @@ static mut API: &'static [(&'static str, *const ())] = &[
/* proxified syscalls */
api!(core_log),
api!(now = &::NOW as *const _),
api!(now = csr::rtio::NOW_HI_ADDR as *const _),
api!(watchdog_set = ::watchdog_set),
api!(watchdog_clear = ::watchdog_clear),

View File

@ -12,7 +12,7 @@ struct slice {
};
void send_to_core_log(struct slice str);
void send_to_rtio_log(long long int timestamp, struct slice data);
void send_to_rtio_log(struct slice data);
#define KERNELCPU_EXEC_ADDRESS 0x40800000
#define KERNELCPU_PAYLOAD_ADDRESS 0x40840000
@ -139,8 +139,8 @@ int core_log(const char *fmt, ...)
}
/* called by kernel */
void rtio_log(long long int timestamp, const char *fmt, ...);
void rtio_log(long long int timestamp, const char *fmt, ...)
void rtio_log(const char *fmt, ...);
void rtio_log(const char *fmt, ...)
{
va_list args;
@ -154,5 +154,5 @@ void rtio_log(long long int timestamp, const char *fmt, ...)
va_end(args);
struct slice str = { buf, size };
send_to_rtio_log(timestamp, str);
send_to_rtio_log(str);
}

View File

@ -99,7 +99,6 @@ mod api;
mod rtio;
mod nrt_bus;
static mut NOW: u64 = 0;
static mut LIBRARY: Option<Library<'static>> = None;
#[no_mangle]
@ -114,8 +113,8 @@ pub extern fn send_to_core_log(text: CSlice<u8>) {
}
#[no_mangle]
pub extern fn send_to_rtio_log(timestamp: i64, text: CSlice<u8>) {
rtio::log(timestamp, text.as_ref())
pub extern fn send_to_rtio_log(text: CSlice<u8>) {
rtio::log(text.as_ref())
}
#[unwind(aborts)]
@ -184,7 +183,6 @@ fn terminate(exception: &eh_artiq::Exception, backtrace: &mut [usize]) -> ! {
}
let backtrace = &mut backtrace.as_mut()[0..cursor];
send(&NowSave(unsafe { NOW }));
send(&RunException {
exception: kernel_proto::Exception {
name: str::from_utf8(exception.name.as_ref()).unwrap(),
@ -508,10 +506,7 @@ pub unsafe fn main() {
ptr::write_bytes(__bss_start as *mut u8, 0, (_end - __bss_start) as usize);
send(&NowInitRequest);
recv!(&NowInitReply(now) => NOW = now);
(mem::transmute::<u32, fn()>(__modinit__))();
send(&NowSave(NOW));
if let Some(typeinfo) = typeinfo {
attribute_writeback(typeinfo as *const ());

View File

@ -51,7 +51,8 @@ mod imp {
}
#[inline(never)]
unsafe fn process_exceptional_status(timestamp: i64, channel: i32, status: u8) {
unsafe fn process_exceptional_status(channel: i32, status: u8) {
let timestamp = *(csr::rtio::NOW_HI_ADDR as *const i64);
if status & RTIO_O_STATUS_WAIT != 0 {
while csr::rtio::o_status_read() & RTIO_O_STATUS_WAIT != 0 {}
}
@ -67,30 +68,28 @@ mod imp {
}
}
pub extern fn output(timestamp: i64, target: i32, data: i32) {
pub extern fn output(target: i32, data: i32) {
unsafe {
csr::rtio::target_write(target as u32);
// writing timestamp clears o_data
csr::rtio::timestamp_write(timestamp as u64);
// writing target clears o_data
rtio_o_data_write(0, data as _);
let status = csr::rtio::o_status_read();
if status != 0 {
process_exceptional_status(timestamp, target >> 8, status);
process_exceptional_status(target >> 8, status);
}
}
}
pub extern fn output_wide(timestamp: i64, target: i32, data: CSlice<i32>) {
pub extern fn output_wide(target: i32, data: CSlice<i32>) {
unsafe {
csr::rtio::target_write(target as u32);
// writing timestamp clears o_data
csr::rtio::timestamp_write(timestamp as u64);
// writing target clears o_data
for i in 0..data.len() {
rtio_o_data_write(i, data[i] as _)
}
let status = csr::rtio::o_status_read();
if status != 0 {
process_exceptional_status(timestamp, target >> 8, status);
process_exceptional_status(target >> 8, status);
}
}
}
@ -98,8 +97,7 @@ mod imp {
pub extern fn input_timestamp(timeout: i64, channel: i32) -> u64 {
unsafe {
csr::rtio::target_write((channel as u32) << 8);
csr::rtio::timestamp_write(timeout as u64);
csr::rtio::i_request_write(1);
csr::rtio::i_timeout_write(timeout as u64);
let mut status = RTIO_I_STATUS_WAIT_STATUS;
while status & RTIO_I_STATUS_WAIT_STATUS != 0 {
@ -128,8 +126,7 @@ mod imp {
pub extern fn input_data(channel: i32) -> i32 {
unsafe {
csr::rtio::target_write((channel as u32) << 8);
csr::rtio::timestamp_write(0xffffffff_ffffffff);
csr::rtio::i_request_write(1);
csr::rtio::i_timeout_write(0xffffffff_ffffffff);
let mut status = RTIO_I_STATUS_WAIT_STATUS;
while status & RTIO_I_STATUS_WAIT_STATUS != 0 {
@ -153,10 +150,9 @@ mod imp {
}
#[cfg(has_rtio_log)]
pub fn log(timestamp: i64, data: &[u8]) {
pub fn log(data: &[u8]) {
unsafe {
csr::rtio::target_write(csr::CONFIG_RTIO_LOG_CHANNEL << 8);
csr::rtio::timestamp_write(timestamp as u64);
let mut word: u32 = 0;
for i in 0..data.len() {
@ -175,7 +171,7 @@ mod imp {
}
#[cfg(not(has_rtio_log))]
pub fn log(_timestamp: i64, _data: &[u8]) {
pub fn log(_data: &[u8]) {
unimplemented!("not(has_rtio_log)")
}
}

View File

@ -22,10 +22,6 @@ pub enum Message<'a> {
LoadRequest(&'a [u8]),
LoadReply(Result<(), dyld::Error<'a>>),
NowInitRequest,
NowInitReply(u64),
NowSave(u64),
RtioInitRequest,
RtioDestinationStatusRequest { destination: u8 },

View File

@ -63,7 +63,6 @@ macro_rules! unexpected {
// Persistent state
#[derive(Debug)]
struct Congress {
now: u64,
cache: Cache,
dma_manager: DmaManager,
finished_cleanly: Cell<bool>
@ -72,7 +71,6 @@ struct Congress {
impl Congress {
fn new() -> Congress {
Congress {
now: 0,
cache: Cache::new(),
dma_manager: DmaManager::new(),
finished_cleanly: Cell::new(true)
@ -365,14 +363,6 @@ fn process_kern_message(io: &Io, aux_mutex: &Mutex,
kern_acknowledge()
}
&kern::NowInitRequest =>
kern_send(io, &kern::NowInitReply(session.congress.now)),
&kern::NowSave(now) => {
session.congress.now = now;
kern_acknowledge()
}
&kern::DmaRecordStart(name) => {
session.congress.dma_manager.record_start(name);
kern_acknowledge()

View File

@ -73,7 +73,11 @@ class RTController(Module):
rt_packet.sr_chan_sel.eq(chan_sel),
rt_packet.sr_address.eq(self.cri.o_address),
rt_packet.sr_data.eq(self.cri.o_data),
rt_packet.sr_timestamp.eq(self.cri.timestamp),
If(rt_packet_read_request,
rt_packet.sr_timestamp.eq(self.cri.i_timeout)
).Else(
rt_packet.sr_timestamp.eq(self.cri.o_timestamp)
),
If(rt_packet_buffer_request,
rt_packet.sr_notwrite.eq(1),
rt_packet.sr_address.eq(0)
@ -103,7 +107,7 @@ class RTController(Module):
self.submodules += timeout_counter
cond_underflow = Signal()
self.comb += cond_underflow.eq((self.cri.timestamp[tsc.glbl_fine_ts_width:]
self.comb += cond_underflow.eq((self.cri.o_timestamp[tsc.glbl_fine_ts_width:]
- self.csrs.underflow_margin.storage[tsc.glbl_fine_ts_width:]) < tsc.coarse_ts_sys)
# buffer space

View File

@ -61,7 +61,7 @@ class RTErrorsSatellite(Module, AutoCSR):
underflow.eq(cri.o_status[1]),
overflow.eq(cri.o_status[0]),
underflow_error_cri.eq(Cat(cri.chan_sel[:16],
cri.timestamp,
cri.o_timestamp,
tsc.full_ts_cri)),
Cat(self.underflow_channel.status,
self.underflow_timestamp_event.status,

View File

@ -68,7 +68,11 @@ class RTPacketRepeater(Module):
If(~self.reset & ~cb0_loaded & (self.cri.cmd != cri.commands["nop"]),
cb0_loaded.eq(1),
cb0_cmd.eq(self.cri.cmd),
cb0_timestamp.eq(self.cri.timestamp),
If(self.cri.cmd == cri.commands["read"],
cb0_timestamp.eq(self.cri.i_timeout)
).Else(
cb0_timestamp.eq(self.cri.o_timestamp)
),
cb0_chan_sel.eq(self.cri.chan_sel),
cb0_o_address.eq(self.cri.o_address),
cb0_o_data.eq(self.cri.o_data)

View File

@ -94,13 +94,10 @@ class RTPacketSatellite(Module):
self.cri.chan_sel.eq(
rx_dp.packet_as["write"].chan_sel),
),
If(cri_read | read_request_pending,
self.cri.timestamp.eq(
rx_dp.packet_as["read_request"].timeout)
).Else(
self.cri.timestamp.eq(
rx_dp.packet_as["write"].timestamp)
),
self.cri.i_timeout.eq(
rx_dp.packet_as["read_request"].timeout),
self.cri.o_timestamp.eq(
rx_dp.packet_as["write"].timestamp),
self.cri.o_address.eq(
rx_dp.packet_as["write"].address),
self.cri.o_data.eq(

View File

@ -70,7 +70,7 @@ class MessageEncoder(Module, AutoCSR):
input_output.rtio_counter.eq(tsc.full_ts_cri),
If(cri.cmd == cri_commands["write"],
input_output.message_type.eq(MessageType.output.value),
input_output.timestamp.eq(cri.timestamp),
input_output.timestamp.eq(cri.o_timestamp),
input_output.data.eq(cri.o_data)
).Else(
input_output.message_type.eq(MessageType.input.value),

View File

@ -29,8 +29,8 @@ layout = [
# 8 MSBs of chan_sel = routing destination
# 16 LSBs of chan_sel = channel within the destination
("chan_sel", 24, DIR_M_TO_S),
("timestamp", 64, DIR_M_TO_S),
("o_timestamp", 64, DIR_M_TO_S),
("o_data", 512, DIR_M_TO_S),
("o_address", 8, DIR_M_TO_S),
# o_status bits:
@ -43,6 +43,7 @@ layout = [
("o_buffer_space_valid", 1, DIR_S_TO_M),
("o_buffer_space", 16, DIR_S_TO_M),
("i_timeout", 64, DIR_M_TO_S),
("i_data", 32, DIR_S_TO_M),
("i_timestamp", 64, DIR_S_TO_M),
# i_status bits:
@ -61,17 +62,19 @@ class Interface(Record):
class KernelInitiator(Module, AutoCSR):
def __init__(self, tsc, cri=None):
self.target = CSRStorage(32)
self.timestamp = CSRStorage(64)
# not using CSRStorage atomic_write feature here to make storage reset_less
self.now_hi = CSR(32)
self.now_lo = CSR(32)
# Writing timestamp clears o_data. This implements automatic
# Writing target clears o_data. This implements automatic
# zero-extension of output event data by the gateware. When staging an
# output event, always write timestamp before o_data.
# output event, always write target before o_data.
self.o_data = CSRStorage(512, write_from_dev=True)
self.o_status = CSRStatus(3)
self.i_timeout = CSRStorage(64)
self.i_data = CSRStatus(32)
self.i_timestamp = CSRStatus(64)
self.i_request = CSR()
self.i_status = CSRStatus(4)
self.i_overflow_reset = CSR()
@ -84,24 +87,39 @@ class KernelInitiator(Module, AutoCSR):
# # #
now_lo_backing = Signal(32)
now = Signal(64, reset_less=True)
self.sync += [
# TODO: fix compiler and make atomic
#If(self.now_lo.re, now_lo_backing.eq(self.now_lo.r)),
#If(self.now_hi.re, now.eq(Cat(now_lo_backing, self.now_hi.r)))
If(self.now_lo.re, now[:32].eq(self.now_lo.r)),
If(self.now_hi.re, now[32:].eq(self.now_hi.r))
]
self.comb += [
self.now_lo.w.eq(now[:32]),
self.now_hi.w.eq(now[32:])
]
self.comb += [
self.cri.cmd.eq(commands["nop"]),
If(self.o_data.re, self.cri.cmd.eq(commands["write"])),
If(self.i_request.re, self.cri.cmd.eq(commands["read"])),
If(self.i_timeout.re, self.cri.cmd.eq(commands["read"])),
self.cri.chan_sel.eq(self.target.storage[8:]),
self.cri.timestamp.eq(self.timestamp.storage),
self.cri.o_timestamp.eq(now),
self.cri.o_data.eq(self.o_data.storage),
self.cri.o_address.eq(self.target.storage[:8]),
self.o_status.status.eq(self.cri.o_status),
self.cri.i_timeout.eq(self.i_timeout.storage),
self.i_data.status.eq(self.cri.i_data),
self.i_timestamp.status.eq(self.cri.i_timestamp),
self.i_status.status.eq(self.cri.i_status),
self.o_data.dat_w.eq(0),
self.o_data.we.eq(self.timestamp.re),
self.o_data.we.eq(self.target.re),
]
self.sync += If(self.counter_update.re, self.counter.status.eq(tsc.full_ts_cri))

View File

@ -274,7 +274,7 @@ class CRIMaster(Module, AutoCSR):
self.comb += [
self.cri.chan_sel.eq(self.sink.channel),
self.cri.timestamp.eq(self.sink.timestamp),
self.cri.o_timestamp.eq(self.sink.timestamp),
self.cri.o_address.eq(self.sink.address),
self.cri.o_data.eq(self.sink.data)
]

View File

@ -118,7 +118,7 @@ class InputCollector(Module):
i_status_raw = Signal(2)
self.comb += i_status_raw.eq(Array(i_statuses)[sel])
input_timeout = Signal.like(self.cri.timestamp, reset_less=True)
input_timeout = Signal.like(self.cri.i_timeout, reset_less=True)
input_pending = Signal()
self.cri.i_data.reset_less = True
self.cri.i_timestamp.reset_less = True
@ -134,7 +134,7 @@ class InputCollector(Module):
input_pending.eq(0)
),
If(self.cri.cmd == cri.commands["read"],
input_timeout.eq(self.cri.timestamp),
input_timeout.eq(self.cri.i_timeout),
input_pending.eq(1),
self.cri.i_status.eq(0b100)
)

View File

@ -60,7 +60,7 @@ class LaneDistributor(Module):
self.comb += [
lio.seqn.eq(seqn),
lio.payload.channel.eq(self.cri.chan_sel[:16]),
lio.payload.timestamp.eq(self.cri.timestamp),
lio.payload.timestamp.eq(self.cri.o_timestamp),
]
if hasattr(lio.payload, "address"):
self.comb += lio.payload.address.eq(self.cri.o_address)
@ -69,7 +69,7 @@ class LaneDistributor(Module):
# when timestamp and channel arrive in cycle #1, prepare computations
coarse_timestamp = Signal(us_timestamp_width)
self.comb += coarse_timestamp.eq(self.cri.timestamp[glbl_fine_ts_width:])
self.comb += coarse_timestamp.eq(self.cri.o_timestamp[glbl_fine_ts_width:])
min_minus_timestamp = Signal((us_timestamp_width + 1, True),
reset_less=True)
laneAmin_minus_timestamp = Signal.like(min_minus_timestamp)
@ -141,7 +141,7 @@ class LaneDistributor(Module):
Array(lio.we for lio in self.output)[use_lanen].eq(do_write)
]
compensated_timestamp = Signal(64)
self.comb += compensated_timestamp.eq(self.cri.timestamp + (compensation << glbl_fine_ts_width))
self.comb += compensated_timestamp.eq(self.cri.o_timestamp + (compensation << glbl_fine_ts_width))
self.sync += [
If(do_write,
current_lane.eq(use_lanen),

View File

@ -112,10 +112,10 @@ class OutputsTestbench:
def write(self, channel, data):
kcsrs = self.dut.master_ki
yield from kcsrs.chan_sel.write(channel)
yield from kcsrs.timestamp.write(self.now)
yield from kcsrs.target.write(channel << 8)
yield from kcsrs.now_hi.write(self.now >> 32)
yield from kcsrs.now_lo.write(self.now & 0xffffffff)
yield from kcsrs.o_data.write(data)
yield from kcsrs.o_we.write(1)
yield
status = 1
wlen = 0
@ -249,9 +249,8 @@ class TestFullStack(unittest.TestCase):
kcsrs = dut.master_ki
def get_input(timeout):
yield from kcsrs.chan_sel.write(2)
yield from kcsrs.timestamp.write(10)
yield from kcsrs.i_request.write(1)
yield from kcsrs.target.write(2 << 8)
yield from kcsrs.i_timeout.write(10)
yield
status = yield from kcsrs.i_status.read()
while status & 0x4:

View File

@ -65,7 +65,7 @@ class TestRepeater(unittest.TestCase):
yield
for channel, timestamp, address, data in test_writes:
yield dut.cri.chan_sel.eq(channel)
yield dut.cri.timestamp.eq(timestamp)
yield dut.cri.o_timestamp.eq(timestamp)
yield dut.cri.o_address.eq(address)
yield dut.cri.o_data.eq(data)
yield dut.cri.cmd.eq(cri.commands["write"])
@ -135,7 +135,7 @@ class TestRepeater(unittest.TestCase):
def read(chan_sel, timeout):
yield dut.cri.chan_sel.eq(chan_sel)
yield dut.cri.timestamp.eq(timeout)
yield dut.cri.i_timeout.eq(timeout)
yield dut.cri.cmd.eq(cri.commands["read"])
yield
yield dut.cri.cmd.eq(cri.commands["nop"])

View File

@ -90,7 +90,7 @@ class Testbench:
def write(self, channel, data):
mcri = self.dut.master.cri
yield mcri.chan_sel.eq(channel)
yield mcri.timestamp.eq(self.now)
yield mcri.o_timestamp.eq(self.now)
yield mcri.o_data.eq(data)
yield
yield mcri.cmd.eq(cri.commands["write"])
@ -109,7 +109,7 @@ class Testbench:
def read(self, channel, timeout):
mcri = self.dut.master.cri
yield mcri.chan_sel.eq(channel)
yield mcri.timestamp.eq(timeout)
yield mcri.i_timeout.eq(timeout)
yield
yield mcri.cmd.eq(cri.commands["read"])
yield

View File

@ -26,7 +26,7 @@ def encode_record(channel, timestamp, address, data):
r = []
r += encode_n(channel, 3, 3)
r += encode_n(timestamp, 8, 8)
r += encode_n(address, 2, 2)
r += encode_n(address, 1, 1)
r += encode_n(data, 1, 64)
return encode_n(len(r)+1, 1, 1) + r
@ -66,7 +66,7 @@ def do_dma(dut, address):
test_writes1 = [
(0x01, 0x23, 0x12, 0x33),
(0x901, 0x902, 0x911, 0xeeeeeeeeeeeeeefffffffffffffffffffffffffffffff28888177772736646717738388488),
(0x901, 0x902, 0x11, 0xeeeeeeeeeeeeeefffffffffffffffffffffffffffffff28888177772736646717738388488),
(0x81, 0x288, 0x88, 0x8888)
]
@ -150,7 +150,7 @@ class TestDMA(unittest.TestCase):
pass
elif cmd == cri.commands["write"]:
channel = yield dut_cri.chan_sel
timestamp = yield dut_cri.timestamp
timestamp = yield dut_cri.o_timestamp
address = yield dut_cri.o_address
data = yield dut_cri.o_data
received.append((channel, timestamp, address, data))

View File

@ -54,7 +54,7 @@ def simulate(wait_cycles, ts_timeouts):
yield
for ts_timeout in ts_timeouts:
yield dut.cri.timestamp.eq(ts_timeout)
yield dut.cri.i_timeout.eq(ts_timeout)
yield dut.cri.cmd.eq(cri.commands["read"])
yield
yield dut.cri.cmd.eq(cri.commands["nop"])

View File

@ -21,7 +21,7 @@ def simulate(input_events, compensation=None, wait=True):
def gen():
for channel, timestamp in input_events:
yield dut.cri.chan_sel.eq(channel)
yield dut.cri.timestamp.eq(timestamp)
yield dut.cri.o_timestamp.eq(timestamp)
yield
yield dut.cri.cmd.eq(cri.commands["write"])

View File

@ -38,7 +38,7 @@ def simulate(input_events, **kwargs):
def gen():
yield dut.sed.cri.chan_sel.eq(0)
for timestamp, data in input_events:
yield dut.sed.cri.timestamp.eq(timestamp)
yield dut.sed.cri.o_timestamp.eq(timestamp)
yield dut.sed.cri.o_data.eq(data)
yield