From: Florent Kermarrec Date: Wed, 28 Jan 2015 23:25:55 +0000 (+0100) Subject: make packetizer/depacketizer generic and use it for all layers X-Git-Tag: 24jan2021_ls180~2604^2~113 X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=5b37068393ac17781e0b7f1f7e42b62e49637c8c;p=litex.git make packetizer/depacketizer generic and use it for all layers --- diff --git a/liteeth/arp/__init__.py b/liteeth/arp/__init__.py index e69de29b..3e09b0ed 100644 --- a/liteeth/arp/__init__.py +++ b/liteeth/arp/__init__.py @@ -0,0 +1,19 @@ +from liteeth.common import * +from liteeth.generic.depacketizer import LiteEthDepacketizer +from liteeth.generic.packetizer import LiteEthPacketizer + +class LiteEthARPDepacketizer(LiteEthDepacketizer): + def __init__(self): + LiteEthDepacketizer.__init__(self, + eth_mac_description(8), + eth_arp_description(8), + arp_header, + arp_header_length) + +class LiteEthARPPacketizer(LiteEthDepacketizer): + def __init__(self): + LiteEthDepacketizer.__init__(self, + eth_arp_description(8), + eth_mac_description(8), + arp_header, + arp_header_length) diff --git a/liteeth/common.py b/liteeth/common.py index 88433e5c..2fc2660f 100644 --- a/liteeth/common.py +++ b/liteeth/common.py @@ -1,7 +1,7 @@ from collections import OrderedDict from migen.fhdl.std import * -from migen.fhdl.std import * +from migen.fhdl.decorators import ModuleDecorator from migen.genlib.resetsync import AsyncResetSynchronizer from migen.genlib.record import * from migen.genlib.fsm import FSM, NextState @@ -160,3 +160,4 @@ class BufferizeEndpoints(ModuleDecorator): self.submodules += buf self.comb += Record.connect(source, buf.d) setattr(self, name, buf.q) + diff --git a/liteeth/generic/__init__.py b/liteeth/generic/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/liteeth/generic/depacketizer.py b/liteeth/generic/depacketizer.py new file mode 100644 index 00000000..ff7308a4 --- /dev/null +++ b/liteeth/generic/depacketizer.py @@ -0,0 +1,61 @@ +from liteeth.common import * + +def _decode_header(h_dict, h_signal, obj): + r = [] + for k, v in sorted(h_dict.items()): + start = v.byte*8+v.offset + end = start+v.width + r.append(getattr(obj, k).eq(h_signal[start:end])) + return r + +class LiteEthDepacketizer(Module): + def __init__(self, sink_description, source_description, header_type, header_length): + self.sink = sink = Sink(sink_description) + self.source = source = Source(source_description) + ### + shift = Signal() + header = Signal(header_length*8) + counter = Counter(max=header_length) + self.submodules += counter + + fsm = FSM(reset_state="IDLE") + self.submodules += fsm + + fsm.act("IDLE", + sink.ack.eq(1), + counter.reset.eq(1), + If(sink.stb, + shift.eq(1), + NextState("RECEIVE_HEADER") + ) + ) + fsm.act("RECEIVE_HEADER", + sink.ack.eq(1), + If(sink.stb, + counter.ce.eq(1), + shift.eq(1), + If(counter.value == header_length-2, + NextState("COPY") + ) + ) + ) + self.sync += \ + If(fsm.before_entering("COPY"), + source.sop.eq(1) + ).Elif(source.stb & source.ack, + source.sop.eq(0) + ) + self.comb += [ + source.sop.eq(sop), + source.eop.eq(sink.eop), + source.data.eq(sink.data), + source.error.eq(sink.error), + _decode_header(header_type, header, source) + ] + fsm.act("COPY", + sink.ack.eq(source.ack), + source.stb.eq(sink.stb), + If(source.stb & source.ack & source.eop, + NextState("IDLE") + ) + ) diff --git a/liteeth/generic/packetizer.py b/liteeth/generic/packetizer.py new file mode 100644 index 00000000..c10ff936 --- /dev/null +++ b/liteeth/generic/packetizer.py @@ -0,0 +1,73 @@ +from liteeth.common import * + +def _encode_header(h_dict, h_signal, obj): + r = [] + for k, v in sorted(h_dict.items()): + start = v.word*32+v.offset + end = start+v.width + r.append(h_signal[start:end].eq(getattr(obj, k))) + return r + +class LiteEthPacketizer(Module): + def __init__(self, sink_description, source_description, header_type, header_length): + self.sink = sink = Sink(sink_description) + self.source = source = Source(source_description) + ### + header = Signal(header_length*8) + header_reg = Signal(header_length*8) + load = Signal() + shift = Signal() + counter = Counter(max=header_length) + self.submodules += counter + + self.comb += header.eq(_encode_header(header_type, header, sink)) + self.sync += [ + If(load, + header_reg.eq(header) + ).Elif(shift, + header_reg.eq(Cat(header_reg[8:], Signal(8))) + ) + ] + + fsm = FSM(reset_state="IDLE") + self.submodules += fsm + + fsm.act("IDLE", + sink.ack.eq(1), + If(sink.stb & sink.sop, + load.eq(1), + sink.ack.eq(0), + source.stb.eq(1), + source.sop.eq(1), + source.eop.eq(0), + source.data.eq(header[:8]), + If(source.stb & source.ack, + NextState("SEND_HEADER"), + ) + ) + ) + fsm.act("SEND_HEADER", + source.stb.eq(1), + source.sop.eq(0), + source.eop.eq(sink.eop), + source.data.eq(header_reg[8:16]), + If(source.stb & source.ack, + sink.ack.eq(1), + If(counter == header_length-2, + NextState("COPY") + ) + ) + ) + fsm.act("COPY", + source.stb.eq(sink.stb), + source.sop.eq(0), + source.eop.eq(sink_eop), + source.data.eq(sink.data), + source.error.eq(sink.error), + If(source.stb & source.ack, + sink.ack.eq(1), + If(source.eop, + NextState("IDLE") + ) + ) + ) diff --git a/liteeth/ip/__init__.py b/liteeth/ip/__init__.py index e69de29b..3dbc7c01 100644 --- a/liteeth/ip/__init__.py +++ b/liteeth/ip/__init__.py @@ -0,0 +1,19 @@ +from liteeth.common import * +from liteeth.generic.depacketizer import LiteEthDepacketizer +from liteeth.generic.packetizer import LiteEthPacketizer + +class LiteEthIPV4Depacketizer(LiteEthDepacketizer): + def __init__(self): + LiteEthDepacketizer.__init__(self, + eth_mac_description(8), + eth_ipv4_description(8), + ipv4_header, + ipv4_header_length) + +class LiteEthIPV4Packetizer(LiteEthDepacketizer): + def __init__(self): + LiteEthDepacketizer.__init__(self, + eth_ipv4_description(8), + eth_mac_description(8), + ipv4_header, + ipv4_header_length) diff --git a/liteeth/mac/__init__.py b/liteeth/mac/__init__.py index 7676f38a..a983c301 100644 --- a/liteeth/mac/__init__.py +++ b/liteeth/mac/__init__.py @@ -1,6 +1,24 @@ from liteeth.common import * from liteeth.mac.core import LiteEthMACCore from liteeth.mac.frontend import wishbone +from liteeth.generic.depacketizer import LiteEthDepacketizer +from liteeth.generic.packetizer import LiteEthPacketizer + +class LiteEthMACDepacketizer(LiteEthDepacketizer): + def __init__(self): + LiteEthDepacketizer.__init__(self, + eth_phy_description(8), + eth_mac_description(8), + mac_header, + mac_header_length) + +class LiteEthMACPacketizer(LiteEthDepacketizer): + def __init__(self): + LiteEthDepacketizer.__init__(self, + eth_mac_description(8), + eth_phy_description(8), + mac_header, + mac_header_length) class LiteEthMAC(Module, AutoCSR): def __init__(self, phy, dw, interface="core", endianness="be", diff --git a/liteeth/mac/core/depacketizer.py b/liteeth/mac/core/depacketizer.py deleted file mode 100644 index b0e1a08e..00000000 --- a/liteeth/mac/core/depacketizer.py +++ /dev/null @@ -1,63 +0,0 @@ -import math - -from liteeth.common import * - -def _decode_header(h_dict, h_signal, obj): - r = [] - for k, v in sorted(h_dict.items()): - start = v.byte*8+v.offset - end = start+v.width - r.append(getattr(obj, k).eq(h_signal[start:end])) - return r - -class LiteEthMACDepacketizer(Module): - def __init__(self): - self.sink = sink = Sink(eth_mac_description(8)) - self.source = source = Source(eth_phy_description(8)) - ### - shift = Signal() - header = Signal(mac_header_length*8) - counter = Counter(max=mac_header_length) - self.submodules += counter - - fsm = FSM(reset_state="IDLE") - self.submodules += fsm - - fsm.act("IDLE", - sink.ack.eq(1), - counter.reset.eq(1), - If(sink.stb, - shift.eq(1), - NextState("RECEIVE_HEADER") - ) - ) - fsm.act("RECEIVE_HEADER", - sink.ack.eq(1), - If(sink.stb, - counter.ce.eq(1), - shift.eq(1), - If(counter.value == mac_header_length-2, - NextState("COPY") - ) - ) - ) - self.sync += \ - If(fsm.before_entering("COPY"), - source.sop.eq(1) - ).Elif(source.stb & source.ack, - source.sop.eq(0) - ) - self.comb += [ - source.sop.eq(sop), - source.eop.eq(sink.eop), - source.data.eq(sink.data), - source.error.eq(sink.error), - _decode_header(mac_header, header, source) - ] - fsm.act("COPY", - sink.ack.eq(source.ack), - source.stb.eq(sink.stb), - If(source.stb & source.ack & source.eop, - NextState("IDLE") - ) - ) diff --git a/liteeth/mac/core/packetizer.py b/liteeth/mac/core/packetizer.py deleted file mode 100644 index 66600216..00000000 --- a/liteeth/mac/core/packetizer.py +++ /dev/null @@ -1,73 +0,0 @@ -from liteeth.common import * - -def _encode_header(h_dict, h_signal, obj): - r = [] - for k, v in sorted(h_dict.items()): - start = v.word*32+v.offset - end = start+v.width - r.append(h_signal[start:end].eq(getattr(obj, k))) - return r - -class LiteEthMACPacketizer(Module): - def __init__(self): - self.sink = sink = Sink(eth_phy_description(8)) - self.source = source = Source(eth_mac_description(8)) - ### - header = Signal(mac_header_length*8) - header_reg = Signal(mac_header_length*8) - load = Signal() - shift = Signal() - counter = Counter(max=mac_header_length) - self.submodules += counter - - self.comb += header.eq(_encode_header(mac_header, header, sink)) - self.sync += [ - If(load, - header_reg.eq(header) - ).Elif(shift, - header_reg.eq(Cat(header_reg[8:], Signal(8))) - ) - ] - - fsm = FSM(reset_state="IDLE") - self.submodules += fsm - - fsm.act("IDLE", - sink.ack.eq(1), - If(sink.stb & sink.sop, - load.eq(1), - sink.ack.eq(0), - source.stb.eq(1), - source.sop.eq(1), - source.eop.eq(0), - source.data.eq(header[:8]), - If(source.stb & source.ack, - NextState("SEND_HEADER"), - ) - ) - ) - fsm.act("SEND_HEADER", - source.stb.eq(1), - source.sop.eq(0), - source.eop.eq(sink.eop), - source.data.eq(header_reg[8:16]), - If(source.stb & source.ack, - sink.ack.eq(1), - If(counter == mac_header_length-2, - NextState("COPY") - ) - ) - ) - fsm.act("COPY", - source.stb.eq(sink.stb), - source.sop.eq(0), - source.eop.eq(sink_eop), - source.data.eq(sink.data), - source.error.eq(sink.error), - If(source.stb & source.ack, - sink.ack.eq(1), - If(source.eop, - NextState("IDLE") - ) - ) - ) diff --git a/liteeth/test/mac_core_tb.py b/liteeth/test/mac_core_tb.py index 810390dc..fe1e4285 100644 --- a/liteeth/test/mac_core_tb.py +++ b/liteeth/test/mac_core_tb.py @@ -15,11 +15,11 @@ class TB(Module): self.submodules.hostmac = mac.MAC(self.hostphy, debug=False, loopback=True) self.submodules.ethmac = LiteEthMAC(phy=self.hostphy, dw=32, interface="core", with_hw_preamble_crc=True) - self.submodules.streamer = PacketStreamer(eth_mac_description(32), last_be=1) - self.submodules.streamer_randomizer = AckRandomizer(eth_mac_description(32), level=50) + self.submodules.streamer = PacketStreamer(eth_phy_description(32), last_be=1) + self.submodules.streamer_randomizer = AckRandomizer(eth_phy_description(32), level=50) - self.submodules.logger_randomizer = AckRandomizer(eth_mac_description(32), level=50) - self.submodules.logger = PacketLogger(eth_mac_description(32)) + self.submodules.logger_randomizer = AckRandomizer(eth_phy_description(32), level=50) + self.submodules.logger = PacketLogger(eth_phy_description(32)) # use sys_clk for each clock_domain self.clock_domains.cd_eth_rx = ClockDomain() diff --git a/liteeth/udp/__init__.py b/liteeth/udp/__init__.py index e69de29b..9f8b5daf 100644 --- a/liteeth/udp/__init__.py +++ b/liteeth/udp/__init__.py @@ -0,0 +1,19 @@ +from liteeth.common import * +from liteeth.generic.depacketizer import LiteEthDepacketizer +from liteeth.generic.packetizer import LiteEthPacketizer + +class LiteEthUDPDepacketizer(LiteEthDepacketizer): + def __init__(self): + LiteEthDepacketizer.__init__(self, + eth_ipv4_description(8), + eth_udp_description(8), + udp_header, + udp_header_length) + +class LiteEthUDPPacketizer(LiteEthDepacketizer): + def __init__(self): + LiteEthDepacketizer.__init__(self, + eth_udp_description(8), + eth_ipv4_description(8), + udp_header, + udp_header_length)