forked from M-Labs/artiq
rtio: judicious spray with reset_less=True
Hoping to reduce rst routing difficulty and easier RTIO timing closure.
This commit is contained in:
parent
b0282fa855
commit
3a6566f949
|
@ -9,12 +9,12 @@ __all__ = ["GrayCodeTransfer", "BlindTransfer"]
|
|||
class GrayCodeTransfer(Module):
|
||||
def __init__(self, width):
|
||||
self.i = Signal(width) # in rtio domain
|
||||
self.o = Signal(width) # in sys domain
|
||||
self.o = Signal(width, reset_less=True) # in sys domain
|
||||
|
||||
# # #
|
||||
|
||||
# convert to Gray code
|
||||
value_gray_rtio = Signal(width)
|
||||
value_gray_rtio = Signal(width, reset_less=True)
|
||||
self.sync.rtio += value_gray_rtio.eq(self.i ^ self.i[1:])
|
||||
# transfer to system clock domain
|
||||
value_gray_sys = Signal(width)
|
||||
|
@ -34,7 +34,7 @@ class BlindTransfer(Module):
|
|||
self.o = Signal()
|
||||
if data_width:
|
||||
self.data_i = Signal(data_width)
|
||||
self.data_o = Signal(data_width)
|
||||
self.data_o = Signal(data_width, reset_less=True)
|
||||
|
||||
# # #
|
||||
|
||||
|
@ -54,7 +54,7 @@ class BlindTransfer(Module):
|
|||
]
|
||||
|
||||
if data_width:
|
||||
bxfer_data = Signal(data_width)
|
||||
bxfer_data = Signal(data_width, reset_less=True)
|
||||
isync += If(ps.i, bxfer_data.eq(self.data_i))
|
||||
bxfer_data.attr.add("no_retiming")
|
||||
self.specials += MultiReg(bxfer_data, self.data_o,
|
||||
|
|
|
@ -47,8 +47,8 @@ layout = [
|
|||
|
||||
|
||||
class Interface(Record):
|
||||
def __init__(self):
|
||||
Record.__init__(self, layout)
|
||||
def __init__(self, **kwargs):
|
||||
Record.__init__(self, layout, **kwargs)
|
||||
|
||||
|
||||
class KernelInitiator(Module, AutoCSR):
|
||||
|
@ -112,7 +112,7 @@ class CRIDecoder(Module):
|
|||
|
||||
# # #
|
||||
|
||||
selected = Signal(8)
|
||||
selected = Signal(8, reset_less=True)
|
||||
self.sync += selected.eq(self.master.chan_sel[16:])
|
||||
|
||||
# master -> slave
|
||||
|
|
|
@ -119,8 +119,10 @@ class InputCollector(Module):
|
|||
|
||||
i_status_raw = Signal(2)
|
||||
self.comb += i_status_raw.eq(Array(i_statuses)[sel])
|
||||
input_timeout = Signal.like(self.cri.timestamp)
|
||||
input_timeout = Signal.like(self.cri.timestamp, reset_less=True)
|
||||
input_pending = Signal()
|
||||
self.cri.i_data.reset_less = True
|
||||
self.cri.i_timestamp.reset_less = True
|
||||
sync_cri += [
|
||||
i_ack.eq(0),
|
||||
If(i_ack,
|
||||
|
|
|
@ -9,11 +9,11 @@ class OInterface:
|
|||
self.busy = Signal()
|
||||
|
||||
if data_width:
|
||||
self.data = Signal(data_width)
|
||||
self.data = Signal(data_width, reset_less=True)
|
||||
if address_width:
|
||||
self.address = Signal(address_width)
|
||||
self.address = Signal(address_width, reset_less=True)
|
||||
if fine_ts_width:
|
||||
self.fine_ts = Signal(fine_ts_width)
|
||||
self.fine_ts = Signal(fine_ts_width, reset_less=True)
|
||||
|
||||
self.enable_replace = enable_replace
|
||||
|
||||
|
@ -36,9 +36,9 @@ class IInterface:
|
|||
self.stb = Signal()
|
||||
|
||||
if data_width:
|
||||
self.data = Signal(data_width)
|
||||
self.data = Signal(data_width, reset_less=True)
|
||||
if fine_ts_width:
|
||||
self.fine_ts = Signal(fine_ts_width)
|
||||
self.fine_ts = Signal(fine_ts_width, reset_less=True)
|
||||
|
||||
assert(not fine_ts_width or timestamped)
|
||||
self.timestamped = timestamped
|
||||
|
|
|
@ -10,7 +10,8 @@ class Gates(Module):
|
|||
def __init__(self, lane_count, seqn_width, layout_fifo_payload, layout_output_network_payload):
|
||||
self.input = [Record(layouts.fifo_egress(seqn_width, layout_fifo_payload))
|
||||
for _ in range(lane_count)]
|
||||
self.output = [Record(layouts.output_network_node(seqn_width, layout_output_network_payload))
|
||||
self.output = [Record(layouts.output_network_node(seqn_width, layout_output_network_payload),
|
||||
reset_less=True)
|
||||
for _ in range(lane_count)]
|
||||
|
||||
if hasattr(self.output[0].payload, "fine_ts"):
|
||||
|
@ -35,4 +36,5 @@ class Gates(Module):
|
|||
]
|
||||
|
||||
self.comb += input.re.eq(input.payload.timestamp[glbl_fine_ts_width:] == self.coarse_timestamp)
|
||||
output.valid.reset_less = False
|
||||
self.sync += output.valid.eq(input.re & input.readable)
|
||||
|
|
|
@ -23,7 +23,7 @@ class LaneDistributor(Module):
|
|||
interface = cri.Interface()
|
||||
self.cri = interface
|
||||
self.sequence_error = Signal()
|
||||
self.sequence_error_channel = Signal(16)
|
||||
self.sequence_error_channel = Signal(16, reset_less=True)
|
||||
# The minimum timestamp that an event must have to avoid triggering
|
||||
# an underflow, at the time when the CRI write happens, and to a channel
|
||||
# with zero latency compensation. This is synchronous to the system clock
|
||||
|
@ -75,10 +75,11 @@ class LaneDistributor(Module):
|
|||
# when timestamp and channel arrive in cycle #1, prepare computations
|
||||
coarse_timestamp = Signal(us_timestamp_width)
|
||||
self.comb += coarse_timestamp.eq(self.cri.timestamp[glbl_fine_ts_width:])
|
||||
min_minus_timestamp = Signal((us_timestamp_width + 1, True))
|
||||
laneAmin_minus_timestamp = Signal((us_timestamp_width + 1, True))
|
||||
laneBmin_minus_timestamp = Signal((us_timestamp_width + 1, True))
|
||||
last_minus_timestamp = Signal((us_timestamp_width + 1, True))
|
||||
min_minus_timestamp = Signal((us_timestamp_width + 1, True),
|
||||
reset_less=True)
|
||||
laneAmin_minus_timestamp = Signal.like(min_minus_timestamp)
|
||||
laneBmin_minus_timestamp = Signal.like(min_minus_timestamp)
|
||||
last_minus_timestamp = Signal.like(min_minus_timestamp)
|
||||
current_lane_plus_one = Signal(max=lane_count)
|
||||
self.comb += current_lane_plus_one.eq(current_lane + 1)
|
||||
self.sync += [
|
||||
|
|
|
@ -13,9 +13,9 @@ __all__ = ["OutputDriver"]
|
|||
class OutputDriver(Module):
|
||||
def __init__(self, channels, glbl_fine_ts_width, lane_count, seqn_width):
|
||||
self.collision = Signal()
|
||||
self.collision_channel = Signal(max=len(channels))
|
||||
self.collision_channel = Signal(max=len(channels), reset_less=True)
|
||||
self.busy = Signal()
|
||||
self.busy_channel = Signal(max=len(channels))
|
||||
self.busy_channel = Signal(max=len(channels), reset_less=True)
|
||||
|
||||
# output network
|
||||
layout_on_payload = layouts.output_network_payload(channels, glbl_fine_ts_width)
|
||||
|
@ -29,9 +29,11 @@ class OutputDriver(Module):
|
|||
("collision", 1),
|
||||
("payload", layout_on_payload)
|
||||
]
|
||||
lane_datas = [Record(layout_lane_data) for _ in range(lane_count)]
|
||||
lane_datas = [Record(layout_lane_data, reset_less=True) for _ in range(lane_count)]
|
||||
en_replaces = [channel.interface.o.enable_replace for channel in channels]
|
||||
for lane_data, on_output in zip(lane_datas, output_network.output):
|
||||
lane_data.valid.reset_less = False
|
||||
lane_data.collision.reset_less = False
|
||||
replace_occured_r = Signal()
|
||||
nondata_replace_occured_r = Signal()
|
||||
self.sync += [
|
||||
|
@ -96,7 +98,7 @@ class OutputDriver(Module):
|
|||
]
|
||||
for lane_data in lane_datas:
|
||||
stb_r = Signal()
|
||||
channel_r = Signal(max=len(channels))
|
||||
channel_r = Signal(max=len(channels), reset_less=True)
|
||||
self.sync += [
|
||||
stb_r.eq(lane_data.valid & ~lane_data.collision),
|
||||
channel_r.eq(lane_data.payload.channel),
|
||||
|
|
|
@ -56,7 +56,8 @@ class OutputNetwork(Module):
|
|||
|
||||
step_input = self.input
|
||||
for step in boms_steps_pairs(lane_count):
|
||||
step_output = [Record(layouts.output_network_node(seqn_width, layout_payload))
|
||||
step_output = [Record(layouts.output_network_node(seqn_width, layout_payload),
|
||||
reset_less=True)
|
||||
for _ in range(lane_count)]
|
||||
|
||||
for node1, node2 in step:
|
||||
|
|
Loading…
Reference in New Issue