forked from M-Labs/artiq
drtio: implement TSC load in satellite
This commit is contained in:
parent
43caffc168
commit
23b3302200
|
@ -64,7 +64,7 @@ class ReceiveDatapath(Module):
|
||||||
|
|
||||||
# outputs
|
# outputs
|
||||||
self.frame_r = Signal()
|
self.frame_r = Signal()
|
||||||
self.data_r = Signal()
|
self.data_r = Signal(ws)
|
||||||
self.packet_type = Signal(8)
|
self.packet_type = Signal(8)
|
||||||
self.packet_last = Signal()
|
self.packet_last = Signal()
|
||||||
self.packet_as = dict()
|
self.packet_as = dict()
|
||||||
|
@ -171,15 +171,20 @@ class TransmitDatapath(Module):
|
||||||
|
|
||||||
class RTPacketSatellite(Module):
|
class RTPacketSatellite(Module):
|
||||||
def __init__(self, nwords):
|
def __init__(self, nwords):
|
||||||
|
# link layer interface
|
||||||
ws = 8*nwords
|
ws = 8*nwords
|
||||||
self.rx_rt_frame = Signal()
|
self.rx_rt_frame = Signal()
|
||||||
self.rx_rt_data = Signal(ws)
|
self.rx_rt_data = Signal(ws)
|
||||||
|
|
||||||
self.tx_rt_frame = Signal()
|
self.tx_rt_frame = Signal()
|
||||||
self.tx_rt_data = Signal(ws)
|
self.tx_rt_data = Signal(ws)
|
||||||
|
|
||||||
|
# I/O Timer interface
|
||||||
|
self.tsc_load = Signal()
|
||||||
|
self.tsc_value = Signal(64)
|
||||||
|
|
||||||
# # #
|
# # #
|
||||||
|
|
||||||
|
# RX/TX datapath
|
||||||
rx_plm = get_m2s_layouts(ws)
|
rx_plm = get_m2s_layouts(ws)
|
||||||
rx_dp = ReceiveDatapath(ws, rx_plm)
|
rx_dp = ReceiveDatapath(ws, rx_plm)
|
||||||
self.submodules += rx_dp
|
self.submodules += rx_dp
|
||||||
|
@ -187,7 +192,6 @@ class RTPacketSatellite(Module):
|
||||||
rx_dp.frame.eq(self.rx_rt_frame),
|
rx_dp.frame.eq(self.rx_rt_frame),
|
||||||
rx_dp.data.eq(self.rx_rt_data)
|
rx_dp.data.eq(self.rx_rt_data)
|
||||||
]
|
]
|
||||||
|
|
||||||
tx_plm = get_s2m_layouts(ws)
|
tx_plm = get_s2m_layouts(ws)
|
||||||
tx_dp = TransmitDatapath(ws, tx_plm)
|
tx_dp = TransmitDatapath(ws, tx_plm)
|
||||||
self.submodules += tx_dp
|
self.submodules += tx_dp
|
||||||
|
@ -196,6 +200,12 @@ class RTPacketSatellite(Module):
|
||||||
self.tx_rt_data.eq(tx_dp.data)
|
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")
|
fsm = FSM(reset_state="WAIT_INPUT")
|
||||||
self.submodules += fsm
|
self.submodules += fsm
|
||||||
|
|
||||||
|
@ -214,6 +224,7 @@ class RTPacketSatellite(Module):
|
||||||
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"]: NextState("ECHO"),
|
||||||
|
rx_plm.types["set_time"]: NextState("SET_TIME"),
|
||||||
"default": NextState("ERROR_UNKNOWN_TYPE")
|
"default": NextState("ERROR_UNKNOWN_TYPE")
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
|
@ -227,6 +238,10 @@ class RTPacketSatellite(Module):
|
||||||
tx_dp.stb.eq(1),
|
tx_dp.stb.eq(1),
|
||||||
If(tx_dp.done, NextState("WAIT_INPUT"))
|
If(tx_dp.done, NextState("WAIT_INPUT"))
|
||||||
)
|
)
|
||||||
|
fsm.act("SET_TIME",
|
||||||
|
self.tsc_load.eq(1),
|
||||||
|
NextState("WAIT_INPUT")
|
||||||
|
)
|
||||||
fsm.act("ERROR_FRAME_MISSED",
|
fsm.act("ERROR_FRAME_MISSED",
|
||||||
tx_dp.send("error", code=error_codes["frame_missed"]),
|
tx_dp.send("error", code=error_codes["frame_missed"]),
|
||||||
tx_dp.stb.eq(1),
|
tx_dp.stb.eq(1),
|
||||||
|
|
|
@ -91,3 +91,25 @@ class TestSatellite(unittest.TestCase):
|
||||||
self.assertEqual(trailer, [])
|
self.assertEqual(trailer, [])
|
||||||
completed = True
|
completed = True
|
||||||
run_simulation(dut, [send(), pr.receive(receive)])
|
run_simulation(dut, [send(), pr.receive(receive)])
|
||||||
|
|
||||||
|
def test_set_time(self):
|
||||||
|
for nwords in range(1, 8):
|
||||||
|
dut = RTPacketSatellite(nwords)
|
||||||
|
pt = PacketInterface("m2s", dut.rx_rt_frame, dut.rx_rt_data)
|
||||||
|
tx_times = [0x12345678aabbccdd, 0x0102030405060708,
|
||||||
|
0xaabbccddeeff1122]
|
||||||
|
def send():
|
||||||
|
for t in tx_times:
|
||||||
|
yield from pt.send("set_time", timestamp=t)
|
||||||
|
# flush
|
||||||
|
for i in range(10):
|
||||||
|
yield
|
||||||
|
rx_times = []
|
||||||
|
@passive
|
||||||
|
def receive():
|
||||||
|
while True:
|
||||||
|
if (yield dut.tsc_load):
|
||||||
|
rx_times.append((yield dut.tsc_value))
|
||||||
|
yield
|
||||||
|
run_simulation(dut, [send(), receive()], vcd_name="foo.vcd")
|
||||||
|
self.assertEqual(tx_times, rx_times)
|
||||||
|
|
Loading…
Reference in New Issue