Merge pull request #88 from lschuermann/dev/wtfverilog
{De,P}acketizer: fix source.last assignment between the two FSMs
This commit is contained in:
commit
b6c5e41097
|
@ -43,6 +43,10 @@ class Packetizer(Module):
|
||||||
if header_words != 1:
|
if header_words != 1:
|
||||||
self.sync += If(sr_shift, sr.eq(sr[data_width:]))
|
self.sync += If(sr_shift, sr.eq(sr[data_width:]))
|
||||||
|
|
||||||
|
source_last_a = Signal()
|
||||||
|
source_last_b = Signal()
|
||||||
|
source_last_s = Signal()
|
||||||
|
|
||||||
# FSM.
|
# FSM.
|
||||||
self.submodules.fsm = fsm = FSM(reset_state="IDLE")
|
self.submodules.fsm = fsm = FSM(reset_state="IDLE")
|
||||||
fsm_from_idle = Signal()
|
fsm_from_idle = Signal()
|
||||||
|
@ -52,7 +56,7 @@ class Packetizer(Module):
|
||||||
If(sink.valid,
|
If(sink.valid,
|
||||||
sink.ready.eq(0),
|
sink.ready.eq(0),
|
||||||
source.valid.eq(1),
|
source.valid.eq(1),
|
||||||
source.last.eq(0),
|
source_last_a.eq(0),
|
||||||
source.data.eq(self.header[:data_width]),
|
source.data.eq(self.header[:data_width]),
|
||||||
If(source.valid & source.ready,
|
If(source.valid & source.ready,
|
||||||
sr_load.eq(1),
|
sr_load.eq(1),
|
||||||
|
@ -67,7 +71,7 @@ class Packetizer(Module):
|
||||||
)
|
)
|
||||||
fsm.act("HEADER-SEND",
|
fsm.act("HEADER-SEND",
|
||||||
source.valid.eq(1),
|
source.valid.eq(1),
|
||||||
source.last.eq(0),
|
source_last_a.eq(0),
|
||||||
source.data.eq(sr[min(data_width, len(sr)-1):]),
|
source.data.eq(sr[min(data_width, len(sr)-1):]),
|
||||||
If(source.valid & source.ready,
|
If(source.valid & source.ready,
|
||||||
sr_shift.eq(1),
|
sr_shift.eq(1),
|
||||||
|
@ -82,7 +86,7 @@ class Packetizer(Module):
|
||||||
)
|
)
|
||||||
fsm.act("ALIGNED-DATA-COPY",
|
fsm.act("ALIGNED-DATA-COPY",
|
||||||
source.valid.eq(sink.valid),
|
source.valid.eq(sink.valid),
|
||||||
source.last.eq(sink.last),
|
source_last_a.eq(sink.last),
|
||||||
source.data.eq(sink.data),
|
source.data.eq(sink.data),
|
||||||
If(source.valid & source.ready,
|
If(source.valid & source.ready,
|
||||||
sink.ready.eq(1),
|
sink.ready.eq(1),
|
||||||
|
@ -96,7 +100,7 @@ class Packetizer(Module):
|
||||||
self.sync += If(source.ready, sink_d.eq(sink))
|
self.sync += If(source.ready, sink_d.eq(sink))
|
||||||
fsm.act("UNALIGNED-DATA-COPY",
|
fsm.act("UNALIGNED-DATA-COPY",
|
||||||
source.valid.eq(sink.valid | sink_d.last),
|
source.valid.eq(sink.valid | sink_d.last),
|
||||||
source.last.eq(sink.last | sink_d.last),
|
source_last_a.eq(sink.last | sink_d.last),
|
||||||
If(fsm_from_idle,
|
If(fsm_from_idle,
|
||||||
source.data[:max(header_leftover*8, 1)].eq(sr[min(header_offset_multiplier*data_width, len(sr)-1):])
|
source.data[:max(header_leftover*8, 1)].eq(sr[min(header_offset_multiplier*data_width, len(sr)-1):])
|
||||||
).Else(
|
).Else(
|
||||||
|
@ -161,7 +165,8 @@ class Packetizer(Module):
|
||||||
If(in_data_copy & sink.last & (sink_last_be > new_last_be),
|
If(in_data_copy & sink.last & (sink_last_be > new_last_be),
|
||||||
# Right shift did not wrap around, need to delay the
|
# Right shift did not wrap around, need to delay the
|
||||||
# calculated last_be value and last by one cycle.
|
# calculated last_be value and last by one cycle.
|
||||||
source.last.eq(0),
|
source_last_b.eq(0),
|
||||||
|
source_last_s.eq(1),
|
||||||
source.last_be.eq(0),
|
source.last_be.eq(0),
|
||||||
If(source.ready & source.valid,
|
If(source.ready & source.valid,
|
||||||
NextValue(delayed_last_be, new_last_be),
|
NextValue(delayed_last_be, new_last_be),
|
||||||
|
@ -170,7 +175,8 @@ class Packetizer(Module):
|
||||||
).Elif(in_data_copy,
|
).Elif(in_data_copy,
|
||||||
# Output the calculated last_be value on the current packet
|
# Output the calculated last_be value on the current packet
|
||||||
# already. For the next sink packet, ignore any last_be
|
# already. For the next sink packet, ignore any last_be
|
||||||
source.last.eq(sink.last),
|
source_last_b.eq(sink.last),
|
||||||
|
source_last_s.eq(1),
|
||||||
source.last_be.eq(new_last_be),
|
source.last_be.eq(new_last_be),
|
||||||
),
|
),
|
||||||
If(in_data_copy,
|
If(in_data_copy,
|
||||||
|
@ -182,7 +188,8 @@ class Packetizer(Module):
|
||||||
|
|
||||||
self.last_be_fsm.act("DELAYED",
|
self.last_be_fsm.act("DELAYED",
|
||||||
# Output the delayed last and last_be signals
|
# Output the delayed last and last_be signals
|
||||||
source.last.eq(1),
|
source_last_b.eq(1),
|
||||||
|
source_last_s.eq(1),
|
||||||
source.last_be.eq(delayed_last_be),
|
source.last_be.eq(delayed_last_be),
|
||||||
sink.ready.eq(0),
|
sink.ready.eq(0),
|
||||||
If(source.ready,
|
If(source.ready,
|
||||||
|
@ -190,6 +197,14 @@ class Packetizer(Module):
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
self.comb += [
|
||||||
|
If(source_last_s,
|
||||||
|
source.last.eq(source_last_b),
|
||||||
|
).Else(
|
||||||
|
source.last.eq(source_last_a),
|
||||||
|
)
|
||||||
|
]
|
||||||
|
|
||||||
# Error.
|
# Error.
|
||||||
if hasattr(sink, "error") and hasattr(source, "error"):
|
if hasattr(sink, "error") and hasattr(source, "error"):
|
||||||
self.comb += source.error.eq(sink.error)
|
self.comb += source.error.eq(sink.error)
|
||||||
|
@ -229,6 +244,10 @@ class Depacketizer(Module):
|
||||||
self.comb += self.header.eq(sr)
|
self.comb += self.header.eq(sr)
|
||||||
self.comb += header.decode(self.header, source)
|
self.comb += header.decode(self.header, source)
|
||||||
|
|
||||||
|
source_last_a = Signal()
|
||||||
|
source_last_b = Signal()
|
||||||
|
source_last_s = Signal()
|
||||||
|
|
||||||
# FSM.
|
# FSM.
|
||||||
self.submodules.fsm = fsm = FSM(reset_state="IDLE")
|
self.submodules.fsm = fsm = FSM(reset_state="IDLE")
|
||||||
fsm_from_idle = Signal()
|
fsm_from_idle = Signal()
|
||||||
|
@ -258,7 +277,7 @@ class Depacketizer(Module):
|
||||||
)
|
)
|
||||||
fsm.act("ALIGNED-DATA-COPY",
|
fsm.act("ALIGNED-DATA-COPY",
|
||||||
source.valid.eq(sink.valid | sink_d.last),
|
source.valid.eq(sink.valid | sink_d.last),
|
||||||
source.last.eq(sink.last | sink_d.last),
|
source_last_a.eq(sink.last | sink_d.last),
|
||||||
sink.ready.eq(source.ready),
|
sink.ready.eq(source.ready),
|
||||||
source.data.eq(sink.data),
|
source.data.eq(sink.data),
|
||||||
If(source.valid & source.ready,
|
If(source.valid & source.ready,
|
||||||
|
@ -272,7 +291,7 @@ class Depacketizer(Module):
|
||||||
self.sync += If(sink.valid & sink.ready, sink_d.eq(sink))
|
self.sync += If(sink.valid & sink.ready, sink_d.eq(sink))
|
||||||
fsm.act("UNALIGNED-DATA-COPY",
|
fsm.act("UNALIGNED-DATA-COPY",
|
||||||
source.valid.eq(sink.valid | sink_d.last),
|
source.valid.eq(sink.valid | sink_d.last),
|
||||||
source.last.eq(sink_d.last),
|
source_last_a.eq(sink_d.last),
|
||||||
sink.ready.eq(source.ready & ~source.last),
|
sink.ready.eq(source.ready & ~source.last),
|
||||||
source.data.eq(sink_d.data[header_leftover*8:]),
|
source.data.eq(sink_d.data[header_leftover*8:]),
|
||||||
source.data[min((bytes_per_clk-header_leftover)*8, data_width-1):].eq(sink.data),
|
source.data[min((bytes_per_clk-header_leftover)*8, data_width-1):].eq(sink.data),
|
||||||
|
@ -351,7 +370,8 @@ class Depacketizer(Module):
|
||||||
If(sink.valid & sink.last & (sink_last_be > new_last_be),
|
If(sink.valid & sink.last & (sink_last_be > new_last_be),
|
||||||
# last_be did wrap around. Need to delay the calculated
|
# last_be did wrap around. Need to delay the calculated
|
||||||
# last_be value and last by one cycle.
|
# last_be value and last by one cycle.
|
||||||
source.last.eq(0),
|
source_last_b.eq(0),
|
||||||
|
source_last_s.eq(1),
|
||||||
source.last_be.eq(0),
|
source.last_be.eq(0),
|
||||||
# Normally just wait until a source bus transaction occurred
|
# Normally just wait until a source bus transaction occurred
|
||||||
# (ready + valid) until the delayed last_be can be
|
# (ready + valid) until the delayed last_be can be
|
||||||
|
@ -369,7 +389,8 @@ class Depacketizer(Module):
|
||||||
),
|
),
|
||||||
).Elif(sink.last,
|
).Elif(sink.last,
|
||||||
# Simply forward the calculated last_be value.
|
# Simply forward the calculated last_be value.
|
||||||
source.last.eq(1),
|
source_last_b.eq(1),
|
||||||
|
source_last_s.eq(1),
|
||||||
source.last_be.eq(new_last_be),
|
source.last_be.eq(new_last_be),
|
||||||
),
|
),
|
||||||
If(self.fsm.ongoing("ALIGNED-DATA-COPY") \
|
If(self.fsm.ongoing("ALIGNED-DATA-COPY") \
|
||||||
|
@ -382,10 +403,19 @@ class Depacketizer(Module):
|
||||||
|
|
||||||
self.last_be_fsm.act("DELAYED",
|
self.last_be_fsm.act("DELAYED",
|
||||||
# Output the delayed last and last_be signals
|
# Output the delayed last and last_be signals
|
||||||
source.last.eq(1),
|
source_last_b.eq(1),
|
||||||
|
source_last_s.eq(1),
|
||||||
source.last_be.eq(delayed_last_be),
|
source.last_be.eq(delayed_last_be),
|
||||||
sink.ready.eq(0),
|
sink.ready.eq(0),
|
||||||
If(source.ready & source.valid,
|
If(source.ready & source.valid,
|
||||||
NextState("DEFAULT"),
|
NextState("DEFAULT"),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
self.comb += [
|
||||||
|
If(source_last_s,
|
||||||
|
source.last.eq(source_last_b),
|
||||||
|
).Else(
|
||||||
|
source.last.eq(source_last_a),
|
||||||
|
),
|
||||||
|
]
|
||||||
|
|
Loading…
Reference in New Issue