rtio: judicious spray with reset_less=True

Hoping to reduce rst routing difficulty and easier RTIO timing closure.
This commit is contained in:
Robert Jördens 2018-03-07 15:11:32 +01:00 committed by Robert Jordens
parent b0282fa855
commit 3a6566f949
8 changed files with 32 additions and 24 deletions

View File

@ -9,12 +9,12 @@ __all__ = ["GrayCodeTransfer", "BlindTransfer"]
class GrayCodeTransfer(Module): class GrayCodeTransfer(Module):
def __init__(self, width): def __init__(self, width):
self.i = Signal(width) # in rtio domain 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 # 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:]) self.sync.rtio += value_gray_rtio.eq(self.i ^ self.i[1:])
# transfer to system clock domain # transfer to system clock domain
value_gray_sys = Signal(width) value_gray_sys = Signal(width)
@ -34,7 +34,7 @@ class BlindTransfer(Module):
self.o = Signal() self.o = Signal()
if data_width: if data_width:
self.data_i = Signal(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: 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)) isync += If(ps.i, bxfer_data.eq(self.data_i))
bxfer_data.attr.add("no_retiming") bxfer_data.attr.add("no_retiming")
self.specials += MultiReg(bxfer_data, self.data_o, self.specials += MultiReg(bxfer_data, self.data_o,

View File

@ -47,8 +47,8 @@ layout = [
class Interface(Record): class Interface(Record):
def __init__(self): def __init__(self, **kwargs):
Record.__init__(self, layout) Record.__init__(self, layout, **kwargs)
class KernelInitiator(Module, AutoCSR): 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:]) self.sync += selected.eq(self.master.chan_sel[16:])
# master -> slave # master -> slave

View File

@ -119,8 +119,10 @@ class InputCollector(Module):
i_status_raw = Signal(2) i_status_raw = Signal(2)
self.comb += i_status_raw.eq(Array(i_statuses)[sel]) 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() input_pending = Signal()
self.cri.i_data.reset_less = True
self.cri.i_timestamp.reset_less = True
sync_cri += [ sync_cri += [
i_ack.eq(0), i_ack.eq(0),
If(i_ack, If(i_ack,

View File

@ -9,11 +9,11 @@ class OInterface:
self.busy = Signal() self.busy = Signal()
if data_width: if data_width:
self.data = Signal(data_width) self.data = Signal(data_width, reset_less=True)
if address_width: if address_width:
self.address = Signal(address_width) self.address = Signal(address_width, reset_less=True)
if fine_ts_width: 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 self.enable_replace = enable_replace
@ -36,9 +36,9 @@ class IInterface:
self.stb = Signal() self.stb = Signal()
if data_width: if data_width:
self.data = Signal(data_width) self.data = Signal(data_width, reset_less=True)
if fine_ts_width: 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) assert(not fine_ts_width or timestamped)
self.timestamped = timestamped self.timestamped = timestamped

View File

@ -10,7 +10,8 @@ class Gates(Module):
def __init__(self, lane_count, seqn_width, layout_fifo_payload, layout_output_network_payload): 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)) self.input = [Record(layouts.fifo_egress(seqn_width, layout_fifo_payload))
for _ in range(lane_count)] 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)] for _ in range(lane_count)]
if hasattr(self.output[0].payload, "fine_ts"): 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) 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) self.sync += output.valid.eq(input.re & input.readable)

View File

@ -23,7 +23,7 @@ class LaneDistributor(Module):
interface = cri.Interface() interface = cri.Interface()
self.cri = interface self.cri = interface
self.sequence_error = Signal() 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 # 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 # 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 # 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 # when timestamp and channel arrive in cycle #1, prepare computations
coarse_timestamp = Signal(us_timestamp_width) coarse_timestamp = Signal(us_timestamp_width)
self.comb += coarse_timestamp.eq(self.cri.timestamp[glbl_fine_ts_width:]) self.comb += coarse_timestamp.eq(self.cri.timestamp[glbl_fine_ts_width:])
min_minus_timestamp = Signal((us_timestamp_width + 1, True)) min_minus_timestamp = Signal((us_timestamp_width + 1, True),
laneAmin_minus_timestamp = Signal((us_timestamp_width + 1, True)) reset_less=True)
laneBmin_minus_timestamp = Signal((us_timestamp_width + 1, True)) laneAmin_minus_timestamp = Signal.like(min_minus_timestamp)
last_minus_timestamp = Signal((us_timestamp_width + 1, True)) laneBmin_minus_timestamp = Signal.like(min_minus_timestamp)
last_minus_timestamp = Signal.like(min_minus_timestamp)
current_lane_plus_one = Signal(max=lane_count) current_lane_plus_one = Signal(max=lane_count)
self.comb += current_lane_plus_one.eq(current_lane + 1) self.comb += current_lane_plus_one.eq(current_lane + 1)
self.sync += [ self.sync += [

View File

@ -13,9 +13,9 @@ __all__ = ["OutputDriver"]
class OutputDriver(Module): class OutputDriver(Module):
def __init__(self, channels, glbl_fine_ts_width, lane_count, seqn_width): def __init__(self, channels, glbl_fine_ts_width, lane_count, seqn_width):
self.collision = Signal() 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 = Signal()
self.busy_channel = Signal(max=len(channels)) self.busy_channel = Signal(max=len(channels), reset_less=True)
# output network # output network
layout_on_payload = layouts.output_network_payload(channels, glbl_fine_ts_width) layout_on_payload = layouts.output_network_payload(channels, glbl_fine_ts_width)
@ -29,9 +29,11 @@ class OutputDriver(Module):
("collision", 1), ("collision", 1),
("payload", layout_on_payload) ("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] en_replaces = [channel.interface.o.enable_replace for channel in channels]
for lane_data, on_output in zip(lane_datas, output_network.output): 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() replace_occured_r = Signal()
nondata_replace_occured_r = Signal() nondata_replace_occured_r = Signal()
self.sync += [ self.sync += [
@ -96,7 +98,7 @@ class OutputDriver(Module):
] ]
for lane_data in lane_datas: for lane_data in lane_datas:
stb_r = Signal() stb_r = Signal()
channel_r = Signal(max=len(channels)) channel_r = Signal(max=len(channels), reset_less=True)
self.sync += [ self.sync += [
stb_r.eq(lane_data.valid & ~lane_data.collision), stb_r.eq(lane_data.valid & ~lane_data.collision),
channel_r.eq(lane_data.payload.channel), channel_r.eq(lane_data.payload.channel),

View File

@ -56,7 +56,8 @@ class OutputNetwork(Module):
step_input = self.input step_input = self.input
for step in boms_steps_pairs(lane_count): 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 _ in range(lane_count)]
for node1, node2 in step: for node1, node2 in step: