forked from M-Labs/artiq
rtio: add support for latency compensation in phy
* if multiple RTIO channels influence the same data stream and physical output channel (see SAWG) differential latency needs to be compensated * this is a NOP for phys with zero delay (default) * if delay==1, it adds one timestamp-wide register * if delay >1, it adds one adder and one register * latency compensation using (~10-50 deep) delay lines is about as expensive as a single adder+register but very tedious to implement
This commit is contained in:
parent
7be27d7116
commit
6cdb96c5e0
@ -159,10 +159,18 @@ class _OutputManager(Module):
|
||||
)
|
||||
self.comb += fifo.re.eq(fifo.readable & (~dout_stb | dout_ack))
|
||||
|
||||
# latency compensation
|
||||
if interface.delay:
|
||||
counter_rtio = Signal.like(counter.value_rtio)
|
||||
self.sync.rio += counter_rtio.eq(counter.value_rtio -
|
||||
interface.delay + 1)
|
||||
else:
|
||||
counter_rtio = counter.value_rtio
|
||||
|
||||
# FIFO read through buffer
|
||||
self.comb += [
|
||||
dout_ack.eq(
|
||||
dout.timestamp[fine_ts_width:] == counter.value_rtio),
|
||||
dout.timestamp[fine_ts_width:] == counter_rtio),
|
||||
interface.stb.eq(dout_stb & dout_ack)
|
||||
]
|
||||
|
||||
@ -210,14 +218,22 @@ class _InputManager(Module):
|
||||
fifo_out.raw_bits().eq(fifo.dout)
|
||||
]
|
||||
|
||||
# latency compensation
|
||||
if interface.delay:
|
||||
counter_rtio = Signal.like(counter.value_rtio)
|
||||
self.sync.rio += counter_rtio.eq(counter.value_rtio -
|
||||
interface.delay + 1)
|
||||
else:
|
||||
counter_rtio = counter.value_rtio
|
||||
|
||||
# FIFO write
|
||||
if data_width:
|
||||
self.comb += fifo_in.data.eq(interface.data)
|
||||
if interface.timestamped:
|
||||
if fine_ts_width:
|
||||
full_ts = Cat(interface.fine_ts, counter.value_rtio)
|
||||
full_ts = Cat(interface.fine_ts, counter_rtio)
|
||||
else:
|
||||
full_ts = counter.value_rtio
|
||||
full_ts = counter_rtio
|
||||
self.comb += fifo_in.timestamp.eq(full_ts)
|
||||
self.comb += fifo.we.eq(interface.stb)
|
||||
|
||||
|
@ -3,7 +3,8 @@ from migen import *
|
||||
|
||||
class OInterface:
|
||||
def __init__(self, data_width, address_width=0,
|
||||
fine_ts_width=0, enable_replace=True):
|
||||
fine_ts_width=0, enable_replace=True,
|
||||
delay=0):
|
||||
self.stb = Signal()
|
||||
self.busy = Signal()
|
||||
|
||||
@ -16,17 +17,22 @@ class OInterface:
|
||||
|
||||
self.enable_replace = enable_replace
|
||||
|
||||
if delay < 0:
|
||||
raise ValueError("only positive delays allowed", delay)
|
||||
self.delay = delay
|
||||
|
||||
@classmethod
|
||||
def like(cls, other):
|
||||
return cls(get_data_width(other),
|
||||
get_address_width(other),
|
||||
get_fine_ts_width(other),
|
||||
other.enable_replace)
|
||||
other.enable_replace,
|
||||
other.delay)
|
||||
|
||||
|
||||
class IInterface:
|
||||
def __init__(self, data_width,
|
||||
timestamped=True, fine_ts_width=0):
|
||||
timestamped=True, fine_ts_width=0, delay=0):
|
||||
self.stb = Signal()
|
||||
|
||||
if data_width:
|
||||
@ -34,14 +40,18 @@ class IInterface:
|
||||
if fine_ts_width:
|
||||
self.fine_ts = Signal(fine_ts_width)
|
||||
|
||||
self.timestamped = timestamped
|
||||
assert(not fine_ts_width or timestamped)
|
||||
self.timestamped = timestamped
|
||||
if delay < 0:
|
||||
raise ValueError("only positive delays")
|
||||
self.delay = delay
|
||||
|
||||
@classmethod
|
||||
def like(cls, other):
|
||||
return cls(get_data_width(other),
|
||||
other.timestamped,
|
||||
get_fine_ts_width(other))
|
||||
get_fine_ts_width(other),
|
||||
delay)
|
||||
|
||||
|
||||
class Interface:
|
||||
|
Loading…
Reference in New Issue
Block a user