From: Florent Kermarrec Date: Mon, 27 Apr 2015 13:06:37 +0000 (+0200) Subject: liteeth: use new Migen modules from actorlib (avoid duplications between cores) X-Git-Tag: 24jan2021_ls180~2293 X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=91c77d464c1d6dca9b8e7b1d0ee57059fe0711a1;p=litex.git liteeth: use new Migen modules from actorlib (avoid duplications between cores) --- diff --git a/misoclib/com/liteeth/common.py b/misoclib/com/liteeth/common.py index fb109a7f..0bc1b01c 100644 --- a/misoclib/com/liteeth/common.py +++ b/misoclib/com/liteeth/common.py @@ -5,11 +5,11 @@ from migen.fhdl.std import * from migen.genlib.resetsync import AsyncResetSynchronizer from migen.genlib.record import * from migen.genlib.fsm import FSM, NextState -from migen.genlib.misc import chooser, FlipFlop, Counter, Timeout +from migen.genlib.misc import chooser, reverse_bytes, FlipFlop, Counter, Timeout from migen.flow.actor import * -from migen.flow.plumbing import Buffer from migen.actorlib.structuring import Converter, Pipeline from migen.actorlib.fifo import SyncFIFO, AsyncFIFO +from migen.actorlib.packet import * from migen.bank.description import * eth_mtu = 1532 @@ -18,121 +18,123 @@ eth_interpacket_gap = 12 eth_preamble = 0xD555555555555555 buffer_depth = 2**log2_int(eth_mtu, need_pow2=False) - -class HField(): - def __init__(self, byte, offset, width): - self.byte = byte - self.offset = offset - self.width = width - ethernet_type_ip = 0x800 ethernet_type_arp = 0x806 -mac_header_len = 14 -mac_header = { - "target_mac": HField(0, 0, 48), - "sender_mac": HField(6, 0, 48), - "ethernet_type": HField(12, 0, 16) +mac_header_length = 14 +mac_header_fields = { + "target_mac": HeaderField(0, 0, 48), + "sender_mac": HeaderField(6, 0, 48), + "ethernet_type": HeaderField(12, 0, 16) } +mac_header = Header(mac_header_fields, + mac_header_length, + swap_field_bytes=True) arp_hwtype_ethernet = 0x0001 arp_proto_ip = 0x0800 arp_opcode_request = 0x0001 arp_opcode_reply = 0x0002 -arp_header_len = 28 -arp_header = { - "hwtype": HField(0, 0, 16), - "proto": HField(2, 0, 16), - "hwsize": HField(4, 0, 8), - "protosize": HField(5, 0, 8), - "opcode": HField(6, 0, 16), - "sender_mac": HField(8, 0, 48), - "sender_ip": HField(14, 0, 32), - "target_mac": HField(18, 0, 48), - "target_ip": HField(24, 0, 32) +arp_header_length = 28 +arp_header_fields = { + "hwtype": HeaderField(0, 0, 16), + "proto": HeaderField(2, 0, 16), + "hwsize": HeaderField(4, 0, 8), + "protosize": HeaderField(5, 0, 8), + "opcode": HeaderField(6, 0, 16), + "sender_mac": HeaderField(8, 0, 48), + "sender_ip": HeaderField(14, 0, 32), + "target_mac": HeaderField(18, 0, 48), + "target_ip": HeaderField(24, 0, 32) } - -ipv4_header_len = 20 -ipv4_header = { - "ihl": HField(0, 0, 4), - "version": HField(0, 4, 4), - "total_length": HField(2, 0, 16), - "identification": HField(4, 0, 16), - "ttl": HField(8, 0, 8), - "protocol": HField(9, 0, 8), - "checksum": HField(10, 0, 16), - "sender_ip": HField(12, 0, 32), - "target_ip": HField(16, 0, 32) +arp_header = Header(arp_header_fields, + arp_header_length, + swap_field_bytes=True) + + +ipv4_header_length = 20 +ipv4_header_fields = { + "ihl": HeaderField(0, 0, 4), + "version": HeaderField(0, 4, 4), + "total_length": HeaderField(2, 0, 16), + "identification": HeaderField(4, 0, 16), + "ttl": HeaderField(8, 0, 8), + "protocol": HeaderField(9, 0, 8), + "checksum": HeaderField(10, 0, 16), + "sender_ip": HeaderField(12, 0, 32), + "target_ip": HeaderField(16, 0, 32) } +ipv4_header = Header(ipv4_header_fields, + ipv4_header_length, + swap_field_bytes=True) -icmp_header_len = 8 -icmp_header = { - "msgtype": HField(0, 0, 8), - "code": HField(1, 0, 8), - "checksum": HField(2, 0, 16), - "quench": HField(4, 0, 32) -} icmp_protocol = 0x01 -udp_header_len = 8 -udp_header = { - "src_port": HField(0, 0, 16), - "dst_port": HField(2, 0, 16), - "length": HField(4, 0, 16), - "checksum": HField(6, 0, 16) +icmp_header_length = 8 +icmp_header_fields = { + "msgtype": HeaderField(0, 0, 8), + "code": HeaderField(1, 0, 8), + "checksum": HeaderField(2, 0, 16), + "quench": HeaderField(4, 0, 32) } +icmp_header = Header(icmp_header_fields, + icmp_header_length, + swap_field_bytes=True) udp_protocol = 0x11 +udp_header_length = 8 +udp_header_fields = { + "src_port": HeaderField(0, 0, 16), + "dst_port": HeaderField(2, 0, 16), + "length": HeaderField(4, 0, 16), + "checksum": HeaderField(6, 0, 16) +} +udp_header = Header(udp_header_fields, + udp_header_length, + swap_field_bytes=True) + + etherbone_magic = 0x4e6f etherbone_version = 1 -etherbone_packet_header_len = 8 -etherbone_packet_header = { - "magic": HField(0, 0, 16), +etherbone_packet_header_length = 8 +etherbone_packet_header_fields = { + "magic": HeaderField(0, 0, 16), - "version": HField(2, 4, 4), - "nr": HField(2, 2, 1), - "pr": HField(2, 1, 1), - "pf": HField(2, 0, 1), + "version": HeaderField(2, 4, 4), + "nr": HeaderField(2, 2, 1), + "pr": HeaderField(2, 1, 1), + "pf": HeaderField(2, 0, 1), - "addr_size": HField(3, 4, 4), - "port_size": HField(3, 0, 4) + "addr_size": HeaderField(3, 4, 4), + "port_size": HeaderField(3, 0, 4) } +etherbone_packet_header = Header(etherbone_packet_header_fields, + etherbone_packet_header_length, + swap_field_bytes=True) -etherbone_record_header_len = 4 -etherbone_record_header = { - "bca": HField(0, 0, 1), - "rca": HField(0, 1, 1), - "rff": HField(0, 2, 1), - "cyc": HField(0, 4, 1), - "wca": HField(0, 5, 1), - "wff": HField(0, 6, 1), +etherbone_record_header_length = 4 +etherbone_record_header_fields = { + "bca": HeaderField(0, 0, 1), + "rca": HeaderField(0, 1, 1), + "rff": HeaderField(0, 2, 1), + "cyc": HeaderField(0, 4, 1), + "wca": HeaderField(0, 5, 1), + "wff": HeaderField(0, 6, 1), - "byte_enable": HField(1, 0, 8), + "byte_enable": HeaderField(1, 0, 8), - "wcount": HField(2, 0, 8), + "wcount": HeaderField(2, 0, 8), - "rcount": HField(3, 0, 8) + "rcount": HeaderField(3, 0, 8) } - - -def reverse_bytes(v): - n = math.ceil(flen(v)/8) - r = [] - for i in reversed(range(n)): - r.append(v[i*8:min((i+1)*8, flen(v))]) - return Cat(iter(r)) +etherbone_record_header = Header(etherbone_record_header_fields, + etherbone_record_header_length, + swap_field_bytes=True) # layouts -def _layout_from_header(header): - _layout = [] - for k, v in sorted(header.items()): - _layout.append((k, v.width)) - return _layout - - def _remove_from_layout(layout, *args): r = [] for f in layout: @@ -155,7 +157,7 @@ def eth_phy_description(dw): def eth_mac_description(dw): - payload_layout = _layout_from_header(mac_header) + [ + payload_layout = mac_header.get_layout() + [ ("data", dw), ("last_be", dw//8), ("error", dw//8) @@ -164,7 +166,7 @@ def eth_mac_description(dw): def eth_arp_description(dw): - param_layout = _layout_from_header(arp_header) + param_layout = arp_header.get_layout() payload_layout = [ ("data", dw), ("error", dw//8) @@ -182,7 +184,7 @@ arp_table_response_layout = [ def eth_ipv4_description(dw): - param_layout = _layout_from_header(ipv4_header) + param_layout = ipv4_header.get_layout() payload_layout = [ ("data", dw), ("error", dw//8) @@ -212,7 +214,7 @@ def convert_ip(s): def eth_icmp_description(dw): - param_layout = _layout_from_header(icmp_header) + param_layout = icmp_header.get_layout() payload_layout = [ ("data", dw), ("error", dw//8) @@ -221,7 +223,7 @@ def eth_icmp_description(dw): def eth_icmp_user_description(dw): - param_layout = _layout_from_header(icmp_header) + [ + param_layout = icmp_header.get_layout() + [ ("ip_address", 32), ("length", 16) ] @@ -233,7 +235,7 @@ def eth_icmp_user_description(dw): def eth_udp_description(dw): - param_layout = _layout_from_header(udp_header) + param_layout = udp_header.get_layout() payload_layout = [ ("data", dw), ("error", dw//8) @@ -256,7 +258,7 @@ def eth_udp_user_description(dw): def eth_etherbone_packet_description(dw): - param_layout = _layout_from_header(etherbone_packet_header) + param_layout = etherbone_packet_header.get_layout() payload_layout = [ ("data", dw), ("error", dw//8) @@ -265,7 +267,7 @@ def eth_etherbone_packet_description(dw): def eth_etherbone_packet_user_description(dw): - param_layout = _layout_from_header(etherbone_packet_header) + param_layout = etherbone_packet_header.get_layout() param_layout = _remove_from_layout(param_layout, "magic", "portsize", @@ -280,7 +282,7 @@ def eth_etherbone_packet_user_description(dw): def eth_etherbone_record_description(dw): - param_layout = _layout_from_header(etherbone_record_header) + param_layout = etherbone_record_header.get_layout() payload_layout = [ ("data", dw), ("error", dw//8) diff --git a/misoclib/com/liteeth/core/arp/__init__.py b/misoclib/com/liteeth/core/arp/__init__.py index e564248b..0c8b68a0 100644 --- a/misoclib/com/liteeth/core/arp/__init__.py +++ b/misoclib/com/liteeth/core/arp/__init__.py @@ -16,8 +16,7 @@ class LiteEthARPPacketizer(LiteEthPacketizer): LiteEthPacketizer.__init__(self, eth_arp_description(8), eth_mac_description(8), - arp_header, - arp_header_len) + arp_header) class LiteEthARPTX(Module): @@ -29,7 +28,7 @@ class LiteEthARPTX(Module): self.submodules.packetizer = packetizer = LiteEthARPPacketizer() - counter = Counter(max=max(arp_header_len, eth_min_len)) + counter = Counter(max=max(arp_header.length, eth_min_len)) self.submodules += counter self.submodules.fsm = fsm = FSM(reset_state="IDLE") @@ -43,7 +42,7 @@ class LiteEthARPTX(Module): ) self.comb += [ packetizer.sink.sop.eq(counter.value == 0), - packetizer.sink.eop.eq(counter.value == max(arp_header_len, eth_min_len)-1), + packetizer.sink.eop.eq(counter.value == max(arp_header.length, eth_min_len)-1), packetizer.sink.hwtype.eq(arp_hwtype_ethernet), packetizer.sink.proto.eq(arp_proto_ip), packetizer.sink.hwsize.eq(6), @@ -82,8 +81,7 @@ class LiteEthARPDepacketizer(LiteEthDepacketizer): LiteEthDepacketizer.__init__(self, eth_mac_description(8), eth_arp_description(8), - arp_header, - arp_header_len) + arp_header) class LiteEthARPRX(Module): diff --git a/misoclib/com/liteeth/core/etherbone/__init__.py b/misoclib/com/liteeth/core/etherbone/__init__.py index 4b622a73..3c7d6f9a 100644 --- a/misoclib/com/liteeth/core/etherbone/__init__.py +++ b/misoclib/com/liteeth/core/etherbone/__init__.py @@ -1,7 +1,5 @@ from misoclib.com.liteeth.common import * from misoclib.com.liteeth.generic import * -from misoclib.com.liteeth.generic.arbiter import Arbiter -from misoclib.com.liteeth.generic.dispatcher import Dispatcher from misoclib.com.liteeth.core.etherbone.packet import * from misoclib.com.liteeth.core.etherbone.probe import * from misoclib.com.liteeth.core.etherbone.record import * diff --git a/misoclib/com/liteeth/core/etherbone/packet.py b/misoclib/com/liteeth/core/etherbone/packet.py index ecd7dc45..2a236d57 100644 --- a/misoclib/com/liteeth/core/etherbone/packet.py +++ b/misoclib/com/liteeth/core/etherbone/packet.py @@ -9,8 +9,7 @@ class LiteEthEtherbonePacketPacketizer(LiteEthPacketizer): LiteEthPacketizer.__init__(self, eth_etherbone_packet_description(32), eth_udp_user_description(32), - etherbone_packet_header, - etherbone_packet_header_len) + etherbone_packet_header) class LiteEthEtherbonePacketTX(Module): @@ -50,7 +49,7 @@ class LiteEthEtherbonePacketTX(Module): source.src_port.eq(udp_port), source.dst_port.eq(udp_port), source.ip_address.eq(sink.ip_address), - source.length.eq(sink.length + etherbone_packet_header_len), + source.length.eq(sink.length + etherbone_packet_header.length), If(source.stb & source.eop & source.ack, NextState("IDLE") ) @@ -62,8 +61,7 @@ class LiteEthEtherbonePacketDepacketizer(LiteEthDepacketizer): LiteEthDepacketizer.__init__(self, eth_udp_user_description(32), eth_etherbone_packet_description(32), - etherbone_packet_header, - etherbone_packet_header_len) + etherbone_packet_header) class LiteEthEtherbonePacketRX(Module): @@ -109,7 +107,7 @@ class LiteEthEtherbonePacketRX(Module): source.src_port.eq(sink.src_port), source.dst_port.eq(sink.dst_port), source.ip_address.eq(sink.ip_address), - source.length.eq(sink.length - etherbone_packet_header_len) + source.length.eq(sink.length - etherbone_packet_header.length) ] fsm.act("PRESENT", source.stb.eq(depacketizer.source.stb), diff --git a/misoclib/com/liteeth/core/etherbone/record.py b/misoclib/com/liteeth/core/etherbone/record.py index eb75a029..263234c4 100644 --- a/misoclib/com/liteeth/core/etherbone/record.py +++ b/misoclib/com/liteeth/core/etherbone/record.py @@ -9,8 +9,7 @@ class LiteEthEtherboneRecordPacketizer(LiteEthPacketizer): LiteEthPacketizer.__init__(self, eth_etherbone_record_description(32), eth_etherbone_packet_user_description(32), - etherbone_record_header, - etherbone_record_header_len) + etherbone_record_header) class LiteEthEtherboneRecordDepacketizer(LiteEthDepacketizer): @@ -18,8 +17,7 @@ class LiteEthEtherboneRecordDepacketizer(LiteEthDepacketizer): LiteEthDepacketizer.__init__(self, eth_etherbone_packet_user_description(32), eth_etherbone_record_description(32), - etherbone_record_header, - etherbone_record_header_len) + etherbone_record_header) class LiteEthEtherboneRecordReceiver(Module): @@ -104,7 +102,7 @@ class LiteEthEtherboneRecordSender(Module): # # # - pbuffer = PacketBuffer(eth_etherbone_mmap_description(32), buffer_depth) + pbuffer = Buffer(eth_etherbone_mmap_description(32), buffer_depth) self.submodules += pbuffer self.comb += Record.connect(sink, pbuffer.sink) @@ -181,7 +179,7 @@ class LiteEthEtherboneRecord(Module): Record.connect(sender.source, packetizer.sink), Record.connect(packetizer.source, source), # XXX improve this - source.length.eq(sender.source.wcount*4 + 4 + etherbone_record_header_len), + source.length.eq(sender.source.wcount*4 + 4 + etherbone_record_header.length), source.ip_address.eq(last_ip_address) ] if endianness is "big": diff --git a/misoclib/com/liteeth/core/icmp/__init__.py b/misoclib/com/liteeth/core/icmp/__init__.py index e3f1a3aa..e1ddeee8 100644 --- a/misoclib/com/liteeth/core/icmp/__init__.py +++ b/misoclib/com/liteeth/core/icmp/__init__.py @@ -9,8 +9,7 @@ class LiteEthICMPPacketizer(LiteEthPacketizer): LiteEthPacketizer.__init__(self, eth_icmp_description(8), eth_ipv4_user_description(8), - icmp_header, - icmp_header_len) + icmp_header) class LiteEthICMPTX(Module): @@ -43,7 +42,7 @@ class LiteEthICMPTX(Module): ) fsm.act("SEND", Record.connect(packetizer.source, source), - source.length.eq(sink.length + icmp_header_len), + source.length.eq(sink.length + icmp_header.length), source.protocol.eq(icmp_protocol), source.ip_address.eq(sink.ip_address), If(source.stb & source.eop & source.ack, @@ -57,8 +56,7 @@ class LiteEthICMPDepacketizer(LiteEthDepacketizer): LiteEthDepacketizer.__init__(self, eth_ipv4_user_description(8), eth_icmp_description(8), - icmp_header, - icmp_header_len) + icmp_header) class LiteEthICMPRX(Module): @@ -99,7 +97,7 @@ class LiteEthICMPRX(Module): source.checksum.eq(depacketizer.source.checksum), source.quench.eq(depacketizer.source.quench), source.ip_address.eq(sink.ip_address), - source.length.eq(sink.length - icmp_header_len), + source.length.eq(sink.length - icmp_header.length), source.data.eq(depacketizer.source.data), source.error.eq(depacketizer.source.error) ] @@ -127,7 +125,7 @@ class LiteEthICMPEcho(Module): # # # - self.submodules.buffer = PacketBuffer(eth_icmp_user_description(8), 128, 2) + self.submodules.buffer = Buffer(eth_icmp_user_description(8), 128, 2) self.comb += [ Record.connect(sink, self.buffer.sink), Record.connect(self.buffer.source, source), diff --git a/misoclib/com/liteeth/core/ip/__init__.py b/misoclib/com/liteeth/core/ip/__init__.py index 72d70423..88a2f3cd 100644 --- a/misoclib/com/liteeth/core/ip/__init__.py +++ b/misoclib/com/liteeth/core/ip/__init__.py @@ -11,8 +11,7 @@ class LiteEthIPV4Packetizer(LiteEthPacketizer): LiteEthPacketizer.__init__(self, eth_ipv4_description(8), eth_mac_description(8), - ipv4_header, - ipv4_header_len) + ipv4_header) class LiteEthIPTX(Module): @@ -104,8 +103,7 @@ class LiteEthIPV4Depacketizer(LiteEthDepacketizer): LiteEthDepacketizer.__init__(self, eth_mac_description(8), eth_ipv4_description(8), - ipv4_header, - ipv4_header_len) + ipv4_header) class LiteEthIPRX(Module): diff --git a/misoclib/com/liteeth/core/ip/checksum.py b/misoclib/com/liteeth/core/ip/checksum.py index dce3e014..266713b6 100644 --- a/misoclib/com/liteeth/core/ip/checksum.py +++ b/misoclib/com/liteeth/core/ip/checksum.py @@ -6,7 +6,7 @@ class LiteEthIPV4Checksum(Module): def __init__(self, words_per_clock_cycle=1, skip_checksum=False): self.reset = Signal() # XXX FIXME InsertReset generates incorrect verilog self.ce = Signal() # XXX FIXME InsertCE generates incorrect verilog - self.header = Signal(ipv4_header_len*8) + self.header = Signal(ipv4_header.length*8) self.value = Signal(16) self.done = Signal() @@ -15,8 +15,8 @@ class LiteEthIPV4Checksum(Module): s = Signal(17) r = Signal(17) n_cycles = 0 - for i in range(ipv4_header_len//2): - if skip_checksum and (i == ipv4_header["checksum"].byte//2): + for i in range(ipv4_header.length//2): + if skip_checksum and (i == ipv4_header.fields["checksum"].byte//2): pass else: s_next = Signal(17) diff --git a/misoclib/com/liteeth/core/udp/__init__.py b/misoclib/com/liteeth/core/udp/__init__.py index 7cadbddc..20bd9ec6 100644 --- a/misoclib/com/liteeth/core/udp/__init__.py +++ b/misoclib/com/liteeth/core/udp/__init__.py @@ -10,8 +10,7 @@ class LiteEthUDPPacketizer(LiteEthPacketizer): LiteEthPacketizer.__init__(self, eth_udp_description(8), eth_ipv4_user_description(8), - udp_header, - udp_header_len) + udp_header) class LiteEthUDPTX(Module): @@ -29,7 +28,7 @@ class LiteEthUDPTX(Module): sink.ack.eq(packetizer.sink.ack), packetizer.sink.src_port.eq(sink.src_port), packetizer.sink.dst_port.eq(sink.dst_port), - packetizer.sink.length.eq(sink.length + udp_header_len), + packetizer.sink.length.eq(sink.length + udp_header.length), packetizer.sink.checksum.eq(0), # Disabled (MAC CRC is enough) packetizer.sink.data.eq(sink.data) ] @@ -58,8 +57,7 @@ class LiteEthUDPDepacketizer(LiteEthDepacketizer): LiteEthDepacketizer.__init__(self, eth_ipv4_user_description(8), eth_udp_description(8), - udp_header, - udp_header_len) + udp_header) class LiteEthUDPRX(Module): @@ -99,7 +97,7 @@ class LiteEthUDPRX(Module): source.src_port.eq(depacketizer.source.src_port), source.dst_port.eq(depacketizer.source.dst_port), source.ip_address.eq(sink.ip_address), - source.length.eq(depacketizer.source.length - udp_header_len), + source.length.eq(depacketizer.source.length - udp_header.length), source.data.eq(depacketizer.source.data), source.error.eq(depacketizer.source.error) ] diff --git a/misoclib/com/liteeth/example_designs/targets/udp.py b/misoclib/com/liteeth/example_designs/targets/udp.py index 76f13990..9aea0c23 100644 --- a/misoclib/com/liteeth/example_designs/targets/udp.py +++ b/misoclib/com/liteeth/example_designs/targets/udp.py @@ -22,7 +22,7 @@ class UDPSoC(BaseSoC): def add_udp_loopback(self, port, dw, depth, name=None): port = self.core.udp.crossbar.get_port(port, dw) - buf = PacketBuffer(eth_udp_user_description(dw), depth//(dw//8), 8) + buf = Buffer(eth_udp_user_description(dw), depth//(dw//8), 8) if name is None: self.submodules += buf else: diff --git a/misoclib/com/liteeth/generic/__init__.py b/misoclib/com/liteeth/generic/__init__.py index db1aea0f..71d0d077 100644 --- a/misoclib/com/liteeth/generic/__init__.py +++ b/misoclib/com/liteeth/generic/__init__.py @@ -10,120 +10,3 @@ class Port: Record.connect(port.source, self.sink) ] return r - - -# Generic modules -class BufferizeEndpoints(ModuleTransformer): - def __init__(self, *names): - self.names = names - - def transform_instance(self, submodule): - endpoints = get_endpoints(submodule) - sinks = {} - sources = {} - for name, endpoint in endpoints.items(): - if not self.names or name in self.names: - if isinstance(endpoint, Sink): - sinks.update({name: endpoint}) - elif isinstance(endpoint, Source): - sources.update({name: endpoint}) - - # add buffer on sinks - for name, sink in sinks.items(): - buf = Buffer(sink.description) - submodule.submodules += buf - setattr(self, name, buf.d) - submodule.comb += Record.connect(buf.q, sink) - - # add buffer on sources - for name, source in sources.items(): - buf = Buffer(source.description) - submodule.submodules += buf - submodule.comb += Record.connect(source, buf.d) - setattr(self, name, buf.q) - - -class EndpointPacketStatus(Module): - def __init__(self, endpoint): - self.start = Signal() - self.done = Signal() - self.ongoing = Signal() - - ongoing = Signal() - self.comb += [ - self.start.eq(endpoint.stb & endpoint.sop & endpoint.ack), - self.done.eq(endpoint.stb & endpoint.eop & endpoint.ack) - ] - self.sync += \ - If(self.start, - ongoing.eq(1) - ).Elif(self.done, - ongoing.eq(0) - ) - self.comb += self.ongoing.eq((self.start | ongoing) & ~self.done) - - -class PacketBuffer(Module): - def __init__(self, description, data_depth, cmd_depth=4, almost_full=None): - self.sink = sink = Sink(description) - self.source = source = Source(description) - - # # # - - sink_status = EndpointPacketStatus(self.sink) - source_status = EndpointPacketStatus(self.source) - self.submodules += sink_status, source_status - - # store incoming packets - # cmds - def cmd_description(): - layout = [("error", 1)] - return EndpointDescription(layout) - cmd_fifo = SyncFIFO(cmd_description(), cmd_depth) - self.submodules += cmd_fifo - self.comb += cmd_fifo.sink.stb.eq(sink_status.done) - if hasattr(sink, "error"): - self.comb += cmd_fifo.sink.error.eq(sink.error) - - # data - data_fifo = SyncFIFO(description, data_depth, buffered=True) - self.submodules += data_fifo - self.comb += [ - Record.connect(self.sink, data_fifo.sink), - data_fifo.sink.stb.eq(self.sink.stb & cmd_fifo.sink.ack), - self.sink.ack.eq(data_fifo.sink.ack & cmd_fifo.sink.ack), - ] - - # output packets - self.fsm = fsm = FSM(reset_state="IDLE") - self.submodules += fsm - fsm.act("IDLE", - If(cmd_fifo.source.stb, - NextState("SEEK_SOP") - ) - ) - fsm.act("SEEK_SOP", - If(~data_fifo.source.sop, - data_fifo.source.ack.eq(1) - ).Else( - NextState("OUTPUT") - ) - ) - if hasattr(source, "error"): - source_error = self.source.error - else: - source_error = Signal() - - fsm.act("OUTPUT", - Record.connect(data_fifo.source, self.source), - source_error.eq(cmd_fifo.source.error), - If(source_status.done, - cmd_fifo.source.ack.eq(1), - NextState("IDLE") - ) - ) - - # compute almost full - if almost_full is not None: - self.almost_full = Signal() - self.comb += self.almost_full.eq(data_fifo.fifo.level > almost_full) diff --git a/misoclib/com/liteeth/generic/arbiter.py b/misoclib/com/liteeth/generic/arbiter.py deleted file mode 100644 index cb6503b0..00000000 --- a/misoclib/com/liteeth/generic/arbiter.py +++ /dev/null @@ -1,28 +0,0 @@ -from migen.fhdl.std import * -from migen.genlib.roundrobin import * -from migen.genlib.record import * - - -class Arbiter(Module): - def __init__(self, sources, sink): - if len(sources) == 0: - pass - elif len(sources) == 1: - self.grant = Signal() - self.comb += Record.connect(sources.pop(), sink) - else: - self.submodules.rr = RoundRobin(len(sources)) - self.grant = self.rr.grant - cases = {} - for i, source in enumerate(sources): - sop = Signal() - eop = Signal() - ongoing = Signal() - self.comb += [ - sop.eq(source.stb & source.sop), - eop.eq(source.stb & source.eop & source.ack), - ] - self.sync += ongoing.eq((sop | ongoing) & ~eop) - self.comb += self.rr.request[i].eq((sop | ongoing) & ~eop) - cases[i] = [Record.connect(source, sink)] - self.comb += Case(self.grant, cases) diff --git a/misoclib/com/liteeth/generic/crossbar.py b/misoclib/com/liteeth/generic/crossbar.py index 3965db4f..abde85b3 100644 --- a/misoclib/com/liteeth/generic/crossbar.py +++ b/misoclib/com/liteeth/generic/crossbar.py @@ -2,8 +2,6 @@ from collections import OrderedDict from misoclib.com.liteeth.common import * from misoclib.com.liteeth.generic import * -from misoclib.com.liteeth.generic.arbiter import Arbiter -from misoclib.com.liteeth.generic.dispatcher import Dispatcher class LiteEthCrossbar(Module): diff --git a/misoclib/com/liteeth/generic/depacketizer.py b/misoclib/com/liteeth/generic/depacketizer.py index 85dec05b..20a85bb0 100644 --- a/misoclib/com/liteeth/generic/depacketizer.py +++ b/misoclib/com/liteeth/generic/depacketizer.py @@ -2,26 +2,17 @@ from misoclib.com.liteeth.common import * from misoclib.com.liteeth.generic 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(reverse_bytes(h_signal[start:end]))) - return r - - class LiteEthDepacketizer(Module): - def __init__(self, sink_description, source_description, header_type, header_length): + def __init__(self, sink_description, source_description, header): self.sink = sink = Sink(sink_description) self.source = source = Source(source_description) - self.header = Signal(header_length*8) + self.header = Signal(header.length*8) # # # dw = flen(sink.data) - header_words = (header_length*8)//dw + header_words = (header.length*8)//dw shift = Signal() counter = Counter(max=max(header_words, 2)) @@ -77,7 +68,7 @@ class LiteEthDepacketizer(Module): source.eop.eq(sink.eop | no_payload), source.data.eq(sink.data), source.error.eq(sink.error), - _decode_header(header_type, self.header, source) + header.decode(self.header, source) ] fsm.act("COPY", sink.ack.eq(source.ack), diff --git a/misoclib/com/liteeth/generic/dispatcher.py b/misoclib/com/liteeth/generic/dispatcher.py deleted file mode 100644 index c11a41ac..00000000 --- a/misoclib/com/liteeth/generic/dispatcher.py +++ /dev/null @@ -1,42 +0,0 @@ -from migen.fhdl.std import * -from migen.genlib.record import * - - -class Dispatcher(Module): - def __init__(self, source, sinks, one_hot=False): - if len(sinks) == 0: - self.sel = Signal() - elif len(sinks) == 1: - self.comb += Record.connect(source, sinks.pop()) - self.sel = Signal() - else: - if one_hot: - self.sel = Signal(len(sinks)) - else: - self.sel = Signal(max=len(sinks)) - - # # # - - sop = Signal() - self.comb += sop.eq(source.stb & source.sop) - sel = Signal(flen(self.sel)) - sel_r = Signal(flen(self.sel)) - self.sync += \ - If(sop, - sel_r.eq(self.sel) - ) - self.comb += \ - If(sop, - sel.eq(self.sel) - ).Else( - sel.eq(sel_r) - ) - cases = {} - for i, sink in enumerate(sinks): - if one_hot: - idx = 2**i - else: - idx = i - cases[idx] = [Record.connect(source, sink)] - cases["default"] = [source.ack.eq(1)] - self.comb += Case(sel, cases) diff --git a/misoclib/com/liteeth/generic/packetizer.py b/misoclib/com/liteeth/generic/packetizer.py index 2088486a..23a83c2a 100644 --- a/misoclib/com/liteeth/generic/packetizer.py +++ b/misoclib/com/liteeth/generic/packetizer.py @@ -2,33 +2,24 @@ from misoclib.com.liteeth.common import * from misoclib.com.liteeth.generic import * -def _encode_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(h_signal[start:end].eq(reverse_bytes(getattr(obj, k)))) - return r - - class LiteEthPacketizer(Module): - def __init__(self, sink_description, source_description, header_type, header_length): + def __init__(self, sink_description, source_description, header): self.sink = sink = Sink(sink_description) self.source = source = Source(source_description) - self.header = Signal(header_length*8) + self.header = Signal(header.length*8) # # # dw = flen(self.sink.data) - header_reg = Signal(header_length*8) - header_words = (header_length*8)//dw + header_reg = Signal(header.length*8) + header_words = (header.length*8)//dw load = Signal() shift = Signal() counter = Counter(max=max(header_words, 2)) self.submodules += counter - self.comb += _encode_header(header_type, self.header, sink) + self.comb += header.encode(sink, self.header) if header_words == 1: self.sync += [ If(load, diff --git a/misoclib/com/liteeth/mac/common.py b/misoclib/com/liteeth/mac/common.py index d5a6d579..809ad4fb 100644 --- a/misoclib/com/liteeth/mac/common.py +++ b/misoclib/com/liteeth/mac/common.py @@ -10,8 +10,7 @@ class LiteEthMACDepacketizer(LiteEthDepacketizer): LiteEthDepacketizer.__init__(self, eth_phy_description(8), eth_mac_description(8), - mac_header, - mac_header_len) + mac_header) class LiteEthMACPacketizer(LiteEthPacketizer): @@ -19,8 +18,7 @@ class LiteEthMACPacketizer(LiteEthPacketizer): LiteEthPacketizer.__init__(self, eth_mac_description(8), eth_phy_description(8), - mac_header, - mac_header_len) + mac_header) class LiteEthMACMasterPort: diff --git a/misoclib/com/liteeth/test/model/arp.py b/misoclib/com/liteeth/test/model/arp.py index 31aab2ec..9a58fea6 100644 --- a/misoclib/com/liteeth/test/model/arp.py +++ b/misoclib/com/liteeth/test/model/arp.py @@ -19,24 +19,24 @@ class ARPPacket(Packet): def decode(self): header = [] - for byte in self[:arp_header_len]: + for byte in self[:arp_header.length]: header.append(self.pop(0)) - for k, v in sorted(arp_header.items()): + for k, v in sorted(arp_header.fields.items()): setattr(self, k, get_field_data(v, header)) def encode(self): header = 0 - for k, v in sorted(arp_header.items()): + for k, v in sorted(arp_header.fields.items()): value = merge_bytes(split_bytes(getattr(self, k), math.ceil(v.width/8)), "little") header += (value << v.offset+(v.byte*8)) - for d in split_bytes(header, arp_header_len): + for d in split_bytes(header, arp_header.length): self.insert(0, d) def __repr__(self): r = "--------\n" - for k in sorted(arp_header.keys()): + for k in sorted(arp_header.fields.keys()): r += k + " : 0x{:0x}\n".format(getattr(self, k)) r += "payload: " for d in self: @@ -78,7 +78,7 @@ class ARP(Module): self.process(packet) def process(self, packet): - if len(packet) != eth_min_len-arp_header_len: + if len(packet) != eth_min_len-arp_header.length: raise ValueError if packet.hwtype != arp_hwtype_ethernet: raise ValueError @@ -95,7 +95,7 @@ class ARP(Module): def process_request(self, request): if request.target_ip == self.ip_address: - reply = ARPPacket([0]*(eth_min_len-arp_header_len)) + reply = ARPPacket([0]*(eth_min_len-arp_header.length)) reply.hwtype = arp_hwtype_ethernet reply.proto = arp_proto_ip reply.opcode = arp_opcode_reply @@ -111,7 +111,7 @@ class ARP(Module): self.table[reply.sender_ip] = reply.sender_mac def request(self, ip_address): - request = ARPPacket([0]*(eth_min_len-arp_header_len)) + request = ARPPacket([0]*(eth_min_len-arp_header.length)) request.hwtype = arp_hwtype_ethernet request.proto = arp_proto_ip request.opcode = arp_opcode_request diff --git a/misoclib/com/liteeth/test/model/etherbone.py b/misoclib/com/liteeth/test/model/etherbone.py index aa4af60f..4f3f558f 100644 --- a/misoclib/com/liteeth/test/model/etherbone.py +++ b/misoclib/com/liteeth/test/model/etherbone.py @@ -161,9 +161,9 @@ class EtherboneRecord(Packet): if not self.encoded: raise ValueError header = [] - for byte in self[:etherbone_record_header_len]: + for byte in self[:etherbone_record_header.length]: header.append(self.pop(0)) - for k, v in sorted(etherbone_record_header.items()): + for k, v in sorted(etherbone_record_header.fields.items()): setattr(self, k, get_field_data(v, header)) self.writes = self.get_writes() if self.writes is not None: @@ -193,12 +193,12 @@ class EtherboneRecord(Packet): if self.reads is not None: self.set_reads(self.reads) header = 0 - for k, v in sorted(etherbone_record_header.items()): + for k, v in sorted(etherbone_record_header.fields.items()): value = merge_bytes(split_bytes(getattr(self, k), math.ceil(v.width/8)), "little") header += (value << v.offset+(v.byte*8)) - for d in split_bytes(header, etherbone_record_header_len): + for d in split_bytes(header, etherbone_record_header.length): self.insert(0, d) self.encoded = True @@ -209,7 +209,7 @@ class EtherboneRecord(Packet): for d in self: r += "{:02x}".format(d) else: - for k in sorted(etherbone_record_header.keys()): + for k in sorted(etherbone_record_header.fields.keys()): r += k + " : 0x{:0x}\n".format(getattr(self, k)) if self.wcount != 0: r += self.writes.__repr__() @@ -247,9 +247,9 @@ class EtherbonePacket(Packet): if not self.encoded: raise ValueError header = [] - for byte in self[:etherbone_packet_header_len]: + for byte in self[:etherbone_packet_header.length]: header.append(self.pop(0)) - for k, v in sorted(etherbone_packet_header.items()): + for k, v in sorted(etherbone_packet_header.fields.items()): setattr(self, k, get_field_data(v, header)) self.records = self.get_records() self.encoded = False @@ -265,10 +265,10 @@ class EtherbonePacket(Packet): raise ValueError self.set_records(self.records) header = 0 - for k, v in sorted(etherbone_packet_header.items()): + for k, v in sorted(etherbone_packet_header.fields.items()): value = merge_bytes(split_bytes(getattr(self, k), math.ceil(v.width/8)), "little") header += (value << v.offset+(v.byte*8)) - for d in split_bytes(header, etherbone_packet_header_len): + for d in split_bytes(header, etherbone_packet_header.length): self.insert(0, d) self.encoded = True @@ -279,7 +279,7 @@ class EtherbonePacket(Packet): for d in self: r += "{:02x}".format(d) else: - for k in sorted(etherbone_packet_header.keys()): + for k in sorted(etherbone_packet_header.fields.keys()): r += k + " : 0x{:0x}\n".format(getattr(self, k)) for i, record in enumerate(self.records): r += record.__repr__(i) diff --git a/misoclib/com/liteeth/test/model/icmp.py b/misoclib/com/liteeth/test/model/icmp.py index 36975f82..48dc073c 100644 --- a/misoclib/com/liteeth/test/model/icmp.py +++ b/misoclib/com/liteeth/test/model/icmp.py @@ -17,24 +17,24 @@ class ICMPPacket(Packet): def decode(self): header = [] - for byte in self[:icmp_header_len]: + for byte in self[:icmp_header.length]: header.append(self.pop(0)) - for k, v in sorted(icmp_header.items()): + for k, v in sorted(icmp_header.fields.items()): setattr(self, k, get_field_data(v, header)) def encode(self): header = 0 - for k, v in sorted(icmp_header.items()): + for k, v in sorted(icmp_header.fields.items()): value = merge_bytes(split_bytes(getattr(self, k), math.ceil(v.width/8)), "little") header += (value << v.offset+(v.byte*8)) - for d in split_bytes(header, icmp_header_len): + for d in split_bytes(header, icmp_header.length): self.insert(0, d) def __repr__(self): r = "--------\n" - for k in sorted(icmp_header.keys()): + for k in sorted(icmp_header.fields.keys()): r += k + " : 0x{:0x}\n".format(getattr(self, k)) r += "payload: " for d in self: diff --git a/misoclib/com/liteeth/test/model/ip.py b/misoclib/com/liteeth/test/model/ip.py index c2a1f67b..6703087f 100644 --- a/misoclib/com/liteeth/test/model/ip.py +++ b/misoclib/com/liteeth/test/model/ip.py @@ -32,35 +32,35 @@ class IPPacket(Packet): return self[10] | (self[11] << 8) def check_checksum(self): - return checksum(self[:ipv4_header_len]) == 0 + return checksum(self[:ipv4_header.length]) == 0 def decode(self): header = [] - for byte in self[:ipv4_header_len]: + for byte in self[:ipv4_header.length]: header.append(self.pop(0)) - for k, v in sorted(ipv4_header.items()): + for k, v in sorted(ipv4_header.fields.items()): setattr(self, k, get_field_data(v, header)) def encode(self): header = 0 - for k, v in sorted(ipv4_header.items()): + for k, v in sorted(ipv4_header.fields.items()): value = merge_bytes(split_bytes(getattr(self, k), math.ceil(v.width/8)), "little") header += (value << v.offset+(v.byte*8)) - for d in split_bytes(header, ipv4_header_len): + for d in split_bytes(header, ipv4_header.length): self.insert(0, d) def insert_checksum(self): self[10] = 0 self[11] = 0 - c = checksum(self[:ipv4_header_len]) + c = checksum(self[:ipv4_header.length]) self[10] = c & 0xff self[11] = (c >> 8) & 0xff def __repr__(self): r = "--------\n" - for k in sorted(ipv4_header.keys()): + for k in sorted(ipv4_header.fields.keys()): r += k + " : 0x{:0x}\n".format(getattr(self, k)) r += "payload: " for d in self: diff --git a/misoclib/com/liteeth/test/model/mac.py b/misoclib/com/liteeth/test/model/mac.py index 11177733..6697121e 100644 --- a/misoclib/com/liteeth/test/model/mac.py +++ b/misoclib/com/liteeth/test/model/mac.py @@ -44,9 +44,9 @@ class MACPacket(Packet): def decode_remove_header(self): header = [] - for byte in self[:mac_header_len]: + for byte in self[:mac_header.length]: header.append(self.pop(0)) - for k, v in sorted(mac_header.items()): + for k, v in sorted(mac_header.fields.items()): setattr(self, k, get_field_data(v, header)) def decode(self): @@ -59,12 +59,12 @@ class MACPacket(Packet): def encode_header(self): header = 0 - for k, v in sorted(mac_header.items()): + for k, v in sorted(mac_header.fields.items()): value = merge_bytes(split_bytes(getattr(self, k), math.ceil(v.width/8)), "little") header += (value << v.offset+(v.byte*8)) - for d in split_bytes(header, mac_header_len): + for d in split_bytes(header, mac_header.length): self.insert(0, d) def insert_crc(self): @@ -82,7 +82,7 @@ class MACPacket(Packet): def __repr__(self): r = "--------\n" - for k in sorted(mac_header.keys()): + for k in sorted(mac_header.fields.keys()): r += k + " : 0x{:0x}\n".format(getattr(self, k)) r += "payload: " for d in self: diff --git a/misoclib/com/liteeth/test/model/udp.py b/misoclib/com/liteeth/test/model/udp.py index f8242ec5..6c6a2bd5 100644 --- a/misoclib/com/liteeth/test/model/udp.py +++ b/misoclib/com/liteeth/test/model/udp.py @@ -17,24 +17,24 @@ class UDPPacket(Packet): def decode(self): header = [] - for byte in self[:udp_header_len]: + for byte in self[:udp_header.length]: header.append(self.pop(0)) - for k, v in sorted(udp_header.items()): + for k, v in sorted(udp_header.fields.items()): setattr(self, k, get_field_data(v, header)) def encode(self): header = 0 - for k, v in sorted(udp_header.items()): + for k, v in sorted(udp_header.fields.items()): value = merge_bytes(split_bytes(getattr(self, k), math.ceil(v.width/8)), "little") header += (value << v.offset+(v.byte*8)) - for d in split_bytes(header, udp_header_len): + for d in split_bytes(header, udp_header.length): self.insert(0, d) def __repr__(self): r = "--------\n" - for k in sorted(udp_header.keys()): + for k in sorted(udp_header.fields.keys()): r += k + " : 0x{:0x}\n".format(getattr(self, k)) r += "payload: " for d in self: @@ -109,13 +109,13 @@ if __name__ == "__main__": packet = UDPPacket(packet) packet.decode() # print(packet) - if packet.length != (len(packet)+udp_header_len): + if packet.length != (len(packet)+udp_header.length): errors += 1 errors += verify_packet(packet, udp_infos) packet.encode() packet.decode() # print(packet) - if packet.length != (len(packet)+udp_header_len): + if packet.length != (len(packet)+udp_header.length): errors += 1 errors += verify_packet(packet, udp_infos)