From eaf4acc3f52f691ee1ad2417905b8579e4878556 Mon Sep 17 00:00:00 2001 From: Florent Kermarrec Date: Wed, 1 Nov 2017 21:11:08 +0100 Subject: [PATCH] core/mac: apply misoc changes (72faa2c) --- liteeth/core/__init__.py | 2 +- liteeth/core/mac/__init__.py | 9 ++++-- liteeth/core/mac/core.py | 11 ++++++++ liteeth/core/mac/crc.py | 5 ++++ liteeth/core/mac/sram.py | 54 +++++++++++++++++++++++++----------- liteeth/core/mac/wishbone.py | 4 +-- 6 files changed, 64 insertions(+), 21 deletions(-) diff --git a/liteeth/core/__init__.py b/liteeth/core/__init__.py index 20689a7..be7eabe 100644 --- a/liteeth/core/__init__.py +++ b/liteeth/core/__init__.py @@ -12,7 +12,7 @@ class LiteEthIPCore(Module, AutoCSR): self.submodules.arp = LiteEthARP(self.mac, mac_address, ip_address, clk_freq) self.submodules.ip = LiteEthIP(self.mac, mac_address, ip_address, self.arp.table) if with_icmp: - self.submodules.icmp = LiteEthICMP(self.ip, ip_address) + self.submodules.icmp = LiteEthICMP(self.ip, ip_address) class LiteEthUDPIPCore(LiteEthIPCore): diff --git a/liteeth/core/mac/__init__.py b/liteeth/core/mac/__init__.py index 99fe92a..59e30e3 100644 --- a/liteeth/core/mac/__init__.py +++ b/liteeth/core/mac/__init__.py @@ -8,7 +8,9 @@ class LiteEthMAC(Module, AutoCSR): def __init__(self, phy, dw, interface="crossbar", endianness="big", - with_preamble_crc=True): + with_preamble_crc=True, + nrxslots=2, + ntxslots=2): self.submodules.core = LiteEthMACCore(phy, dw, endianness, with_preamble_crc) self.csrs = [] if interface == "crossbar": @@ -22,7 +24,10 @@ class LiteEthMAC(Module, AutoCSR): self.depacketizer.source.connect(self.crossbar.master.sink) ] elif interface == "wishbone": - self.submodules.interface = LiteEthMACWishboneInterface(dw, 2, 2) + self.rx_slots = CSRConstant(nrxslots) + self.tx_slots = CSRConstant(ntxslots) + self.slot_size = CSRConstant(2**bits_for(eth_mtu)) + self.submodules.interface = LiteEthMACWishboneInterface(dw, nrxslots, ntxslots) self.comb += Port.connect(self.interface, self.core) self.ev, self.bus = self.interface.sram.ev, self.interface.bus self.csrs = self.interface.get_csrs() + self.core.get_csrs() diff --git a/liteeth/core/mac/core.py b/liteeth/core/mac/core.py index 51c0ffc..3c0bf0f 100644 --- a/liteeth/core/mac/core.py +++ b/liteeth/core/mac/core.py @@ -1,6 +1,7 @@ from liteeth.common import * from liteeth.core.mac import gap, preamble, crc, padding, last_be from liteeth.phy.model import LiteEthPHYModel +from litex.gen.genlib.cdc import PulseSynchronizer class LiteEthMACCore(Module, AutoCSR): @@ -29,6 +30,8 @@ class LiteEthMACCore(Module, AutoCSR): self._preamble_crc = CSRStatus(reset=1) elif with_preamble_crc: self._preamble_crc = CSRStatus(reset=1) + self.crc_errors = CSRStatus(32) + # Preamble insert/check preamble_inserter = preamble.LiteEthMACPreambleInserter(phy.dw) preamble_checker = preamble.LiteEthMACPreambleChecker(phy.dw) @@ -44,6 +47,14 @@ class LiteEthMACCore(Module, AutoCSR): tx_pipeline += [preamble_inserter, crc32_inserter] rx_pipeline += [preamble_checker, crc32_checker] + # CRC error counter + self.submodules.ps_crc_error = PulseSynchronizer("eth_rx", "sys") + + self.comb += self.ps_crc_error.i.eq(crc32_checker.crc_error) + self.sync += [ + If(self.ps_crc_error.o, + self.crc_errors.status.eq(self.crc_errors.status + 1))] + # Padding if with_padding: padding_inserter = padding.LiteEthMACPaddingInserter(phy.dw, 60) diff --git a/liteeth/core/mac/crc.py b/liteeth/core/mac/crc.py index 398e6f3..5407689 100644 --- a/liteeth/core/mac/crc.py +++ b/liteeth/core/mac/crc.py @@ -215,11 +215,15 @@ class LiteEthMACCRCChecker(Module): source : out Packets output without CRC and "error" set to 0 on last when CRC OK / set to 1 when CRC KO. + crc_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() + # # # dw = len(sink.data) @@ -252,6 +256,7 @@ class LiteEthMACCRCChecker(Module): source.payload.eq(fifo.source.payload), source.error.eq(sink.error | crc.error), + self.crc_error.eq(sink.last & crc.error), ] fsm.act("RESET", diff --git a/liteeth/core/mac/sram.py b/liteeth/core/mac/sram.py index 65730b3..47a8d75 100644 --- a/liteeth/core/mac/sram.py +++ b/liteeth/core/mac/sram.py @@ -15,6 +15,8 @@ class LiteEthMACSRAMWriter(Module, AutoCSR): self._slot = CSRStatus(slotbits) self._length = CSRStatus(lengthbits) + self.errors = CSRStatus(32) + self.submodules.ev = EventManager() self.ev.available = EventSourceLevel() self.ev.finalize() @@ -67,17 +69,26 @@ class LiteEthMACSRAMWriter(Module, AutoCSR): ongoing.eq(1), counter_ce.eq(1), NextState("WRITE") + ).Else( + NextValue(self.errors.status, self.errors.status + 1), + NextState("DISCARD_REMAINING") ) ) ) fsm.act("WRITE", - counter_ce.eq(sink.valid), - ongoing.eq(counter < eth_mtu), - If(sink.valid & sink.last, - If((sink.error & sink.last_be) != 0, - NextState("DISCARD") + If(sink.valid, + If(counter == eth_mtu, + NextState("DISCARD_REMAINING") ).Else( - NextState("TERMINATE") + counter_ce.eq(1), + ongoing.eq(1) + ), + If(sink.last, + If((sink.error & sink.last_be) != 0, + NextState("DISCARD") + ).Else( + NextState("TERMINATE") + ) ) ) ) @@ -85,6 +96,11 @@ class LiteEthMACSRAMWriter(Module, AutoCSR): counter_reset.eq(1), NextState("IDLE") ) + fsm.act("DISCARD_REMAINING", + If(sink.valid & sink.last, + NextState("TERMINATE") + ) + ) self.comb += [ fifo.sink.slot.eq(slot), fifo.sink.length.eq(counter) @@ -128,7 +144,7 @@ class LiteEthMACSRAMReader(Module, AutoCSR): self.source = source = stream.Endpoint(eth_phy_description(dw)) slotbits = max(log2_int(nslots), 1) - lengthbits = log2_int(depth*4) # length in bytes + lengthbits = bits_for(depth*4) # length in bytes self.lengthbits = lengthbits self._start = CSR() @@ -166,14 +182,22 @@ class LiteEthMACSRAMReader(Module, AutoCSR): # fsm last = Signal() + last_d = Signal() fsm = FSM(reset_state="IDLE") self.submodules += fsm fsm.act("IDLE", + counter_reset.eq(1), If(fifo.source.valid, - counter_ce.eq(1), - NextState("SEND") + NextState("CHECK") + ) + ) + fsm.act("CHECK", + If(~last_d, + NextState("SEND"), + ).Else( + NextState("END"), ) ) length_lsb = fifo.source.length[0:2] @@ -194,21 +218,19 @@ class LiteEthMACSRAMReader(Module, AutoCSR): source.valid.eq(1), source.last.eq(last), If(source.ready, - counter_ce.eq(1), - If(last, - NextState("TERMINATE") - ) + counter_ce.eq(~last), + NextState("CHECK") ) ) - fsm.act("TERMINATE", + fsm.act("END", fifo.source.ready.eq(1), self.ev.done.trigger.eq(1), - counter_reset.eq(1), NextState("IDLE") ) # last computation - self.comb += last.eq(counter >= fifo.source.length) + self.comb += last.eq((counter + 4) >= fifo.source.length) + self.sync += last_d.eq(last) # memory rd_slot = fifo.source.slot diff --git a/liteeth/core/mac/wishbone.py b/liteeth/core/mac/wishbone.py index c006345..96fecf7 100644 --- a/liteeth/core/mac/wishbone.py +++ b/liteeth/core/mac/wishbone.py @@ -14,7 +14,7 @@ class LiteEthMACWishboneInterface(Module, AutoCSR): # # # # storage in SRAM - sram_depth = buffer_depth//(dw//8) + sram_depth = eth_mtu//(dw//8) self.submodules.sram = sram.LiteEthMACSRAM(dw, sram_depth, nrxslots, ntxslots) self.comb += [ self.sink.connect(self.sram.sink), @@ -30,7 +30,7 @@ class LiteEthMACWishboneInterface(Module, AutoCSR): wb_sram_ifs = wb_rx_sram_ifs + wb_tx_sram_ifs wb_slaves = [] - decoderoffset = log2_int(sram_depth) + decoderoffset = log2_int(sram_depth, need_pow2=False) decoderbits = log2_int(len(wb_sram_ifs)) for n, wb_sram_if in enumerate(wb_sram_ifs): def slave_filter(a, v=n):