mirror of https://github.com/m-labs/artiq.git
drtio: add buffering to repeater
This commit is contained in:
parent
2b44786f73
commit
eda15a596c
|
@ -48,16 +48,57 @@ class RTPacketRepeater(Module):
|
||||||
tsc_value_load = Signal()
|
tsc_value_load = Signal()
|
||||||
self.sync.rtio += If(tsc_value_load, tsc_value.eq(tsc.coarse_ts))
|
self.sync.rtio += If(tsc_value_load, tsc_value.eq(tsc.coarse_ts))
|
||||||
|
|
||||||
# Write buffer and extra data count
|
# CRI buffer stage 1
|
||||||
wb_timestamp = Signal(64)
|
cb0_loaded = Signal()
|
||||||
wb_chan_sel = Signal(24)
|
cb0_ack = Signal()
|
||||||
wb_address = Signal(16)
|
|
||||||
wb_data = Signal(512)
|
cb0_cmd = Signal(2)
|
||||||
self.sync.rtio += If(self.cri.cmd == cri.commands["write"],
|
cb0_timestamp = Signal(64)
|
||||||
wb_timestamp.eq(self.cri.timestamp),
|
cb0_chan_sel = Signal(24)
|
||||||
wb_chan_sel.eq(self.cri.chan_sel),
|
cb0_o_address = Signal(16)
|
||||||
wb_address.eq(self.cri.o_address),
|
cb0_o_data = Signal(512)
|
||||||
wb_data.eq(self.cri.o_data))
|
self.sync.rtio += [
|
||||||
|
If(cb0_ack,
|
||||||
|
cb0_loaded.eq(0),
|
||||||
|
cb0_cmd.eq(cri.commands["nop"])
|
||||||
|
),
|
||||||
|
If(~cb0_loaded & (self.cri.cmd != cri.commands["nop"]),
|
||||||
|
cb0_loaded.eq(1),
|
||||||
|
cb0_cmd.eq(self.cri.cmd),
|
||||||
|
cb0_timestamp.eq(self.cri.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)
|
||||||
|
),
|
||||||
|
self.err_command_missed.eq(cb0_loaded & (self.cri.cmd != cri.commands["nop"])),
|
||||||
|
self.command_missed_chan_sel.eq(self.cri.chan_sel),
|
||||||
|
self.command_missed_cmd.eq(self.cri.cmd)
|
||||||
|
]
|
||||||
|
|
||||||
|
# CRI buffer stage 2 and write data slicer
|
||||||
|
cb_loaded = Signal()
|
||||||
|
cb_ack = Signal()
|
||||||
|
|
||||||
|
cb_cmd = Signal(2)
|
||||||
|
cb_timestamp = Signal(64)
|
||||||
|
cb_chan_sel = Signal(24)
|
||||||
|
cb_o_address = Signal(16)
|
||||||
|
cb_o_data = Signal(512)
|
||||||
|
self.sync.rtio += [
|
||||||
|
If(cb_ack,
|
||||||
|
cb_loaded.eq(0),
|
||||||
|
cb_cmd.eq(cri.commands["nop"])
|
||||||
|
),
|
||||||
|
If(~cb_loaded & cb0_loaded,
|
||||||
|
cb_loaded.eq(1),
|
||||||
|
cb_cmd.eq(cb0_cmd),
|
||||||
|
cb_timestamp.eq(cb0_timestamp),
|
||||||
|
cb_chan_sel.eq(cb0_chan_sel),
|
||||||
|
cb_o_address.eq(cb0_o_address),
|
||||||
|
cb_o_data.eq(cb0_o_data)
|
||||||
|
)
|
||||||
|
]
|
||||||
|
self.comb += cb0_ack.eq(~cb_loaded)
|
||||||
|
|
||||||
wb_extra_data_cnt = Signal(8)
|
wb_extra_data_cnt = Signal(8)
|
||||||
short_data_len = tx_plm.field_length("write", "short_data")
|
short_data_len = tx_plm.field_length("write", "short_data")
|
||||||
|
@ -104,12 +145,6 @@ class RTPacketRepeater(Module):
|
||||||
self.submodules += timeout_counter
|
self.submodules += timeout_counter
|
||||||
|
|
||||||
# Read
|
# Read
|
||||||
rb_chan_sel = Signal(24)
|
|
||||||
rb_timeout = Signal(64)
|
|
||||||
self.sync.rtio += If(self.cri.cmd == cri.commands["read"],
|
|
||||||
rb_chan_sel.eq(self.cri.chan_sel),
|
|
||||||
rb_timeout.eq(self.cri.timestamp))
|
|
||||||
|
|
||||||
read_not = Signal()
|
read_not = Signal()
|
||||||
read_no_event = Signal()
|
read_no_event = Signal()
|
||||||
read_is_overflow = Signal()
|
read_is_overflow = Signal()
|
||||||
|
@ -137,9 +172,8 @@ class RTPacketRepeater(Module):
|
||||||
# input status
|
# input status
|
||||||
i_status_wait_event = Signal()
|
i_status_wait_event = Signal()
|
||||||
i_status_overflow = Signal()
|
i_status_overflow = Signal()
|
||||||
i_status_wait_status = Signal()
|
|
||||||
self.comb += self.cri.i_status.eq(Cat(
|
self.comb += self.cri.i_status.eq(Cat(
|
||||||
i_status_wait_event, i_status_overflow, i_status_wait_status))
|
i_status_wait_event, i_status_overflow, cb0_loaded | cb_loaded))
|
||||||
|
|
||||||
load_read_reply = Signal()
|
load_read_reply = Signal()
|
||||||
self.sync.rtio += [
|
self.sync.rtio += [
|
||||||
|
@ -158,14 +192,6 @@ class RTPacketRepeater(Module):
|
||||||
)
|
)
|
||||||
]
|
]
|
||||||
|
|
||||||
# Missed commands
|
|
||||||
cri_ready = Signal()
|
|
||||||
self.sync.rtio += [
|
|
||||||
self.err_command_missed.eq(~cri_ready & (self.cri.cmd != cri.commands["nop"])),
|
|
||||||
self.command_missed_chan_sel.eq(self.cri.chan_sel),
|
|
||||||
self.command_missed_cmd.eq(self.cri.cmd)
|
|
||||||
]
|
|
||||||
|
|
||||||
# TX and CRI FSM
|
# TX and CRI FSM
|
||||||
tx_fsm = ClockDomainsRenamer("rtio")(FSM(reset_state="IDLE"))
|
tx_fsm = ClockDomainsRenamer("rtio")(FSM(reset_state="IDLE"))
|
||||||
self.submodules += tx_fsm
|
self.submodules += tx_fsm
|
||||||
|
@ -179,10 +205,9 @@ class RTPacketRepeater(Module):
|
||||||
tsc_value_load.eq(1),
|
tsc_value_load.eq(1),
|
||||||
NextState("SET_TIME")
|
NextState("SET_TIME")
|
||||||
).Else(
|
).Else(
|
||||||
cri_ready.eq(1),
|
If(cb_cmd == cri.commands["write"], NextState("WRITE")),
|
||||||
If(self.cri.cmd == cri.commands["write"], NextState("WRITE")),
|
If(cb_cmd == cri.commands["get_buffer_space"], NextState("BUFFER_SPACE")),
|
||||||
If(self.cri.cmd == cri.commands["get_buffer_space"], NextState("BUFFER_SPACE")),
|
If(cb_cmd == cri.commands["read"], NextState("READ"))
|
||||||
If(self.cri.cmd == cri.commands["read"], NextState("READ"))
|
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -196,13 +221,14 @@ class RTPacketRepeater(Module):
|
||||||
|
|
||||||
tx_fsm.act("WRITE",
|
tx_fsm.act("WRITE",
|
||||||
tx_dp.send("write",
|
tx_dp.send("write",
|
||||||
timestamp=wb_timestamp,
|
timestamp=cb_timestamp,
|
||||||
chan_sel=wb_chan_sel,
|
chan_sel=cb_chan_sel,
|
||||||
address=wb_address,
|
address=cb_o_address,
|
||||||
extra_data_cnt=wb_extra_data_cnt,
|
extra_data_cnt=wb_extra_data_cnt,
|
||||||
short_data=wb_data[:short_data_len]),
|
short_data=cb_o_data[:short_data_len]),
|
||||||
If(tx_dp.packet_last,
|
If(tx_dp.packet_last,
|
||||||
If(wb_extra_data_cnt == 0,
|
If(wb_extra_data_cnt == 0,
|
||||||
|
cb_ack.eq(1),
|
||||||
NextState("IDLE")
|
NextState("IDLE")
|
||||||
).Else(
|
).Else(
|
||||||
NextState("WRITE_EXTRA")
|
NextState("WRITE_EXTRA")
|
||||||
|
@ -213,6 +239,7 @@ class RTPacketRepeater(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,
|
||||||
|
cb_ack.eq(1),
|
||||||
NextState("IDLE")
|
NextState("IDLE")
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
@ -228,30 +255,31 @@ class RTPacketRepeater(Module):
|
||||||
timeout_counter.wait.eq(1),
|
timeout_counter.wait.eq(1),
|
||||||
If(timeout_counter.done,
|
If(timeout_counter.done,
|
||||||
self.err_buffer_space_timeout.eq(1),
|
self.err_buffer_space_timeout.eq(1),
|
||||||
|
cb_ack.eq(1),
|
||||||
NextState("READY")
|
NextState("READY")
|
||||||
).Else(
|
).Else(
|
||||||
If(buffer_space_not,
|
If(buffer_space_not,
|
||||||
self.cri.o_buffer_space_valid.eq(1),
|
self.cri.o_buffer_space_valid.eq(1),
|
||||||
|
cb_ack.eq(1),
|
||||||
NextState("READY")
|
NextState("READY")
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
tx_fsm.act("READ",
|
tx_fsm.act("READ",
|
||||||
i_status_wait_status.eq(1),
|
|
||||||
tx_dp.send("read_request",
|
tx_dp.send("read_request",
|
||||||
chan_sel=rb_chan_sel,
|
chan_sel=cb_chan_sel,
|
||||||
timeout=rb_timeout),
|
timeout=cb_timestamp),
|
||||||
rtio_read_not_ack.eq(1),
|
rtio_read_not_ack.eq(1),
|
||||||
If(tx_dp.packet_last,
|
If(tx_dp.packet_last,
|
||||||
NextState("GET_READ_REPLY")
|
NextState("GET_READ_REPLY")
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
tx_fsm.act("GET_READ_REPLY",
|
tx_fsm.act("GET_READ_REPLY",
|
||||||
i_status_wait_status.eq(1),
|
|
||||||
rtio_read_not_ack.eq(1),
|
rtio_read_not_ack.eq(1),
|
||||||
If(rtio_read_not,
|
If(rtio_read_not,
|
||||||
load_read_reply.eq(1),
|
load_read_reply.eq(1),
|
||||||
|
cb_ack.eq(1),
|
||||||
NextState("READY")
|
NextState("READY")
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
Loading…
Reference in New Issue