mac/crc: Cleanup and try to move data-path connection outside of FSM for timings.
This commit is contained in:
parent
b22ac619ab
commit
bbdd6835aa
|
@ -152,16 +152,20 @@ class LiteEthMACCRC32Inserter(LiteXModule):
|
||||||
|
|
||||||
# # #
|
# # #
|
||||||
|
|
||||||
|
# Parameters.
|
||||||
data_width = len(sink.data)
|
data_width = len(sink.data)
|
||||||
|
ratio = 32//data_width
|
||||||
assert data_width in [8, 32, 64]
|
assert data_width in [8, 32, 64]
|
||||||
crc = LiteEthMACCRC32(data_width)
|
|
||||||
fsm = FSM(reset_state="IDLE")
|
|
||||||
self.submodules += crc, fsm
|
|
||||||
|
|
||||||
# crc packet checksum
|
# Signals.
|
||||||
crc_packet = Signal(crc.width)
|
crc_packet = Signal(32)
|
||||||
last_be = Signal().like(sink.last_be)
|
last_be = Signal(data_width//8)
|
||||||
|
|
||||||
|
# CRC32 Generator.
|
||||||
|
self.crc = crc = LiteEthMACCRC32(data_width)
|
||||||
|
|
||||||
|
# FSM.
|
||||||
|
self.fsm = fsm = FSM(reset_state="IDLE")
|
||||||
fsm.act("IDLE",
|
fsm.act("IDLE",
|
||||||
crc.reset.eq(1),
|
crc.reset.eq(1),
|
||||||
sink.ready.eq(1),
|
sink.ready.eq(1),
|
||||||
|
@ -170,22 +174,23 @@ class LiteEthMACCRC32Inserter(LiteXModule):
|
||||||
NextState("COPY"),
|
NextState("COPY"),
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
fsm.act("COPY",
|
self.comb += [
|
||||||
crc.ce.eq(sink.valid & source.ready),
|
|
||||||
crc.data.eq(sink.data),
|
crc.data.eq(sink.data),
|
||||||
crc.be.eq(sink.last_be),
|
crc.be.eq(sink.last_be),
|
||||||
|
]
|
||||||
|
fsm.act("COPY",
|
||||||
|
crc.ce.eq(sink.valid & source.ready),
|
||||||
sink.connect(source),
|
sink.connect(source),
|
||||||
source.last.eq(0),
|
source.last.eq(0),
|
||||||
source.last_be.eq(0),
|
source.last_be.eq(0),
|
||||||
If(sink.last,
|
If(sink.last,
|
||||||
# Fill the empty space of the last data word with the
|
# Fill the empty space of the last data word with the beginning of the CRC value.
|
||||||
# beginning of the crc value
|
|
||||||
[If(sink.last_be[e],
|
[If(sink.last_be[e],
|
||||||
source.data.eq(Cat(sink.data[:(e+1)*8],
|
source.data.eq(Cat(sink.data[:(e+1)*8],
|
||||||
crc.value)[:data_width])) for e in range(data_width//8)],
|
crc.value)[:data_width])) for e in range(data_width//8)],
|
||||||
# If the whole crc value fits in the last sink paket, signal the
|
# If the whole crc value fits in the last sink packet, signal the end. This also
|
||||||
# end. This also means the next state is idle
|
# means the next state is idle
|
||||||
If((data_width == 64) & (sink.last_be <= 0xF),
|
If((data_width == 64) & (sink.last_be <= 0xf),
|
||||||
source.last.eq(1),
|
source.last.eq(1),
|
||||||
source.last_be.eq(sink.last_be << (data_width//8 - 4))
|
source.last_be.eq(sink.last_be << (data_width//8 - 4))
|
||||||
),
|
),
|
||||||
|
@ -194,7 +199,7 @@ class LiteEthMACCRC32Inserter(LiteXModule):
|
||||||
),
|
),
|
||||||
|
|
||||||
If(sink.valid & sink.last & source.ready,
|
If(sink.valid & sink.last & source.ready,
|
||||||
If((data_width == 64) & (sink.last_be <= 0xF),
|
If((data_width == 64) & (sink.last_be <= 0xf),
|
||||||
NextState("IDLE"),
|
NextState("IDLE"),
|
||||||
).Else(
|
).Else(
|
||||||
NextValue(crc_packet, crc.value),
|
NextValue(crc_packet, crc.value),
|
||||||
|
@ -207,7 +212,6 @@ class LiteEthMACCRC32Inserter(LiteXModule):
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
ratio = crc.width//data_width
|
|
||||||
if ratio > 1:
|
if ratio > 1:
|
||||||
cnt = Signal(max=ratio, reset=ratio-1)
|
cnt = Signal(max=ratio, reset=ratio-1)
|
||||||
cnt_done = Signal()
|
cnt_done = Signal()
|
||||||
|
@ -216,7 +220,9 @@ class LiteEthMACCRC32Inserter(LiteXModule):
|
||||||
chooser(crc_packet, cnt, source.data, reverse=True),
|
chooser(crc_packet, cnt, source.data, reverse=True),
|
||||||
If(cnt_done,
|
If(cnt_done,
|
||||||
source.last.eq(1),
|
source.last.eq(1),
|
||||||
If(source.ready, NextState("IDLE"))
|
If(source.ready,
|
||||||
|
NextState("IDLE")
|
||||||
|
)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
self.comb += cnt_done.eq(cnt == 0)
|
self.comb += cnt_done.eq(cnt == 0)
|
||||||
|
@ -234,7 +240,9 @@ class LiteEthMACCRC32Inserter(LiteXModule):
|
||||||
source.last_be.eq(last_be),
|
source.last_be.eq(last_be),
|
||||||
[If(last_be[e],
|
[If(last_be[e],
|
||||||
source.data.eq(crc_packet[-(e+1)*8:])) for e in range(data_width//8)],
|
source.data.eq(crc_packet[-(e+1)*8:])) for e in range(data_width//8)],
|
||||||
If(source.ready, NextState("IDLE"))
|
If(source.ready,
|
||||||
|
NextState("IDLE")
|
||||||
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
# MAC CRC32 Checker --------------------------------------------------------------------------------
|
# MAC CRC32 Checker --------------------------------------------------------------------------------
|
||||||
|
@ -267,17 +275,16 @@ class LiteEthMACCRC32Checker(LiteXModule):
|
||||||
|
|
||||||
# # #
|
# # #
|
||||||
|
|
||||||
|
# Parameters.
|
||||||
data_width = len(sink.data)
|
data_width = len(sink.data)
|
||||||
|
ratio = ceil(32/data_width)
|
||||||
assert data_width in [8, 32, 64]
|
assert data_width in [8, 32, 64]
|
||||||
crc = LiteEthMACCRC32(data_width)
|
|
||||||
self.submodules += crc
|
|
||||||
ratio = ceil(crc.width/data_width)
|
|
||||||
|
|
||||||
fifo = ResetInserter()(stream.SyncFIFO(description, ratio + 1))
|
# CRC32 Checker.
|
||||||
self.submodules += fifo
|
self.crc = crc = LiteEthMACCRC32(data_width)
|
||||||
|
|
||||||
fsm = FSM(reset_state="RESET")
|
# FIFO.
|
||||||
self.submodules += fsm
|
self.fifo = fifo = ResetInserter()(stream.SyncFIFO(description, ratio + 1))
|
||||||
|
|
||||||
fifo_in = Signal()
|
fifo_in = Signal()
|
||||||
fifo_out = Signal()
|
fifo_out = Signal()
|
||||||
|
@ -293,6 +300,8 @@ class LiteEthMACCRC32Checker(LiteXModule):
|
||||||
self.sink.ready.eq(fifo_in),
|
self.sink.ready.eq(fifo_in),
|
||||||
]
|
]
|
||||||
|
|
||||||
|
# FSM.
|
||||||
|
self.fsm = fsm = FSM(reset_state="RESET")
|
||||||
fsm.act("RESET",
|
fsm.act("RESET",
|
||||||
crc.reset.eq(1),
|
crc.reset.eq(1),
|
||||||
fifo.reset.eq(1),
|
fifo.reset.eq(1),
|
||||||
|
@ -310,10 +319,10 @@ class LiteEthMACCRC32Checker(LiteXModule):
|
||||||
)
|
)
|
||||||
last_be = Signal().like(sink.last_be)
|
last_be = Signal().like(sink.last_be)
|
||||||
crc_error = Signal()
|
crc_error = Signal()
|
||||||
|
self.comb += fifo.source.connect(source, omit={"valid", "ready", "last", "last_be"})
|
||||||
fsm.act("COPY",
|
fsm.act("COPY",
|
||||||
fifo.source.ready.eq(fifo_out),
|
fifo.source.ready.eq(fifo_out),
|
||||||
source.valid.eq(sink.valid & fifo_full),
|
source.valid.eq(sink.valid & fifo_full),
|
||||||
source.payload.eq(fifo.source.payload),
|
|
||||||
|
|
||||||
If(data_width <= 32,
|
If(data_width <= 32,
|
||||||
source.last.eq(sink.last),
|
source.last.eq(sink.last),
|
||||||
|
@ -350,7 +359,7 @@ class LiteEthMACCRC32Checker(LiteXModule):
|
||||||
# If the last sink word contains both data and the crc value, shift out
|
# If the last sink word contains both data and the crc value, shift out
|
||||||
# the last value here. Can only happen for data_width == 64
|
# the last value here. Can only happen for data_width == 64
|
||||||
fsm.act("COPY_LAST",
|
fsm.act("COPY_LAST",
|
||||||
fifo.source.connect(source),
|
fifo.source.connect(source, keep={"valid", "ready", "last"}),
|
||||||
source.error.eq(fifo.source.error | Replicate(crc_error, data_width//8)),
|
source.error.eq(fifo.source.error | Replicate(crc_error, data_width//8)),
|
||||||
source.last_be.eq(last_be),
|
source.last_be.eq(last_be),
|
||||||
If(source.valid & source.ready,
|
If(source.valid & source.ready,
|
||||||
|
|
Loading…
Reference in New Issue