rtio/sed: trigger collision error on non-data replace

This commit is contained in:
Sebastien Bourdeauducq 2017-09-16 17:01:23 +08:00
parent 770ce2658f
commit e2c1d4f3d5
4 changed files with 16 additions and 2 deletions

View File

@ -29,7 +29,10 @@ class Gates(Module):
else: else:
self.sync += getattr(output.payload, field).eq(getattr(input.payload, field)) self.sync += getattr(output.payload, field).eq(getattr(input.payload, field))
self.sync += output.seqn.eq(input.seqn) self.sync += output.seqn.eq(input.seqn)
self.comb += output.replace_occured.eq(0) self.comb += [
output.replace_occured.eq(0),
output.nondata_replace_occured.eq(0)
]
self.comb += input.re.eq(input.payload.timestamp[fine_ts_width:] == self.coarse_timestamp) self.comb += input.re.eq(input.payload.timestamp[fine_ts_width:] == self.coarse_timestamp)
self.sync += output.valid.eq(input.re & input.readable) self.sync += output.valid.eq(input.re & input.readable)

View File

@ -69,5 +69,6 @@ def output_network_node(seqn_width, layout_payload):
("valid", 1), ("valid", 1),
("seqn", seqn_width), ("seqn", seqn_width),
("replace_occured", 1), ("replace_occured", 1),
("nondata_replace_occured", 1),
("payload", layout_payload) ("payload", layout_payload)
] ]

View File

@ -33,10 +33,12 @@ class OutputDriver(Module):
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):
replace_occured_r = Signal() replace_occured_r = Signal()
nondata_replace_occured_r = Signal()
self.sync += [ self.sync += [
lane_data.valid.eq(on_output.valid), lane_data.valid.eq(on_output.valid),
lane_data.payload.eq(on_output.payload), lane_data.payload.eq(on_output.payload),
replace_occured_r.eq(on_output.replace_occured), replace_occured_r.eq(on_output.replace_occured),
nondata_replace_occured_r.eq(on_output.nondata_replace_occured)
] ]
en_replaces_rom = Memory(1, len(en_replaces), init=en_replaces) en_replaces_rom = Memory(1, len(en_replaces), init=en_replaces)
@ -44,7 +46,7 @@ class OutputDriver(Module):
self.specials += en_replaces_rom, en_replaces_rom_port self.specials += en_replaces_rom, en_replaces_rom_port
self.comb += [ self.comb += [
en_replaces_rom_port.adr.eq(on_output.payload.channel), en_replaces_rom_port.adr.eq(on_output.payload.channel),
lane_data.collision.eq(replace_occured_r & ~en_replaces_rom_port.dat_r) lane_data.collision.eq(replace_occured_r & (~en_replaces_rom_port.dat_r | nondata_replace_occured_r))
] ]
self.sync += [ self.sync += [

View File

@ -60,6 +60,13 @@ class OutputNetwork(Module):
for _ in range(lane_count)] for _ in range(lane_count)]
for node1, node2 in step: for node1, node2 in step:
nondata_difference = Signal()
for field, _ in layout_payload:
if field != "data":
f1 = getattr(step_input[node1].payload, field)
f2 = getattr(step_input[node2].payload, field)
self.comb += If(f1 != f2, nondata_difference.eq(1))
k1 = Cat(step_input[node1].payload.channel, ~step_input[node1].valid) k1 = Cat(step_input[node1].payload.channel, ~step_input[node1].valid)
k2 = Cat(step_input[node2].payload.channel, ~step_input[node2].valid) k2 = Cat(step_input[node2].payload.channel, ~step_input[node2].valid)
self.sync += [ self.sync += [
@ -72,6 +79,7 @@ class OutputNetwork(Module):
step_output[node2].eq(step_input[node2]) step_output[node2].eq(step_input[node2])
), ),
step_output[node1].replace_occured.eq(1), step_output[node1].replace_occured.eq(1),
step_output[node1].nondata_replace_occured.eq(nondata_difference),
step_output[node2].valid.eq(0), step_output[node2].valid.eq(0),
).Elif(k1 < k2, ).Elif(k1 < k2,
step_output[node1].eq(step_input[node1]), step_output[node1].eq(step_input[node1]),