forked from M-Labs/artiq
drtio: implement basic writes, errors, fifo levels on satellite
This commit is contained in:
parent
23b3302200
commit
87ec333f55
|
@ -48,8 +48,12 @@ def get_s2m_layouts(alignment):
|
||||||
|
|
||||||
|
|
||||||
error_codes = {
|
error_codes = {
|
||||||
"frame_missed": 0,
|
"unknown_type": 0,
|
||||||
"unknown_type": 1
|
# The transmitter is normally responsible for avoiding
|
||||||
|
# overflows and underflows. Those error reports are only
|
||||||
|
# for diagnosing internal ARTIQ bugs.
|
||||||
|
"write_overflow": 1,
|
||||||
|
"write_underflow": 2
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -182,6 +186,21 @@ class RTPacketSatellite(Module):
|
||||||
self.tsc_load = Signal()
|
self.tsc_load = Signal()
|
||||||
self.tsc_value = Signal(64)
|
self.tsc_value = Signal(64)
|
||||||
|
|
||||||
|
self.fifo_level_channel = Signal(16)
|
||||||
|
self.fifo_level_update = Signal()
|
||||||
|
self.fifo_level = Signal(24)
|
||||||
|
|
||||||
|
self.write_stb = Signal()
|
||||||
|
self.write_timestamp = Signal(64)
|
||||||
|
self.write_channel = Signal(16)
|
||||||
|
self.write_address = Signal(16)
|
||||||
|
self.write_data = Signal(256)
|
||||||
|
self.write_overflow = Signal()
|
||||||
|
self.write_overflow_ack = Signal()
|
||||||
|
self.write_underflow = Signal()
|
||||||
|
self.write_underflow_ack = Signal()
|
||||||
|
|
||||||
|
|
||||||
# # #
|
# # #
|
||||||
|
|
||||||
# RX/TX datapath
|
# RX/TX datapath
|
||||||
|
@ -200,55 +219,108 @@ class RTPacketSatellite(Module):
|
||||||
self.tx_rt_data.eq(tx_dp.data)
|
self.tx_rt_data.eq(tx_dp.data)
|
||||||
]
|
]
|
||||||
|
|
||||||
# glue
|
# RX->TX
|
||||||
self.comb += [
|
echo_req = Signal()
|
||||||
self.tsc_value.eq(rx_dp.packet_as["set_time"].timestamp)
|
err_set = Signal()
|
||||||
]
|
err_req = Signal()
|
||||||
|
err_ack = Signal()
|
||||||
# main control FSM
|
fifo_level_set = Signal()
|
||||||
fsm = FSM(reset_state="WAIT_INPUT")
|
fifo_level_req = Signal()
|
||||||
self.submodules += fsm
|
fifo_level_ack = Signal()
|
||||||
|
|
||||||
continuation = Signal()
|
|
||||||
continuation_r = Signal()
|
|
||||||
frame_r_r = Signal()
|
|
||||||
self.sync += [
|
self.sync += [
|
||||||
continuation_r.eq(continuation),
|
If(err_ack, err_req.eq(0)),
|
||||||
frame_r_r.eq(rx_dp.frame_r)
|
If(err_set, err_req.eq(1)),
|
||||||
|
If(fifo_level_ack, fifo_level_req.eq(0)),
|
||||||
|
If(fifo_level_set, fifo_level_req.eq(1)),
|
||||||
]
|
]
|
||||||
fsm.act("WAIT_INPUT",
|
err_code = Signal(max=len(error_codes)+1)
|
||||||
|
|
||||||
|
# RX FSM
|
||||||
|
self.comb += [
|
||||||
|
self.tsc_value.eq(
|
||||||
|
rx_dp.packet_as["set_time"].timestamp),
|
||||||
|
self.fifo_level_channel.eq(
|
||||||
|
rx_dp.packet_as["fifo_level_request"].channel),
|
||||||
|
self.write_timestamp.eq(
|
||||||
|
rx_dp.packet_as["write"].timestamp),
|
||||||
|
self.write_channel.eq(
|
||||||
|
rx_dp.packet_as["write"].channel),
|
||||||
|
self.write_address.eq(
|
||||||
|
rx_dp.packet_as["write"].address),
|
||||||
|
self.write_data.eq(
|
||||||
|
rx_dp.packet_as["write"].short_data)
|
||||||
|
]
|
||||||
|
|
||||||
|
rx_fsm = FSM(reset_state="INPUT")
|
||||||
|
self.submodules += rx_fsm
|
||||||
|
|
||||||
|
rx_fsm.act("INPUT",
|
||||||
If(rx_dp.frame_r,
|
If(rx_dp.frame_r,
|
||||||
If(~frame_r_r | continuation_r,
|
|
||||||
continuation.eq(1),
|
|
||||||
rx_dp.packet_buffer_load.eq(1),
|
rx_dp.packet_buffer_load.eq(1),
|
||||||
If(rx_dp.packet_last,
|
If(rx_dp.packet_last,
|
||||||
Case(rx_dp.packet_type, {
|
Case(rx_dp.packet_type, {
|
||||||
rx_plm.types["echo_request"]: NextState("ECHO"),
|
rx_plm.types["echo_request"]: echo_req.eq(1),
|
||||||
rx_plm.types["set_time"]: NextState("SET_TIME"),
|
rx_plm.types["set_time"]: NextState("SET_TIME"),
|
||||||
"default": NextState("ERROR_UNKNOWN_TYPE")
|
rx_plm.types["write"]: NextState("WRITE"),
|
||||||
|
rx_plm.types["fifo_level_request"]: NextState("FIFO_LEVEL"),
|
||||||
|
"default": [
|
||||||
|
err_set.eq(1),
|
||||||
|
NextValue(err_code, error_codes["unknown_type"])]
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
).Else(
|
|
||||||
NextState("ERROR_FRAME_MISSED")
|
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
rx_fsm.act("SET_TIME",
|
||||||
|
self.tsc_load.eq(1),
|
||||||
|
NextState("INPUT")
|
||||||
)
|
)
|
||||||
fsm.act("ECHO",
|
rx_fsm.act("WRITE",
|
||||||
|
self.write_stb.eq(1),
|
||||||
|
NextState("INPUT")
|
||||||
|
)
|
||||||
|
rx_fsm.act("FIFO_LEVEL",
|
||||||
|
fifo_level_set.eq(1),
|
||||||
|
self.fifo_level_update.eq(1),
|
||||||
|
NextState("INPUT")
|
||||||
|
)
|
||||||
|
|
||||||
|
# TX FSM
|
||||||
|
tx_fsm = FSM(reset_state="IDLE")
|
||||||
|
self.submodules += tx_fsm
|
||||||
|
|
||||||
|
tx_fsm.act("IDLE",
|
||||||
|
If(echo_req, NextState("ECHO")),
|
||||||
|
If(fifo_level_req, NextState("FIFO_LEVEL")),
|
||||||
|
If(self.write_overflow, NextState("ERROR_WRITE_OVERFLOW")),
|
||||||
|
If(self.write_underflow, NextState("ERROR_WRITE_UNDERFLOW")),
|
||||||
|
If(err_req, NextState("ERROR"))
|
||||||
|
)
|
||||||
|
tx_fsm.act("ECHO",
|
||||||
tx_dp.send("echo_reply"),
|
tx_dp.send("echo_reply"),
|
||||||
tx_dp.stb.eq(1),
|
tx_dp.stb.eq(1),
|
||||||
If(tx_dp.done, NextState("WAIT_INPUT"))
|
If(tx_dp.done, NextState("IDLE"))
|
||||||
)
|
)
|
||||||
fsm.act("SET_TIME",
|
tx_fsm.act("FIFO_LEVEL",
|
||||||
self.tsc_load.eq(1),
|
fifo_level_ack.eq(1),
|
||||||
NextState("WAIT_INPUT")
|
tx_dp.send("fifo_level_reply", level=self.fifo_level),
|
||||||
)
|
|
||||||
fsm.act("ERROR_FRAME_MISSED",
|
|
||||||
tx_dp.send("error", code=error_codes["frame_missed"]),
|
|
||||||
tx_dp.stb.eq(1),
|
tx_dp.stb.eq(1),
|
||||||
If(tx_dp.done, NextState("WAIT_INPUT"))
|
If(tx_dp.done, NextState("IDLE"))
|
||||||
)
|
)
|
||||||
fsm.act("ERROR_UNKNOWN_TYPE",
|
tx_fsm.act("ERROR_WRITE_OVERFLOW",
|
||||||
tx_dp.send("error", code=error_codes["unknown_type"]),
|
self.write_overflow_ack.eq(1),
|
||||||
|
tx_dp.send("error", code=error_codes["write_overflow"]),
|
||||||
tx_dp.stb.eq(1),
|
tx_dp.stb.eq(1),
|
||||||
If(tx_dp.done, NextState("WAIT_INPUT"))
|
If(tx_dp.done, NextState("IDLE"))
|
||||||
|
)
|
||||||
|
tx_fsm.act("ERROR_WRITE_UNDERFLOW",
|
||||||
|
self.write_underflow_ack.eq(1),
|
||||||
|
tx_dp.send("error", code=error_codes["write_underflow"]),
|
||||||
|
tx_dp.stb.eq(1),
|
||||||
|
If(tx_dp.done, NextState("IDLE"))
|
||||||
|
)
|
||||||
|
tx_fsm.act("ERROR",
|
||||||
|
err_ack.eq(1),
|
||||||
|
tx_dp.send("error", code=err_code),
|
||||||
|
tx_dp.stb.eq(1),
|
||||||
|
If(tx_dp.done, NextState("IDLE"))
|
||||||
)
|
)
|
||||||
|
|
Loading…
Reference in New Issue