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),
|
||||
last_timestamps.adr.eq(chan_sel),
|
||||
last_timestamps.dat_w.eq(self.cri.timestamp),
|
||||
rt_packets.write_channel.eq(chan_sel),
|
||||
rt_packets.write_address.eq(self.cri.o_address),
|
||||
rt_packets.write_data.eq(self.cri.o_data),
|
||||
rt_packets.sr_channel.eq(chan_sel),
|
||||
rt_packets.sr_address.eq(self.cri.o_address),
|
||||
rt_packets.sr_data.eq(self.cri.o_data),
|
||||
rt_packets.sr_timestamp.eq(self.cri.timestamp),
|
||||
If(rt_packets_fifo_request,
|
||||
rt_packets.write_timestamp.eq(0xffff000000000000)
|
||||
).Else(
|
||||
rt_packets.write_timestamp.eq(self.cri.timestamp)
|
||||
rt_packets.sr_notwrite.eq(1),
|
||||
rt_packets.sr_address.eq(0)
|
||||
)
|
||||
]
|
||||
|
||||
@ -159,8 +159,8 @@ class RTController(Module):
|
||||
)
|
||||
fsm.act("WRITE",
|
||||
status_wait.eq(1),
|
||||
rt_packets.write_stb.eq(1),
|
||||
If(rt_packets.write_ack,
|
||||
rt_packets.sr_stb.eq(1),
|
||||
If(rt_packets.sr_ack,
|
||||
fifo_spaces.we.eq(1),
|
||||
fifo_spaces.dat_w.eq(fifo_spaces.dat_r - 1),
|
||||
last_timestamps.we.eq(1),
|
||||
@ -174,9 +174,9 @@ class RTController(Module):
|
||||
fsm.act("GET_FIFO_SPACE",
|
||||
status_wait.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),
|
||||
If(rt_packets.write_ack,
|
||||
If(rt_packets.sr_ack,
|
||||
NextState("GET_FIFO_SPACE_REPLY")
|
||||
)
|
||||
)
|
||||
@ -211,7 +211,7 @@ class RTController(Module):
|
||||
)
|
||||
]
|
||||
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 + 1)
|
||||
)
|
||||
|
@ -61,20 +61,28 @@ class _CrossDomainNotification(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
|
||||
|
||||
# write interface, optimized for throughput
|
||||
self.write_stb = Signal()
|
||||
self.write_ack = Signal()
|
||||
self.write_timestamp = Signal(64)
|
||||
self.write_channel = Signal(16)
|
||||
self.write_address = Signal(16)
|
||||
self.write_data = Signal(512)
|
||||
# standard request interface
|
||||
#
|
||||
# notwrite=1 address=0 FIFO space request <channel>
|
||||
# notwrite=1 address=1 read request <channel, timestamp>
|
||||
# notwrite=1 address=2 read consume
|
||||
#
|
||||
# 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
|
||||
# write with timestamp[48:] == 0xffff to make a fifo space request
|
||||
# (space requests have to be ordered wrt writes)
|
||||
# fifo space reply interface
|
||||
self.fifo_space_not = Signal()
|
||||
self.fifo_space_not_ack = Signal()
|
||||
self.fifo_space = Signal(16)
|
||||
@ -122,63 +130,66 @@ class RTPacketMaster(Module):
|
||||
self.submodules += rx_dp
|
||||
|
||||
# Write FIFO and extra data count
|
||||
wfifo = ClockDomainsRenamer({"write": "sys_with_rst", "read": "rtio_with_rst"})(
|
||||
AsyncFIFO(64+16+16+512, write_fifo_depth))
|
||||
self.submodules += wfifo
|
||||
write_timestamp_d = Signal(64)
|
||||
write_channel_d = Signal(16)
|
||||
write_address_d = Signal(16)
|
||||
write_data_d = Signal(512)
|
||||
sr_fifo = ClockDomainsRenamer({"write": "sys_with_rst", "read": "rtio_with_rst"})(
|
||||
AsyncFIFO(1+64+16+16+512, sr_fifo_depth))
|
||||
self.submodules += sr_fifo
|
||||
sr_notwrite_d = Signal()
|
||||
sr_timestamp_d = Signal(64)
|
||||
sr_channel_d = Signal(16)
|
||||
sr_address_d = Signal(16)
|
||||
sr_data_d = Signal(512)
|
||||
self.comb += [
|
||||
wfifo.we.eq(self.write_stb),
|
||||
self.write_ack.eq(wfifo.writable),
|
||||
wfifo.din.eq(Cat(self.write_timestamp, self.write_channel,
|
||||
self.write_address, self.write_data)),
|
||||
Cat(write_timestamp_d, write_channel_d,
|
||||
write_address_d, write_data_d).eq(wfifo.dout)
|
||||
sr_fifo.we.eq(self.sr_stb),
|
||||
self.sr_ack.eq(sr_fifo.writable),
|
||||
sr_fifo.din.eq(Cat(self.sr_notwrite, self.sr_timestamp, self.sr_channel,
|
||||
self.sr_address, self.sr_data)),
|
||||
Cat(sr_notwrite_d, sr_timestamp_d, sr_channel_d,
|
||||
sr_address_d, sr_data_d).eq(sr_fifo.dout)
|
||||
]
|
||||
|
||||
wfb_readable = Signal()
|
||||
wfb_re = Signal()
|
||||
sr_buf_readable = 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 += \
|
||||
If(wfifo.re,
|
||||
wfb_readable.eq(1),
|
||||
).Elif(wfb_re,
|
||||
wfb_readable.eq(0),
|
||||
If(sr_fifo.re,
|
||||
sr_buf_readable.eq(1),
|
||||
).Elif(sr_buf_re,
|
||||
sr_buf_readable.eq(0),
|
||||
)
|
||||
|
||||
write_timestamp = Signal(64)
|
||||
write_channel = Signal(16)
|
||||
write_address = Signal(16)
|
||||
write_extra_data_cnt = Signal(8)
|
||||
write_data = Signal(512)
|
||||
sr_notwrite = Signal()
|
||||
sr_timestamp = Signal(64)
|
||||
sr_channel = Signal(16)
|
||||
sr_address = Signal(16)
|
||||
sr_extra_data_cnt = Signal(8)
|
||||
sr_data = Signal(512)
|
||||
|
||||
self.sync.rtio += If(wfifo.re,
|
||||
write_timestamp.eq(write_timestamp_d),
|
||||
write_channel.eq(write_channel_d),
|
||||
write_address.eq(write_address_d),
|
||||
write_data.eq(write_data_d))
|
||||
self.sync.rtio += If(sr_fifo.re,
|
||||
sr_notwrite.eq(sr_notwrite_d),
|
||||
sr_timestamp.eq(sr_timestamp_d),
|
||||
sr_channel.eq(sr_channel_d),
|
||||
sr_address.eq(sr_address_d),
|
||||
sr_data.eq(sr_data_d))
|
||||
|
||||
short_data_len = tx_plm.field_length("write", "short_data")
|
||||
write_extra_data_d = Signal(512)
|
||||
self.comb += write_extra_data_d.eq(write_data_d[short_data_len:])
|
||||
sr_extra_data_d = Signal(512)
|
||||
self.comb += sr_extra_data_d.eq(sr_data_d[short_data_len:])
|
||||
for i in range(512//ws):
|
||||
self.sync.rtio += If(wfifo.re,
|
||||
If(write_extra_data_d[ws*i:ws*(i+1)] != 0, write_extra_data_cnt.eq(i+1)))
|
||||
self.sync.rtio += If(sr_fifo.re,
|
||||
If(sr_extra_data_d[ws*i:ws*(i+1)] != 0, sr_extra_data_cnt.eq(i+1)))
|
||||
|
||||
write_extra_data = Signal(512)
|
||||
self.sync.rtio += If(wfifo.re, write_extra_data.eq(write_extra_data_d))
|
||||
sr_extra_data = Signal(512)
|
||||
self.sync.rtio += If(sr_fifo.re, sr_extra_data.eq(sr_extra_data_d))
|
||||
|
||||
extra_data_ce = Signal()
|
||||
extra_data_last = Signal()
|
||||
extra_data_counter = Signal(max=512//ws+1)
|
||||
self.comb += [
|
||||
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)}),
|
||||
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 += \
|
||||
If(extra_data_ce,
|
||||
@ -230,8 +241,9 @@ class RTPacketMaster(Module):
|
||||
self.sync.rtio += If(tsc_value_load, tsc_value.eq(self.tsc_value))
|
||||
|
||||
tx_fsm.act("IDLE",
|
||||
If(wfb_readable,
|
||||
If(write_timestamp[48:] == 0xffff,
|
||||
If(sr_buf_readable,
|
||||
If(sr_notwrite,
|
||||
# TODO: sr_address
|
||||
NextState("FIFO_SPACE")
|
||||
).Else(
|
||||
NextState("WRITE")
|
||||
@ -250,14 +262,14 @@ class RTPacketMaster(Module):
|
||||
)
|
||||
tx_fsm.act("WRITE",
|
||||
tx_dp.send("write",
|
||||
timestamp=write_timestamp,
|
||||
channel=write_channel,
|
||||
address=write_address,
|
||||
extra_data_cnt=write_extra_data_cnt,
|
||||
short_data=write_data[:short_data_len]),
|
||||
timestamp=sr_timestamp,
|
||||
channel=sr_channel,
|
||||
address=sr_address,
|
||||
extra_data_cnt=sr_extra_data_cnt,
|
||||
short_data=sr_data[:short_data_len]),
|
||||
If(tx_dp.packet_last,
|
||||
If(write_extra_data_cnt == 0,
|
||||
wfb_re.eq(1),
|
||||
If(sr_extra_data_cnt == 0,
|
||||
sr_buf_re.eq(1),
|
||||
NextState("IDLE")
|
||||
).Else(
|
||||
NextState("WRITE_EXTRA")
|
||||
@ -268,14 +280,14 @@ class RTPacketMaster(Module):
|
||||
tx_dp.raw_stb.eq(1),
|
||||
extra_data_ce.eq(1),
|
||||
If(extra_data_last,
|
||||
wfb_re.eq(1),
|
||||
sr_buf_re.eq(1),
|
||||
NextState("IDLE")
|
||||
)
|
||||
)
|
||||
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,
|
||||
wfb_re.eq(1),
|
||||
sr_buf_re.eq(1),
|
||||
NextState("IDLE")
|
||||
)
|
||||
)
|
||||
|
Loading…
Reference in New Issue
Block a user