forked from M-Labs/artiq
drtio: input support (untested)
This commit is contained in:
parent
d1b9f9d737
commit
497c795d8c
@ -96,6 +96,7 @@ class RTController(Module):
|
|||||||
|
|
||||||
# common packet fields
|
# common packet fields
|
||||||
rt_packet_fifo_request = Signal()
|
rt_packet_fifo_request = Signal()
|
||||||
|
rt_packet_read_request = Signal()
|
||||||
self.comb += [
|
self.comb += [
|
||||||
fifo_spaces.adr.eq(chan_sel),
|
fifo_spaces.adr.eq(chan_sel),
|
||||||
last_timestamps.adr.eq(chan_sel),
|
last_timestamps.adr.eq(chan_sel),
|
||||||
@ -107,27 +108,29 @@ class RTController(Module):
|
|||||||
If(rt_packet_fifo_request,
|
If(rt_packet_fifo_request,
|
||||||
rt_packet.sr_notwrite.eq(1),
|
rt_packet.sr_notwrite.eq(1),
|
||||||
rt_packet.sr_address.eq(0)
|
rt_packet.sr_address.eq(0)
|
||||||
|
),
|
||||||
|
If(rt_packet_read_request,
|
||||||
|
rt_packet.sr_notwrite.eq(1),
|
||||||
|
rt_packet.sr_address.eq(1)
|
||||||
)
|
)
|
||||||
]
|
]
|
||||||
|
|
||||||
fsm = ClockDomainsRenamer("sys_with_rst")(FSM())
|
# output status
|
||||||
self.submodules += fsm
|
o_status_wait = Signal()
|
||||||
|
o_status_underflow = Signal()
|
||||||
status_wait = Signal()
|
o_status_sequence_error = Signal()
|
||||||
status_underflow = Signal()
|
|
||||||
status_sequence_error = Signal()
|
|
||||||
self.comb += [
|
self.comb += [
|
||||||
self.cri.o_status.eq(Cat(
|
self.cri.o_status.eq(Cat(
|
||||||
status_wait, status_underflow, status_sequence_error)),
|
o_status_wait, o_status_underflow, o_status_sequence_error)),
|
||||||
self.csrs.o_wait.status.eq(status_wait)
|
self.csrs.o_wait.status.eq(o_status_wait)
|
||||||
]
|
]
|
||||||
sequence_error_set = Signal()
|
o_sequence_error_set = Signal()
|
||||||
underflow_set = Signal()
|
o_underflow_set = Signal()
|
||||||
self.sync.sys_with_rst += [
|
self.sync.sys_with_rst += [
|
||||||
If(self.cri.cmd == cri.commands["o_underflow_reset"], status_underflow.eq(0)),
|
If(self.cri.cmd == cri.commands["o_underflow_reset"], o_status_underflow.eq(0)),
|
||||||
If(self.cri.cmd == cri.commands["o_sequence_error_reset"], status_sequence_error.eq(0)),
|
If(self.cri.cmd == cri.commands["o_sequence_error_reset"], o_status_sequence_error.eq(0)),
|
||||||
If(underflow_set, status_underflow.eq(1)),
|
If(o_underflow_set, o_status_underflow.eq(1)),
|
||||||
If(sequence_error_set, status_sequence_error.eq(1))
|
If(o_sequence_error_set, o_status_sequence_error.eq(1))
|
||||||
]
|
]
|
||||||
|
|
||||||
signal_fifo_space_timeout = Signal()
|
signal_fifo_space_timeout = Signal()
|
||||||
@ -143,22 +146,49 @@ class RTController(Module):
|
|||||||
cond_underflow = ((self.cri.timestamp[fine_ts_width:]
|
cond_underflow = ((self.cri.timestamp[fine_ts_width:]
|
||||||
- self.csrs.underflow_margin.storage[fine_ts_width:]) < self.counter.value_sys)
|
- self.csrs.underflow_margin.storage[fine_ts_width:]) < self.counter.value_sys)
|
||||||
|
|
||||||
|
# input status
|
||||||
|
i_status_wait_event = Signal()
|
||||||
|
i_status_overflow = Signal()
|
||||||
|
i_status_wait_status = Signal()
|
||||||
|
self.comb += self.cri.i_status.eq(Cat(
|
||||||
|
i_status_wait_event, i_status_overflow, i_status_wait_status))
|
||||||
|
|
||||||
|
load_read_reply = Signal()
|
||||||
|
self.sync.sys_with_rst += [
|
||||||
|
If(load_read_reply,
|
||||||
|
i_status_wait_event.eq(0),
|
||||||
|
i_status_overflow.eq(0),
|
||||||
|
If(rt_packet.read_no_event,
|
||||||
|
If(rt_packet.read_is_overflow,
|
||||||
|
i_status_overflow.eq(1)
|
||||||
|
).Else(
|
||||||
|
i_status_wait_event.eq(1)
|
||||||
|
)
|
||||||
|
),
|
||||||
|
self.cri.i_data.eq(rt_packet.read_data),
|
||||||
|
self.cri.i_timestamp.eq(rt_packet.read_timestamp)
|
||||||
|
)
|
||||||
|
]
|
||||||
|
|
||||||
|
# FSM
|
||||||
|
fsm = ClockDomainsRenamer("sys_with_rst")(FSM())
|
||||||
|
self.submodules += fsm
|
||||||
|
|
||||||
fsm.act("IDLE",
|
fsm.act("IDLE",
|
||||||
If(self.cri.cmd == cri.commands["write"],
|
If(self.cri.cmd == cri.commands["write"],
|
||||||
If(cond_sequence_error,
|
If(cond_sequence_error,
|
||||||
sequence_error_set.eq(1)
|
o_sequence_error_set.eq(1)
|
||||||
).Elif(cond_underflow,
|
).Elif(cond_underflow,
|
||||||
underflow_set.eq(1)
|
o_underflow_set.eq(1)
|
||||||
).Else(
|
).Else(
|
||||||
NextState("WRITE")
|
NextState("WRITE")
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
If(self.csrs.o_get_fifo_space.re,
|
If(self.cri.cmd == cri.commands["read_request"], NextState("READ")),
|
||||||
NextState("GET_FIFO_SPACE")
|
If(self.csrs.o_get_fifo_space.re, NextState("GET_FIFO_SPACE"))
|
||||||
)
|
|
||||||
)
|
)
|
||||||
fsm.act("WRITE",
|
fsm.act("WRITE",
|
||||||
status_wait.eq(1),
|
o_status_wait.eq(1),
|
||||||
rt_packet.sr_stb.eq(1),
|
rt_packet.sr_stb.eq(1),
|
||||||
If(rt_packet.sr_ack,
|
If(rt_packet.sr_ack,
|
||||||
fifo_spaces.we.eq(1),
|
fifo_spaces.we.eq(1),
|
||||||
@ -172,16 +202,16 @@ class RTController(Module):
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
fsm.act("GET_FIFO_SPACE",
|
fsm.act("GET_FIFO_SPACE",
|
||||||
status_wait.eq(1),
|
o_status_wait.eq(1),
|
||||||
|
rt_packet.fifo_space_not_ack.eq(1),
|
||||||
rt_packet_fifo_request.eq(1),
|
rt_packet_fifo_request.eq(1),
|
||||||
rt_packet.sr_stb.eq(1),
|
rt_packet.sr_stb.eq(1),
|
||||||
rt_packet.fifo_space_not_ack.eq(1),
|
|
||||||
If(rt_packet.sr_ack,
|
If(rt_packet.sr_ack,
|
||||||
NextState("GET_FIFO_SPACE_REPLY")
|
NextState("GET_FIFO_SPACE_REPLY")
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
fsm.act("GET_FIFO_SPACE_REPLY",
|
fsm.act("GET_FIFO_SPACE_REPLY",
|
||||||
status_wait.eq(1),
|
o_status_wait.eq(1),
|
||||||
fifo_spaces.dat_w.eq(rt_packet.fifo_space),
|
fifo_spaces.dat_w.eq(rt_packet.fifo_space),
|
||||||
fifo_spaces.we.eq(1),
|
fifo_spaces.we.eq(1),
|
||||||
rt_packet.fifo_space_not_ack.eq(1),
|
rt_packet.fifo_space_not_ack.eq(1),
|
||||||
@ -198,6 +228,21 @@ class RTController(Module):
|
|||||||
NextState("GET_FIFO_SPACE")
|
NextState("GET_FIFO_SPACE")
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
fsm.act("READ",
|
||||||
|
i_status_wait_status.eq(1),
|
||||||
|
rt_packet_read_request.eq(1),
|
||||||
|
rt_packet.sr_stb.eq(1),
|
||||||
|
If(rt_packet.sr_ack,
|
||||||
|
NextState("GET_READ_REPLY")
|
||||||
|
)
|
||||||
|
)
|
||||||
|
fsm.act("GET_READ_REPLY",
|
||||||
|
i_status_wait_status.eq(1),
|
||||||
|
If(rt_packet.read_not,
|
||||||
|
load_read_reply.eq(1),
|
||||||
|
NextState("IDLE")
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
# channel state access
|
# channel state access
|
||||||
self.comb += [
|
self.comb += [
|
||||||
|
@ -9,81 +9,148 @@ from artiq.gateware.rtio import rtlink
|
|||||||
|
|
||||||
class IOS(Module):
|
class IOS(Module):
|
||||||
def __init__(self, rt_packet, channels, max_fine_ts_width, full_ts_width):
|
def __init__(self, rt_packet, channels, max_fine_ts_width, full_ts_width):
|
||||||
tsc = Signal(full_ts_width - max_fine_ts_width)
|
self.rt_packet = rt_packet
|
||||||
|
self.max_fine_ts_width = max_fine_ts_width
|
||||||
|
|
||||||
|
self.tsc = Signal(full_ts_width - max_fine_ts_width)
|
||||||
self.sync.rtio += \
|
self.sync.rtio += \
|
||||||
If(rt_packet.tsc_load,
|
If(rt_packet.tsc_load,
|
||||||
tsc.eq(rt_packet.tsc_load_value)
|
self.tsc.eq(rt_packet.tsc_load_value)
|
||||||
).Else(
|
).Else(
|
||||||
tsc.eq(tsc + 1)
|
self.tsc.eq(self.tsc + 1)
|
||||||
)
|
)
|
||||||
self.comb += rt_packet.tsc_input.eq(tsc)
|
self.comb += rt_packet.tsc_input.eq(self.tsc)
|
||||||
|
|
||||||
for n, channel in enumerate(channels):
|
for n, channel in enumerate(channels):
|
||||||
interface = channel.interface.o
|
self.add_output(n, channel)
|
||||||
data_width = rtlink.get_data_width(interface)
|
self.add_input(n, channel)
|
||||||
address_width = rtlink.get_address_width(interface)
|
|
||||||
fine_ts_width = rtlink.get_fine_ts_width(interface)
|
|
||||||
assert fine_ts_width <= max_fine_ts_width
|
|
||||||
|
|
||||||
# FIFO
|
def add_output(self, n, channel):
|
||||||
ev_layout = []
|
rt_packet = self.rt_packet
|
||||||
if data_width:
|
max_fine_ts_width = self.max_fine_ts_width
|
||||||
ev_layout.append(("data", data_width))
|
|
||||||
if address_width:
|
|
||||||
ev_layout.append(("address", address_width))
|
|
||||||
ev_layout.append(("timestamp", len(tsc) + fine_ts_width))
|
|
||||||
|
|
||||||
fifo = ClockDomainsRenamer("rio")(
|
interface = channel.interface.o
|
||||||
SyncFIFOBuffered(layout_len(ev_layout), channel.ofifo_depth))
|
data_width = rtlink.get_data_width(interface)
|
||||||
self.submodules += fifo
|
address_width = rtlink.get_address_width(interface)
|
||||||
fifo_in = Record(ev_layout)
|
fine_ts_width = rtlink.get_fine_ts_width(interface)
|
||||||
fifo_out = Record(ev_layout)
|
assert fine_ts_width <= max_fine_ts_width
|
||||||
self.comb += [
|
|
||||||
fifo.din.eq(fifo_in.raw_bits()),
|
|
||||||
fifo_out.raw_bits().eq(fifo.dout)
|
|
||||||
]
|
|
||||||
|
|
||||||
# FIFO level
|
# FIFO
|
||||||
self.sync.rio += \
|
ev_layout = []
|
||||||
If(rt_packet.fifo_space_update &
|
if data_width:
|
||||||
(rt_packet.fifo_space_channel == n),
|
ev_layout.append(("data", data_width))
|
||||||
rt_packet.fifo_space.eq(channel.ofifo_depth - fifo.level))
|
if address_width:
|
||||||
|
ev_layout.append(("address", address_width))
|
||||||
|
ev_layout.append(("timestamp", len(self.tsc) + fine_ts_width))
|
||||||
|
|
||||||
# FIFO write
|
fifo = ClockDomainsRenamer("rio")(
|
||||||
self.comb += fifo.we.eq(rt_packet.write_stb
|
SyncFIFOBuffered(layout_len(ev_layout), channel.ofifo_depth))
|
||||||
& (rt_packet.write_channel == n))
|
self.submodules += fifo
|
||||||
self.sync.rio += [
|
fifo_in = Record(ev_layout)
|
||||||
If(rt_packet.write_overflow_ack,
|
fifo_out = Record(ev_layout)
|
||||||
rt_packet.write_overflow.eq(0)),
|
self.comb += [
|
||||||
If(rt_packet.write_underflow_ack,
|
fifo.din.eq(fifo_in.raw_bits()),
|
||||||
rt_packet.write_underflow.eq(0)),
|
fifo_out.raw_bits().eq(fifo.dout)
|
||||||
If(fifo.we,
|
]
|
||||||
If(~fifo.writable, rt_packet.write_overflow.eq(1)),
|
|
||||||
If(rt_packet.write_timestamp[max_fine_ts_width:] < (tsc + 4),
|
# FIFO level
|
||||||
rt_packet.write_underflow.eq(1)
|
self.sync.rio += \
|
||||||
)
|
If(rt_packet.fifo_space_update &
|
||||||
|
(rt_packet.fifo_space_channel == n),
|
||||||
|
rt_packet.fifo_space.eq(channel.ofifo_depth - fifo.level))
|
||||||
|
|
||||||
|
# FIFO write
|
||||||
|
self.comb += fifo.we.eq(rt_packet.write_stb
|
||||||
|
& (rt_packet.write_channel == n))
|
||||||
|
self.sync.rio += [
|
||||||
|
If(rt_packet.write_overflow_ack,
|
||||||
|
rt_packet.write_overflow.eq(0)),
|
||||||
|
If(rt_packet.write_underflow_ack,
|
||||||
|
rt_packet.write_underflow.eq(0)),
|
||||||
|
If(fifo.we,
|
||||||
|
If(~fifo.writable, rt_packet.write_overflow.eq(1)),
|
||||||
|
If(rt_packet.write_timestamp[max_fine_ts_width:] < (self.tsc + 4),
|
||||||
|
rt_packet.write_underflow.eq(1)
|
||||||
)
|
)
|
||||||
]
|
)
|
||||||
if data_width:
|
]
|
||||||
self.comb += fifo_in.data.eq(rt_packet.write_data)
|
if data_width:
|
||||||
if address_width:
|
self.comb += fifo_in.data.eq(rt_packet.write_data)
|
||||||
self.comb += fifo_in.address.eq(rt_packet.write_address)
|
if address_width:
|
||||||
self.comb += fifo_in.timestamp.eq(
|
self.comb += fifo_in.address.eq(rt_packet.write_address)
|
||||||
rt_packet.write_timestamp[max_fine_ts_width-fine_ts_width:])
|
self.comb += fifo_in.timestamp.eq(
|
||||||
|
rt_packet.write_timestamp[max_fine_ts_width-fine_ts_width:])
|
||||||
|
|
||||||
# FIFO read
|
# FIFO read
|
||||||
self.sync.rio += [
|
self.sync.rio += [
|
||||||
fifo.re.eq(0),
|
fifo.re.eq(0),
|
||||||
interface.stb.eq(0),
|
interface.stb.eq(0),
|
||||||
If(fifo.readable &
|
If(fifo.readable &
|
||||||
(fifo_out.timestamp[fine_ts_width:] == tsc),
|
(fifo_out.timestamp[fine_ts_width:] == self.tsc),
|
||||||
fifo.re.eq(1),
|
fifo.re.eq(1),
|
||||||
interface.stb.eq(1)
|
interface.stb.eq(1)
|
||||||
)
|
)
|
||||||
]
|
]
|
||||||
if data_width:
|
if data_width:
|
||||||
self.sync.rio += interface.data.eq(fifo_out.data)
|
self.sync.rio += interface.data.eq(fifo_out.data)
|
||||||
if address_width:
|
if address_width:
|
||||||
self.sync.rio += interface.address.eq(fifo_out.address)
|
self.sync.rio += interface.address.eq(fifo_out.address)
|
||||||
|
if fine_ts_width:
|
||||||
|
self.sync.rio += interface.fine_ts.eq(fifo_out.timestamp[:fine_ts_width])
|
||||||
|
|
||||||
|
def add_input(self, n, channel):
|
||||||
|
interface = channel.interface.i
|
||||||
|
if interface is None:
|
||||||
|
return
|
||||||
|
data_width = rtlink.get_data_width(interface)
|
||||||
|
fine_ts_width = rtlink.get_fine_ts_width(interface)
|
||||||
|
|
||||||
|
selected = Signal()
|
||||||
|
self.comb += selected.eq(rt_packet.read_channel == n)
|
||||||
|
|
||||||
|
# FIFO
|
||||||
|
ev_layout = []
|
||||||
|
if data_width:
|
||||||
|
ev_layout.append(("data", data_width))
|
||||||
|
if interface.timestamped:
|
||||||
|
ev_layout.append(("timestamp", len(self.tsc) + fine_ts_width))
|
||||||
|
|
||||||
|
fifo = ClockDomainsRenamer("rio")(
|
||||||
|
SyncFIFOBuffered(layout_len(ev_layout), channel.ififo_depth))
|
||||||
|
self.submodules += fifo
|
||||||
|
fifo_in = Record(ev_layout)
|
||||||
|
fifo_out = Record(ev_layout)
|
||||||
|
self.comb += [
|
||||||
|
fifo.din.eq(fifo_in.raw_bits()),
|
||||||
|
fifo_out.raw_bits().eq(fifo.dout)
|
||||||
|
]
|
||||||
|
|
||||||
|
# FIFO write
|
||||||
|
if data_width:
|
||||||
|
self.comb += fifo_in.data.eq(interface.data)
|
||||||
|
if interface.timestamped:
|
||||||
if fine_ts_width:
|
if fine_ts_width:
|
||||||
self.sync.rio += interface.fine_ts.eq(fifo_out.timestamp[:fine_ts_width])
|
full_ts = Cat(interface.fine_ts, self.tsc)
|
||||||
|
else:
|
||||||
|
full_ts = self.tsc
|
||||||
|
self.comb += fifo_in.timestamp.eq(full_ts)
|
||||||
|
self.comb += fifo.we.eq(interface.stb)
|
||||||
|
|
||||||
|
overflow = Signal()
|
||||||
|
self.comb += If(selected, rt_packet.read_overflow.eq(overflow))
|
||||||
|
self.sync.rio += [
|
||||||
|
If(selected & rt_packet.read_overflow_ack, overflow.eq(0)),
|
||||||
|
If(fifo.we & ~fifo.writable, overflow.eq(1))
|
||||||
|
]
|
||||||
|
|
||||||
|
# FIFO read
|
||||||
|
if data_width:
|
||||||
|
self.comb += If(selected, rt_packet.read_data.eq(fifo_out.data))
|
||||||
|
if interface.timestamped:
|
||||||
|
self.comb += If(selected, rt_packet.read_timestamp.eq(fifo_out.timestamp))
|
||||||
|
self.comb += [
|
||||||
|
If(selected,
|
||||||
|
rt_packet.read_readable.eq(fifo.readable),
|
||||||
|
fifo.re.eq(rt_packet.read_consume)
|
||||||
|
)
|
||||||
|
]
|
||||||
|
@ -43,7 +43,7 @@ class _CrossDomainNotification(Module):
|
|||||||
def __init__(self, domain,
|
def __init__(self, domain,
|
||||||
emi_stb, emi_data,
|
emi_stb, emi_data,
|
||||||
rec_stb, rec_ack, rec_data):
|
rec_stb, rec_ack, rec_data):
|
||||||
emi_data_r = Signal.like(emi_data)
|
emi_data_r = Signal(len(emi_data))
|
||||||
emi_data_r.attr.add("no_retiming")
|
emi_data_r.attr.add("no_retiming")
|
||||||
dsync = getattr(self.sync, domain)
|
dsync = getattr(self.sync, domain)
|
||||||
dsync += If(emi_stb, emi_data_r.eq(emi_data))
|
dsync += If(emi_stb, emi_data_r.eq(emi_data))
|
||||||
@ -68,7 +68,6 @@ class RTPacketMaster(Module):
|
|||||||
#
|
#
|
||||||
# notwrite=1 address=0 FIFO space request <channel>
|
# notwrite=1 address=0 FIFO space request <channel>
|
||||||
# notwrite=1 address=1 read request <channel, timestamp>
|
# notwrite=1 address=1 read request <channel, timestamp>
|
||||||
# notwrite=1 address=2 read consume
|
|
||||||
#
|
#
|
||||||
# optimized for write throughput
|
# optimized for write throughput
|
||||||
# requests are performed on the DRTIO link preserving their order of issue
|
# requests are performed on the DRTIO link preserving their order of issue
|
||||||
@ -87,6 +86,18 @@ class RTPacketMaster(Module):
|
|||||||
self.fifo_space_not_ack = Signal()
|
self.fifo_space_not_ack = Signal()
|
||||||
self.fifo_space = Signal(16)
|
self.fifo_space = Signal(16)
|
||||||
|
|
||||||
|
# read reply interface
|
||||||
|
self.read_not = Signal()
|
||||||
|
self.read_not_ack = Signal()
|
||||||
|
# no_event is_overflow
|
||||||
|
# 0 X event
|
||||||
|
# 1 0 timeout
|
||||||
|
# 1 1 overflow
|
||||||
|
self.read_no_event = Signal()
|
||||||
|
self.read_is_overflow = Signal()
|
||||||
|
self.read_data = Signal(32)
|
||||||
|
self.read_timestamp = Signal(64)
|
||||||
|
|
||||||
# echo interface
|
# echo interface
|
||||||
self.echo_stb = Signal()
|
self.echo_stb = Signal()
|
||||||
self.echo_ack = Signal()
|
self.echo_ack = Signal()
|
||||||
@ -230,6 +241,24 @@ class RTPacketMaster(Module):
|
|||||||
error_not, error_code,
|
error_not, error_code,
|
||||||
self.error_not, self.error_not_ack, self.error_code)
|
self.error_not, self.error_not_ack, self.error_code)
|
||||||
|
|
||||||
|
read_not = Signal()
|
||||||
|
read_no_event = Signal()
|
||||||
|
read_is_overflow = Signal()
|
||||||
|
read_data = Signal(32)
|
||||||
|
read_timestamp = Signal(64)
|
||||||
|
self.submodules += _CrossDomainNotification("rtio_rx",
|
||||||
|
read_not,
|
||||||
|
Cat(read_no_event, read_is_overflow, read_data, read_timestamp),
|
||||||
|
|
||||||
|
self.read_not, self.read_not_ack,
|
||||||
|
Cat(self.read_no_event, self.read_is_overflow,
|
||||||
|
self.read_data, self.read_timestamp))
|
||||||
|
self.comb += [
|
||||||
|
read_is_overflow.eq(rx_dp.packet_as["read_reply_noevent"].overflow),
|
||||||
|
read_data.eq(rx_dp.packet_as["read_reply"].data),
|
||||||
|
read_timestamp.eq(rx_dp.packet_as["read_reply"].timestamp)
|
||||||
|
]
|
||||||
|
|
||||||
# TX FSM
|
# TX 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
|
||||||
@ -243,8 +272,10 @@ class RTPacketMaster(Module):
|
|||||||
tx_fsm.act("IDLE",
|
tx_fsm.act("IDLE",
|
||||||
If(sr_buf_readable,
|
If(sr_buf_readable,
|
||||||
If(sr_notwrite,
|
If(sr_notwrite,
|
||||||
# TODO: sr_address
|
Case(sr_address[0], {
|
||||||
NextState("FIFO_SPACE")
|
0: NextState("FIFO_SPACE"),
|
||||||
|
1: NextState("READ")
|
||||||
|
}),
|
||||||
).Else(
|
).Else(
|
||||||
NextState("WRITE")
|
NextState("WRITE")
|
||||||
)
|
)
|
||||||
@ -291,6 +322,13 @@ class RTPacketMaster(Module):
|
|||||||
NextState("IDLE")
|
NextState("IDLE")
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
tx_fsm.act("READ",
|
||||||
|
tx_dp.send("read_request", channel=sr_channel, timeout=sr_timestamp),
|
||||||
|
If(tx_dp.packet_last,
|
||||||
|
sr_buf_re.eq(1),
|
||||||
|
NextState("IDLE")
|
||||||
|
)
|
||||||
|
)
|
||||||
tx_fsm.act("ECHO",
|
tx_fsm.act("ECHO",
|
||||||
tx_dp.send("echo_request"),
|
tx_dp.send("echo_request"),
|
||||||
If(tx_dp.packet_last,
|
If(tx_dp.packet_last,
|
||||||
@ -332,6 +370,8 @@ class RTPacketMaster(Module):
|
|||||||
rx_plm.types["error"]: NextState("ERROR"),
|
rx_plm.types["error"]: NextState("ERROR"),
|
||||||
rx_plm.types["echo_reply"]: echo_received_now.eq(1),
|
rx_plm.types["echo_reply"]: echo_received_now.eq(1),
|
||||||
rx_plm.types["fifo_space_reply"]: NextState("FIFO_SPACE"),
|
rx_plm.types["fifo_space_reply"]: NextState("FIFO_SPACE"),
|
||||||
|
rx_plm.types["read_reply"]: NextState("READ_REPLY"),
|
||||||
|
rx_plm.types["read_reply_noevent"]: NextState("READ_REPLY_NOEVENT"),
|
||||||
"default": [
|
"default": [
|
||||||
error_not.eq(1),
|
error_not.eq(1),
|
||||||
error_code.eq(error_codes["unknown_type_local"])
|
error_code.eq(error_codes["unknown_type_local"])
|
||||||
@ -356,6 +396,16 @@ class RTPacketMaster(Module):
|
|||||||
fifo_space.eq(rx_dp.packet_as["fifo_space_reply"].space),
|
fifo_space.eq(rx_dp.packet_as["fifo_space_reply"].space),
|
||||||
NextState("INPUT")
|
NextState("INPUT")
|
||||||
)
|
)
|
||||||
|
rx_fsm.act("READ_REPLY",
|
||||||
|
read_not.eq(1),
|
||||||
|
read_no_event.eq(0),
|
||||||
|
NextState("INPUT")
|
||||||
|
)
|
||||||
|
rx_fsm.act("READ_REPLY_NOEVENT",
|
||||||
|
read_not.eq(1),
|
||||||
|
read_no_event.eq(1),
|
||||||
|
NextState("INPUT")
|
||||||
|
)
|
||||||
|
|
||||||
# packet counters
|
# packet counters
|
||||||
tx_frame_r = Signal()
|
tx_frame_r = Signal()
|
||||||
|
@ -32,9 +32,10 @@ class RTPacketSatellite(Module):
|
|||||||
self.read_channel = Signal(16)
|
self.read_channel = Signal(16)
|
||||||
self.read_readable = Signal()
|
self.read_readable = Signal()
|
||||||
self.read_consume = Signal()
|
self.read_consume = Signal()
|
||||||
self.read_timestamp = Signal(64)
|
|
||||||
self.read_data = Signal(32)
|
self.read_data = Signal(32)
|
||||||
|
self.read_timestamp = Signal(64)
|
||||||
self.read_overflow = Signal()
|
self.read_overflow = Signal()
|
||||||
|
self.read_overflow_ack = Signal()
|
||||||
|
|
||||||
# # #
|
# # #
|
||||||
|
|
||||||
@ -144,7 +145,6 @@ class RTPacketSatellite(Module):
|
|||||||
rx_plm.types["write"]: NextState("WRITE"),
|
rx_plm.types["write"]: NextState("WRITE"),
|
||||||
rx_plm.types["fifo_space_request"]: NextState("FIFO_SPACE"),
|
rx_plm.types["fifo_space_request"]: NextState("FIFO_SPACE"),
|
||||||
rx_plm.types["read_request"]: NextState("READ_REQUEST"),
|
rx_plm.types["read_request"]: NextState("READ_REQUEST"),
|
||||||
rx_plm.types["read_consume"]: NextState("READ_CONSUME"),
|
|
||||||
"default": [
|
"default": [
|
||||||
err_set.eq(1),
|
err_set.eq(1),
|
||||||
NextValue(err_code, error_codes["unknown_type_remote"])]
|
NextValue(err_code, error_codes["unknown_type_remote"])]
|
||||||
@ -194,10 +194,6 @@ class RTPacketSatellite(Module):
|
|||||||
load_read_request.eq(1),
|
load_read_request.eq(1),
|
||||||
NextState("INPUT")
|
NextState("INPUT")
|
||||||
)
|
)
|
||||||
rx_fsm.act("READ_CONSUME",
|
|
||||||
self.read_consume.eq(1),
|
|
||||||
NextState("INPUT")
|
|
||||||
)
|
|
||||||
|
|
||||||
# TX FSM
|
# TX FSM
|
||||||
tx_fsm = FSM(reset_state="IDLE")
|
tx_fsm = FSM(reset_state="IDLE")
|
||||||
@ -245,14 +241,20 @@ class RTPacketSatellite(Module):
|
|||||||
tx_fsm.act("READ_OVERFLOW",
|
tx_fsm.act("READ_OVERFLOW",
|
||||||
tx_dp.send("read_reply_noevent", overflow=1),
|
tx_dp.send("read_reply_noevent", overflow=1),
|
||||||
clear_read_request.eq(1),
|
clear_read_request.eq(1),
|
||||||
If(tx_dp.packet_last, NextState("IDLE"))
|
If(tx_dp.packet_last,
|
||||||
|
self.read_overflow_ack.eq(1),
|
||||||
|
NextState("IDLE")
|
||||||
|
)
|
||||||
)
|
)
|
||||||
tx_fsm.act("READ",
|
tx_fsm.act("READ",
|
||||||
tx_dp.send("read_reply",
|
tx_dp.send("read_reply",
|
||||||
timestamp=self.read_timestamp,
|
timestamp=self.read_timestamp,
|
||||||
data=self.read_data),
|
data=self.read_data),
|
||||||
clear_read_request.eq(1),
|
clear_read_request.eq(1),
|
||||||
If(tx_dp.packet_last, NextState("IDLE"))
|
If(tx_dp.packet_last,
|
||||||
|
self.read_consume.eq(1),
|
||||||
|
NextState("IDLE")
|
||||||
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
tx_fsm.act("ERROR",
|
tx_fsm.act("ERROR",
|
||||||
|
@ -57,7 +57,6 @@ def get_m2s_layouts(alignment):
|
|||||||
plm.add_type("fifo_space_request", ("channel", 16))
|
plm.add_type("fifo_space_request", ("channel", 16))
|
||||||
|
|
||||||
plm.add_type("read_request", ("channel", 16), ("timeout", 64))
|
plm.add_type("read_request", ("channel", 16), ("timeout", 64))
|
||||||
plm.add_type("read_consume") # channel is specified in the last read_request packet
|
|
||||||
|
|
||||||
return plm
|
return plm
|
||||||
|
|
||||||
|
@ -42,7 +42,7 @@ layout = [
|
|||||||
("i_data", 32, DIR_S_TO_M),
|
("i_data", 32, DIR_S_TO_M),
|
||||||
("i_timestamp", 64, DIR_S_TO_M),
|
("i_timestamp", 64, DIR_S_TO_M),
|
||||||
# i_status bits:
|
# i_status bits:
|
||||||
# <0:wait for event> <1:overflow> <2:wait for status>
|
# <0:wait for event (command timeout)> <1:overflow> <2:wait for status>
|
||||||
("i_status", 3, DIR_S_TO_M),
|
("i_status", 3, DIR_S_TO_M),
|
||||||
|
|
||||||
("counter", 64, DIR_S_TO_M)
|
("counter", 64, DIR_S_TO_M)
|
||||||
|
Loading…
Reference in New Issue
Block a user