mirror of
https://github.com/enjoy-digital/liteeth.git
synced 2025-01-03 03:43:37 -05:00
core/mac: apply changes from misoc: remove gap_checker in rx, add preamble errors, fix preamble checker
This commit is contained in:
parent
ccdb85bcb7
commit
c9ec30df2f
4 changed files with 58 additions and 79 deletions
|
@ -16,12 +16,8 @@ class LiteEthMACCore(Module, AutoCSR):
|
|||
|
||||
# Interpacket gap
|
||||
tx_gap_inserter = gap.LiteEthMACGap(phy.dw)
|
||||
rx_gap_checker = gap.LiteEthMACGap(phy.dw, ack_on_gap=True)
|
||||
self.submodules += ClockDomainsRenamer("eth_tx")(tx_gap_inserter)
|
||||
self.submodules += ClockDomainsRenamer("eth_rx")(rx_gap_checker)
|
||||
|
||||
tx_pipeline += [tx_gap_inserter]
|
||||
rx_pipeline += [rx_gap_checker]
|
||||
|
||||
# Preamble / CRC
|
||||
if isinstance(phy, LiteEthPHYModel):
|
||||
|
@ -30,6 +26,7 @@ class LiteEthMACCore(Module, AutoCSR):
|
|||
self._preamble_crc = CSRStatus(reset=1)
|
||||
elif with_preamble_crc:
|
||||
self._preamble_crc = CSRStatus(reset=1)
|
||||
self.preamble_errors = CSRStatus(32)
|
||||
self.crc_errors = CSRStatus(32)
|
||||
|
||||
# Preamble insert/check
|
||||
|
@ -47,13 +44,20 @@ class LiteEthMACCore(Module, AutoCSR):
|
|||
tx_pipeline += [preamble_inserter, crc32_inserter]
|
||||
rx_pipeline += [preamble_checker, crc32_checker]
|
||||
|
||||
# CRC error counter
|
||||
# Error counters
|
||||
self.submodules.ps_preamble_error = PulseSynchronizer("eth_rx", "sys")
|
||||
self.submodules.ps_crc_error = PulseSynchronizer("eth_rx", "sys")
|
||||
|
||||
self.comb += self.ps_crc_error.i.eq(crc32_checker.crc_error)
|
||||
self.comb += [
|
||||
self.ps_preamble_error.i.eq(preamble_checker.error),
|
||||
self.ps_crc_error.i.eq(crc32_checker.error),
|
||||
]
|
||||
self.sync += [
|
||||
If(self.ps_preamble_error.o,
|
||||
self.preamble_errors.status.eq(self.preamble_errors.status + 1)),
|
||||
If(self.ps_crc_error.o,
|
||||
self.crc_errors.status.eq(self.crc_errors.status + 1))]
|
||||
self.crc_errors.status.eq(self.crc_errors.status + 1)),
|
||||
]
|
||||
|
||||
# Padding
|
||||
if with_padding:
|
||||
|
|
|
@ -133,9 +133,9 @@ class LiteEthMACCRCInserter(Module):
|
|||
Attributes
|
||||
----------
|
||||
sink : in
|
||||
Packets input without CRC.
|
||||
Packets octets without CRC.
|
||||
source : out
|
||||
Packets output with CRC.
|
||||
Packets octets with CRC.
|
||||
"""
|
||||
def __init__(self, crc_class, description):
|
||||
self.sink = sink = stream.Endpoint(description)
|
||||
|
@ -211,18 +211,18 @@ class LiteEthMACCRCChecker(Module):
|
|||
Attributes
|
||||
----------
|
||||
sink : in
|
||||
Packets input with CRC.
|
||||
Packet octets with CRC.
|
||||
source : out
|
||||
Packets output without CRC and "error" set to 0
|
||||
Packet octets without CRC and "error" set to 0
|
||||
on last when CRC OK / set to 1 when CRC KO.
|
||||
crc_error : out
|
||||
error : out
|
||||
Pulses every time a CRC error is detected.
|
||||
"""
|
||||
def __init__(self, crc_class, description):
|
||||
self.sink = sink = stream.Endpoint(description)
|
||||
self.source = source = stream.Endpoint(description)
|
||||
|
||||
self.crc_error = Signal()
|
||||
self.error = Signal()
|
||||
|
||||
# # #
|
||||
|
||||
|
@ -256,7 +256,7 @@ class LiteEthMACCRCChecker(Module):
|
|||
source.payload.eq(fifo.source.payload),
|
||||
|
||||
source.error.eq(sink.error | crc.error),
|
||||
self.crc_error.eq(source.valid & source.last & crc.error),
|
||||
self.error.eq(source.valid & source.last & crc.error),
|
||||
]
|
||||
|
||||
fsm.act("RESET",
|
||||
|
|
|
@ -4,7 +4,7 @@ from liteeth.common import *
|
|||
|
||||
|
||||
class LiteEthMACGap(Module):
|
||||
def __init__(self, dw, ack_on_gap=False):
|
||||
def __init__(self, dw):
|
||||
self.sink = sink = stream.Endpoint(eth_phy_description(dw))
|
||||
self.source = source = stream.Endpoint(eth_phy_description(dw))
|
||||
|
||||
|
@ -31,7 +31,6 @@ class LiteEthMACGap(Module):
|
|||
)
|
||||
fsm.act("GAP",
|
||||
counter_ce.eq(1),
|
||||
sink.ready.eq(int(ack_on_gap)),
|
||||
If(counter == (gap-1),
|
||||
NextState("COPY")
|
||||
)
|
||||
|
|
|
@ -4,6 +4,17 @@ from litex.gen.genlib.misc import chooser
|
|||
|
||||
|
||||
class LiteEthMACPreambleInserter(Module):
|
||||
"""Preamble inserter
|
||||
|
||||
Inserts preamble at the beginning of each packet.
|
||||
|
||||
Attributes
|
||||
----------
|
||||
sink : in
|
||||
Packet octets.
|
||||
source : out
|
||||
Preamble, SFD, and packet octets.
|
||||
"""
|
||||
def __init__(self, dw):
|
||||
self.sink = stream.Endpoint(eth_phy_description(dw))
|
||||
self.source = stream.Endpoint(eth_phy_description(dw))
|
||||
|
@ -48,7 +59,7 @@ class LiteEthMACPreambleInserter(Module):
|
|||
self.source.last_be.eq(self.sink.last_be)
|
||||
]
|
||||
fsm.act("COPY",
|
||||
self.sink.connect(self.source, omit=set(["data", "last_be"])),
|
||||
self.sink.connect(self.source, omit={"data", "last_be"}),
|
||||
|
||||
If(self.sink.valid & self.sink.last & self.source.ready,
|
||||
NextState("IDLE"),
|
||||
|
@ -57,80 +68,45 @@ class LiteEthMACPreambleInserter(Module):
|
|||
|
||||
|
||||
class LiteEthMACPreambleChecker(Module):
|
||||
"""Preamble detector
|
||||
|
||||
Detects preamble at the beginning of each packet.
|
||||
|
||||
Attributes
|
||||
----------
|
||||
sink : in
|
||||
Bits input.
|
||||
source : out
|
||||
Packet octets starting immediately after SFD.
|
||||
error : out
|
||||
Pulses every time a preamble error is detected.
|
||||
"""
|
||||
def __init__(self, dw):
|
||||
self.sink = stream.Endpoint(eth_phy_description(dw))
|
||||
self.source = stream.Endpoint(eth_phy_description(dw))
|
||||
assert dw == 8
|
||||
self.sink = sink = stream.Endpoint(eth_phy_description(dw))
|
||||
self.source = source = stream.Endpoint(eth_phy_description(dw))
|
||||
|
||||
self.error = Signal()
|
||||
|
||||
# # #
|
||||
|
||||
preamble = Signal(64, reset=eth_preamble)
|
||||
cnt_max = (64//dw) - 1
|
||||
cnt = Signal(max=cnt_max+1, reset_less=True)
|
||||
clr_cnt = Signal()
|
||||
inc_cnt = Signal()
|
||||
|
||||
self.sync += \
|
||||
If(clr_cnt,
|
||||
cnt.eq(0)
|
||||
).Elif(inc_cnt,
|
||||
cnt.eq(cnt+1)
|
||||
)
|
||||
|
||||
discard = Signal(reset_less=True)
|
||||
clr_discard = Signal()
|
||||
set_discard = Signal()
|
||||
|
||||
self.sync += \
|
||||
If(clr_discard,
|
||||
discard.eq(0)
|
||||
).Elif(set_discard,
|
||||
discard.eq(1)
|
||||
)
|
||||
|
||||
ref = Signal(dw)
|
||||
match = Signal()
|
||||
self.comb += [
|
||||
chooser(preamble, cnt, ref),
|
||||
match.eq(self.sink.data == ref)
|
||||
]
|
||||
|
||||
fsm = FSM(reset_state="IDLE")
|
||||
self.submodules += fsm
|
||||
|
||||
fsm.act("IDLE",
|
||||
self.sink.ready.eq(1),
|
||||
clr_cnt.eq(1),
|
||||
clr_discard.eq(1),
|
||||
If(self.sink.valid,
|
||||
clr_cnt.eq(0),
|
||||
inc_cnt.eq(1),
|
||||
clr_discard.eq(0),
|
||||
set_discard.eq(~match),
|
||||
NextState("CHECK"),
|
||||
)
|
||||
)
|
||||
fsm.act("CHECK",
|
||||
self.sink.ready.eq(1),
|
||||
If(self.sink.valid,
|
||||
set_discard.eq(~match),
|
||||
If(cnt == cnt_max,
|
||||
If(discard | (~match),
|
||||
NextState("IDLE")
|
||||
).Else(
|
||||
NextState("COPY")
|
||||
)
|
||||
).Else(
|
||||
inc_cnt.eq(1)
|
||||
)
|
||||
)
|
||||
sink.ready.eq(1),
|
||||
If(sink.valid & ~sink.last & (sink.data == eth_preamble >> 56),
|
||||
NextState("COPY")
|
||||
),
|
||||
If(sink.valid & sink.last, self.error.eq(1))
|
||||
)
|
||||
self.comb += [
|
||||
self.source.data.eq(self.sink.data),
|
||||
self.source.last_be.eq(self.sink.last_be)
|
||||
source.data.eq(sink.data),
|
||||
source.last_be.eq(sink.last_be)
|
||||
]
|
||||
fsm.act("COPY",
|
||||
self.sink.connect(self.source, omit=set(["data", "last_be"])),
|
||||
If(self.source.valid & self.source.last & self.source.ready,
|
||||
sink.connect(source, omit={"data", "last_be"}),
|
||||
If(source.valid & source.last & source.ready,
|
||||
NextState("IDLE"),
|
||||
)
|
||||
)
|
||||
|
|
Loading…
Reference in a new issue