forked from M-Labs/artiq
drtio: introduce 'standard request' interface in RT packet layer
This commit is contained in:
parent
2b8729f326
commit
6b7c781ff2
|
@ -100,13 +100,13 @@ class RTController(Module):
|
||||||
fifo_spaces.adr.eq(chan_sel),
|
fifo_spaces.adr.eq(chan_sel),
|
||||||
last_timestamps.adr.eq(chan_sel),
|
last_timestamps.adr.eq(chan_sel),
|
||||||
last_timestamps.dat_w.eq(self.cri.timestamp),
|
last_timestamps.dat_w.eq(self.cri.timestamp),
|
||||||
rt_packets.write_channel.eq(chan_sel),
|
rt_packets.sr_channel.eq(chan_sel),
|
||||||
rt_packets.write_address.eq(self.cri.o_address),
|
rt_packets.sr_address.eq(self.cri.o_address),
|
||||||
rt_packets.write_data.eq(self.cri.o_data),
|
rt_packets.sr_data.eq(self.cri.o_data),
|
||||||
|
rt_packets.sr_timestamp.eq(self.cri.timestamp),
|
||||||
If(rt_packets_fifo_request,
|
If(rt_packets_fifo_request,
|
||||||
rt_packets.write_timestamp.eq(0xffff000000000000)
|
rt_packets.sr_notwrite.eq(1),
|
||||||
).Else(
|
rt_packets.sr_address.eq(0)
|
||||||
rt_packets.write_timestamp.eq(self.cri.timestamp)
|
|
||||||
)
|
)
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -159,8 +159,8 @@ class RTController(Module):
|
||||||
)
|
)
|
||||||
fsm.act("WRITE",
|
fsm.act("WRITE",
|
||||||
status_wait.eq(1),
|
status_wait.eq(1),
|
||||||
rt_packets.write_stb.eq(1),
|
rt_packets.sr_stb.eq(1),
|
||||||
If(rt_packets.write_ack,
|
If(rt_packets.sr_ack,
|
||||||
fifo_spaces.we.eq(1),
|
fifo_spaces.we.eq(1),
|
||||||
fifo_spaces.dat_w.eq(fifo_spaces.dat_r - 1),
|
fifo_spaces.dat_w.eq(fifo_spaces.dat_r - 1),
|
||||||
last_timestamps.we.eq(1),
|
last_timestamps.we.eq(1),
|
||||||
|
@ -174,9 +174,9 @@ class RTController(Module):
|
||||||
fsm.act("GET_FIFO_SPACE",
|
fsm.act("GET_FIFO_SPACE",
|
||||||
status_wait.eq(1),
|
status_wait.eq(1),
|
||||||
rt_packets_fifo_request.eq(1),
|
rt_packets_fifo_request.eq(1),
|
||||||
rt_packets.write_stb.eq(1),
|
rt_packets.sr_stb.eq(1),
|
||||||
rt_packets.fifo_space_not_ack.eq(1),
|
rt_packets.fifo_space_not_ack.eq(1),
|
||||||
If(rt_packets.write_ack,
|
If(rt_packets.sr_ack,
|
||||||
NextState("GET_FIFO_SPACE_REPLY")
|
NextState("GET_FIFO_SPACE_REPLY")
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
@ -211,7 +211,7 @@ class RTController(Module):
|
||||||
)
|
)
|
||||||
]
|
]
|
||||||
self.sync += \
|
self.sync += \
|
||||||
If((rt_packets.write_stb & rt_packets.write_ack & rt_packets_fifo_request),
|
If((rt_packets.sr_stb & rt_packets.sr_ack & rt_packets_fifo_request),
|
||||||
self.csrs.o_dbg_fifo_space_req_cnt.status.eq(
|
self.csrs.o_dbg_fifo_space_req_cnt.status.eq(
|
||||||
self.csrs.o_dbg_fifo_space_req_cnt.status + 1)
|
self.csrs.o_dbg_fifo_space_req_cnt.status + 1)
|
||||||
)
|
)
|
||||||
|
|
|
@ -61,20 +61,28 @@ class _CrossDomainNotification(Module):
|
||||||
|
|
||||||
|
|
||||||
class RTPacketMaster(Module):
|
class RTPacketMaster(Module):
|
||||||
def __init__(self, link_layer, write_fifo_depth=4):
|
def __init__(self, link_layer, sr_fifo_depth=4):
|
||||||
# all interface signals in sys domain unless otherwise specified
|
# all interface signals in sys domain unless otherwise specified
|
||||||
|
|
||||||
# write interface, optimized for throughput
|
# standard request interface
|
||||||
self.write_stb = Signal()
|
#
|
||||||
self.write_ack = Signal()
|
# notwrite=1 address=0 FIFO space request <channel>
|
||||||
self.write_timestamp = Signal(64)
|
# notwrite=1 address=1 read request <channel, timestamp>
|
||||||
self.write_channel = Signal(16)
|
# notwrite=1 address=2 read consume
|
||||||
self.write_address = Signal(16)
|
#
|
||||||
self.write_data = Signal(512)
|
# optimized for write throughput
|
||||||
|
# requests are performed on the DRTIO link preserving their order of issue
|
||||||
|
# this is important for FIFO space requests, which have to be ordered
|
||||||
|
# wrt writes.
|
||||||
|
self.sr_stb = Signal()
|
||||||
|
self.sr_ack = Signal()
|
||||||
|
self.sr_notwrite = Signal()
|
||||||
|
self.sr_timestamp = Signal(64)
|
||||||
|
self.sr_channel = Signal(16)
|
||||||
|
self.sr_address = Signal(16)
|
||||||
|
self.sr_data = Signal(512)
|
||||||
|
|
||||||
# fifo space interface
|
# fifo space reply interface
|
||||||
# write with timestamp[48:] == 0xffff to make a fifo space request
|
|
||||||
# (space requests have to be ordered wrt writes)
|
|
||||||
self.fifo_space_not = Signal()
|
self.fifo_space_not = Signal()
|
||||||
self.fifo_space_not_ack = Signal()
|
self.fifo_space_not_ack = Signal()
|
||||||
self.fifo_space = Signal(16)
|
self.fifo_space = Signal(16)
|
||||||
|
@ -122,63 +130,66 @@ class RTPacketMaster(Module):
|
||||||
self.submodules += rx_dp
|
self.submodules += rx_dp
|
||||||
|
|
||||||
# Write FIFO and extra data count
|
# Write FIFO and extra data count
|
||||||
wfifo = ClockDomainsRenamer({"write": "sys_with_rst", "read": "rtio_with_rst"})(
|
sr_fifo = ClockDomainsRenamer({"write": "sys_with_rst", "read": "rtio_with_rst"})(
|
||||||
AsyncFIFO(64+16+16+512, write_fifo_depth))
|
AsyncFIFO(1+64+16+16+512, sr_fifo_depth))
|
||||||
self.submodules += wfifo
|
self.submodules += sr_fifo
|
||||||
write_timestamp_d = Signal(64)
|
sr_notwrite_d = Signal()
|
||||||
write_channel_d = Signal(16)
|
sr_timestamp_d = Signal(64)
|
||||||
write_address_d = Signal(16)
|
sr_channel_d = Signal(16)
|
||||||
write_data_d = Signal(512)
|
sr_address_d = Signal(16)
|
||||||
|
sr_data_d = Signal(512)
|
||||||
self.comb += [
|
self.comb += [
|
||||||
wfifo.we.eq(self.write_stb),
|
sr_fifo.we.eq(self.sr_stb),
|
||||||
self.write_ack.eq(wfifo.writable),
|
self.sr_ack.eq(sr_fifo.writable),
|
||||||
wfifo.din.eq(Cat(self.write_timestamp, self.write_channel,
|
sr_fifo.din.eq(Cat(self.sr_notwrite, self.sr_timestamp, self.sr_channel,
|
||||||
self.write_address, self.write_data)),
|
self.sr_address, self.sr_data)),
|
||||||
Cat(write_timestamp_d, write_channel_d,
|
Cat(sr_notwrite_d, sr_timestamp_d, sr_channel_d,
|
||||||
write_address_d, write_data_d).eq(wfifo.dout)
|
sr_address_d, sr_data_d).eq(sr_fifo.dout)
|
||||||
]
|
]
|
||||||
|
|
||||||
wfb_readable = Signal()
|
sr_buf_readable = Signal()
|
||||||
wfb_re = Signal()
|
sr_buf_re = Signal()
|
||||||
|
|
||||||
self.comb += wfifo.re.eq(wfifo.readable & (~wfb_readable | wfb_re))
|
self.comb += sr_fifo.re.eq(sr_fifo.readable & (~sr_buf_readable | sr_buf_re))
|
||||||
self.sync.rtio += \
|
self.sync.rtio += \
|
||||||
If(wfifo.re,
|
If(sr_fifo.re,
|
||||||
wfb_readable.eq(1),
|
sr_buf_readable.eq(1),
|
||||||
).Elif(wfb_re,
|
).Elif(sr_buf_re,
|
||||||
wfb_readable.eq(0),
|
sr_buf_readable.eq(0),
|
||||||
)
|
)
|
||||||
|
|
||||||
write_timestamp = Signal(64)
|
sr_notwrite = Signal()
|
||||||
write_channel = Signal(16)
|
sr_timestamp = Signal(64)
|
||||||
write_address = Signal(16)
|
sr_channel = Signal(16)
|
||||||
write_extra_data_cnt = Signal(8)
|
sr_address = Signal(16)
|
||||||
write_data = Signal(512)
|
sr_extra_data_cnt = Signal(8)
|
||||||
|
sr_data = Signal(512)
|
||||||
|
|
||||||
self.sync.rtio += If(wfifo.re,
|
self.sync.rtio += If(sr_fifo.re,
|
||||||
write_timestamp.eq(write_timestamp_d),
|
sr_notwrite.eq(sr_notwrite_d),
|
||||||
write_channel.eq(write_channel_d),
|
sr_timestamp.eq(sr_timestamp_d),
|
||||||
write_address.eq(write_address_d),
|
sr_channel.eq(sr_channel_d),
|
||||||
write_data.eq(write_data_d))
|
sr_address.eq(sr_address_d),
|
||||||
|
sr_data.eq(sr_data_d))
|
||||||
|
|
||||||
short_data_len = tx_plm.field_length("write", "short_data")
|
short_data_len = tx_plm.field_length("write", "short_data")
|
||||||
write_extra_data_d = Signal(512)
|
sr_extra_data_d = Signal(512)
|
||||||
self.comb += write_extra_data_d.eq(write_data_d[short_data_len:])
|
self.comb += sr_extra_data_d.eq(sr_data_d[short_data_len:])
|
||||||
for i in range(512//ws):
|
for i in range(512//ws):
|
||||||
self.sync.rtio += If(wfifo.re,
|
self.sync.rtio += If(sr_fifo.re,
|
||||||
If(write_extra_data_d[ws*i:ws*(i+1)] != 0, write_extra_data_cnt.eq(i+1)))
|
If(sr_extra_data_d[ws*i:ws*(i+1)] != 0, sr_extra_data_cnt.eq(i+1)))
|
||||||
|
|
||||||
write_extra_data = Signal(512)
|
sr_extra_data = Signal(512)
|
||||||
self.sync.rtio += If(wfifo.re, write_extra_data.eq(write_extra_data_d))
|
self.sync.rtio += If(sr_fifo.re, sr_extra_data.eq(sr_extra_data_d))
|
||||||
|
|
||||||
extra_data_ce = Signal()
|
extra_data_ce = Signal()
|
||||||
extra_data_last = Signal()
|
extra_data_last = Signal()
|
||||||
extra_data_counter = Signal(max=512//ws+1)
|
extra_data_counter = Signal(max=512//ws+1)
|
||||||
self.comb += [
|
self.comb += [
|
||||||
Case(extra_data_counter,
|
Case(extra_data_counter,
|
||||||
{i+1: tx_dp.raw_data.eq(write_extra_data[i*ws:(i+1)*ws])
|
{i+1: tx_dp.raw_data.eq(sr_extra_data[i*ws:(i+1)*ws])
|
||||||
for i in range(512//ws)}),
|
for i in range(512//ws)}),
|
||||||
extra_data_last.eq(extra_data_counter == write_extra_data_cnt)
|
extra_data_last.eq(extra_data_counter == sr_extra_data_cnt)
|
||||||
]
|
]
|
||||||
self.sync.rtio += \
|
self.sync.rtio += \
|
||||||
If(extra_data_ce,
|
If(extra_data_ce,
|
||||||
|
@ -230,8 +241,9 @@ class RTPacketMaster(Module):
|
||||||
self.sync.rtio += If(tsc_value_load, tsc_value.eq(self.tsc_value))
|
self.sync.rtio += If(tsc_value_load, tsc_value.eq(self.tsc_value))
|
||||||
|
|
||||||
tx_fsm.act("IDLE",
|
tx_fsm.act("IDLE",
|
||||||
If(wfb_readable,
|
If(sr_buf_readable,
|
||||||
If(write_timestamp[48:] == 0xffff,
|
If(sr_notwrite,
|
||||||
|
# TODO: sr_address
|
||||||
NextState("FIFO_SPACE")
|
NextState("FIFO_SPACE")
|
||||||
).Else(
|
).Else(
|
||||||
NextState("WRITE")
|
NextState("WRITE")
|
||||||
|
@ -250,14 +262,14 @@ class RTPacketMaster(Module):
|
||||||
)
|
)
|
||||||
tx_fsm.act("WRITE",
|
tx_fsm.act("WRITE",
|
||||||
tx_dp.send("write",
|
tx_dp.send("write",
|
||||||
timestamp=write_timestamp,
|
timestamp=sr_timestamp,
|
||||||
channel=write_channel,
|
channel=sr_channel,
|
||||||
address=write_address,
|
address=sr_address,
|
||||||
extra_data_cnt=write_extra_data_cnt,
|
extra_data_cnt=sr_extra_data_cnt,
|
||||||
short_data=write_data[:short_data_len]),
|
short_data=sr_data[:short_data_len]),
|
||||||
If(tx_dp.packet_last,
|
If(tx_dp.packet_last,
|
||||||
If(write_extra_data_cnt == 0,
|
If(sr_extra_data_cnt == 0,
|
||||||
wfb_re.eq(1),
|
sr_buf_re.eq(1),
|
||||||
NextState("IDLE")
|
NextState("IDLE")
|
||||||
).Else(
|
).Else(
|
||||||
NextState("WRITE_EXTRA")
|
NextState("WRITE_EXTRA")
|
||||||
|
@ -268,14 +280,14 @@ class RTPacketMaster(Module):
|
||||||
tx_dp.raw_stb.eq(1),
|
tx_dp.raw_stb.eq(1),
|
||||||
extra_data_ce.eq(1),
|
extra_data_ce.eq(1),
|
||||||
If(extra_data_last,
|
If(extra_data_last,
|
||||||
wfb_re.eq(1),
|
sr_buf_re.eq(1),
|
||||||
NextState("IDLE")
|
NextState("IDLE")
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
tx_fsm.act("FIFO_SPACE",
|
tx_fsm.act("FIFO_SPACE",
|
||||||
tx_dp.send("fifo_space_request", channel=write_channel),
|
tx_dp.send("fifo_space_request", channel=sr_channel),
|
||||||
If(tx_dp.packet_last,
|
If(tx_dp.packet_last,
|
||||||
wfb_re.eq(1),
|
sr_buf_re.eq(1),
|
||||||
NextState("IDLE")
|
NextState("IDLE")
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
Loading…
Reference in New Issue