From 87ec333f5556a20ce533e3913e9ed90210b3f20a Mon Sep 17 00:00:00 2001 From: Sebastien Bourdeauducq Date: Mon, 10 Oct 2016 00:13:41 +0800 Subject: [PATCH] drtio: implement basic writes, errors, fifo levels on satellite --- artiq/gateware/drtio/rt_packets.py | 154 +++++++++++++++++++++-------- 1 file changed, 113 insertions(+), 41 deletions(-) diff --git a/artiq/gateware/drtio/rt_packets.py b/artiq/gateware/drtio/rt_packets.py index be7971316..9dbc825fb 100644 --- a/artiq/gateware/drtio/rt_packets.py +++ b/artiq/gateware/drtio/rt_packets.py @@ -48,8 +48,12 @@ def get_s2m_layouts(alignment): error_codes = { - "frame_missed": 0, - "unknown_type": 1 + "unknown_type": 0, + # 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 } @@ -181,6 +185,21 @@ class RTPacketSatellite(Module): # I/O Timer interface self.tsc_load = Signal() 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() + # # # @@ -200,55 +219,108 @@ class RTPacketSatellite(Module): self.tx_rt_data.eq(tx_dp.data) ] - # glue - self.comb += [ - self.tsc_value.eq(rx_dp.packet_as["set_time"].timestamp) - ] - - # main control FSM - fsm = FSM(reset_state="WAIT_INPUT") - self.submodules += fsm - - continuation = Signal() - continuation_r = Signal() - frame_r_r = Signal() + # RX->TX + echo_req = Signal() + err_set = Signal() + err_req = Signal() + err_ack = Signal() + fifo_level_set = Signal() + fifo_level_req = Signal() + fifo_level_ack = Signal() self.sync += [ - continuation_r.eq(continuation), - frame_r_r.eq(rx_dp.frame_r) + If(err_ack, err_req.eq(0)), + 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(~frame_r_r | continuation_r, - continuation.eq(1), - rx_dp.packet_buffer_load.eq(1), - If(rx_dp.packet_last, - Case(rx_dp.packet_type, { - rx_plm.types["echo_request"]: NextState("ECHO"), - rx_plm.types["set_time"]: NextState("SET_TIME"), - "default": NextState("ERROR_UNKNOWN_TYPE") - }) - ) - ).Else( - NextState("ERROR_FRAME_MISSED") + rx_dp.packet_buffer_load.eq(1), + If(rx_dp.packet_last, + Case(rx_dp.packet_type, { + rx_plm.types["echo_request"]: echo_req.eq(1), + rx_plm.types["set_time"]: NextState("SET_TIME"), + 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"])] + }) ) ) ) - fsm.act("ECHO", + rx_fsm.act("SET_TIME", + self.tsc_load.eq(1), + NextState("INPUT") + ) + 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.stb.eq(1), - If(tx_dp.done, NextState("WAIT_INPUT")) + If(tx_dp.done, NextState("IDLE")) ) - fsm.act("SET_TIME", - self.tsc_load.eq(1), - NextState("WAIT_INPUT") - ) - fsm.act("ERROR_FRAME_MISSED", - tx_dp.send("error", code=error_codes["frame_missed"]), + tx_fsm.act("FIFO_LEVEL", + fifo_level_ack.eq(1), + tx_dp.send("fifo_level_reply", level=self.fifo_level), tx_dp.stb.eq(1), - If(tx_dp.done, NextState("WAIT_INPUT")) + If(tx_dp.done, NextState("IDLE")) ) - fsm.act("ERROR_UNKNOWN_TYPE", - tx_dp.send("error", code=error_codes["unknown_type"]), + tx_fsm.act("ERROR_WRITE_OVERFLOW", + self.write_overflow_ack.eq(1), + tx_dp.send("error", code=error_codes["write_overflow"]), 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")) )