artiq/artiq/gateware/drtio/rt_controller_repeater.py

64 lines
2.3 KiB
Python
Raw Normal View History

2018-09-05 16:08:40 +08:00
from migen import *
2019-07-05 18:46:18 +08:00
from migen.genlib.cdc import MultiReg, BlindTransfer
2018-09-05 16:08:40 +08:00
from misoc.interconnect.csr import *
2018-09-09 14:11:21 +08:00
from artiq.gateware.drtio.cdc import CrossDomainRequest
2018-09-05 16:08:40 +08:00
class RTController(Module, AutoCSR):
def __init__(self, rt_packet):
2018-09-20 10:58:38 +08:00
self.reset = CSRStorage()
2018-09-05 16:08:40 +08:00
self.set_time = CSR()
self.protocol_error = CSR(4)
2018-09-12 20:54:01 +08:00
self.command_missed_cmd = CSRStatus(2)
2018-09-12 15:44:34 +08:00
self.command_missed_chan_sel = CSRStatus(24)
self.buffer_space_timeout_dest = CSRStatus(8)
self.async_messages_ready = CSR()
2018-09-05 16:08:40 +08:00
2022-12-17 15:39:54 +08:00
self.sync += rt_packet.reset.eq(self.reset.storage)
2018-09-20 10:58:38 +08:00
2018-09-05 16:08:40 +08:00
self.sync += [
2023-12-01 16:34:33 +08:00
If(rt_packet.set_time_ack, rt_packet.set_time_stb.eq(0)),
If(self.set_time.re, rt_packet.set_time_stb.eq(1))
2018-09-05 16:08:40 +08:00
]
2023-12-01 16:34:33 +08:00
self.comb += self.set_time.w.eq(rt_packet.set_time_stb)
2018-09-05 16:08:40 +08:00
self.sync += [
If(rt_packet.async_messages_ready, self.async_messages_ready.w.eq(1)),
If(self.async_messages_ready.re, self.async_messages_ready.w.eq(0))
]
2018-09-05 16:08:40 +08:00
errors = [
2018-09-12 15:44:34 +08:00
(rt_packet.err_unknown_packet_type, "rtio_rx", None, None),
(rt_packet.err_packet_truncated, "rtio_rx", None, None),
2022-12-17 15:39:54 +08:00
(rt_packet.err_command_missed, "sys",
2018-09-12 20:54:01 +08:00
Cat(rt_packet.command_missed_cmd, rt_packet.command_missed_chan_sel),
Cat(self.command_missed_cmd.status, self.command_missed_chan_sel.status)),
2022-12-17 15:39:54 +08:00
(rt_packet.err_buffer_space_timeout, "sys",
2018-09-12 15:44:34 +08:00
rt_packet.buffer_space_destination, self.buffer_space_timeout_dest.status)
2018-09-05 16:08:40 +08:00
]
2018-09-12 15:44:34 +08:00
for n, (err_i, err_cd, din, dout) in enumerate(errors):
if din is not None:
data_width = len(din)
else:
data_width = 0
xfer = BlindTransfer(err_cd, "sys", data_width=data_width)
2018-09-05 16:08:40 +08:00
self.submodules += xfer
self.comb += xfer.i.eq(err_i)
err_pending = Signal()
self.sync += [
If(self.protocol_error.re & self.protocol_error.r[n], err_pending.eq(0)),
If(xfer.o, err_pending.eq(1))
]
self.comb += self.protocol_error.w[n].eq(err_pending)
2018-09-12 15:44:34 +08:00
if din is not None:
self.comb += xfer.data_i.eq(din)
self.sync += If(xfer.o & ~err_pending, dout.eq(xfer.data_o))