From: Florent Kermarrec Date: Thu, 29 Jan 2015 23:02:11 +0000 (+0100) Subject: model: add real dumps and test models with it X-Git-Tag: 24jan2021_ls180~2604^2~107 X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=08e83af62d980c3b6925e4c86322e2044e9dc6e2;p=litex.git model: add real dumps and test models with it --- diff --git a/liteeth/test/Makefile b/liteeth/test/Makefile index 974f1e57..7d2283c8 100644 --- a/liteeth/test/Makefile +++ b/liteeth/test/Makefile @@ -3,6 +3,10 @@ PYTHON = python3 CMD = PYTHONPATH=$(LEDIR) $(PYTHON) +model_tb: + $(CMD) ./model/mac.py + $(CMD) ./model/arp.py + mac_core_tb: $(CMD) mac_core_tb.py diff --git a/liteeth/test/common.py b/liteeth/test/common.py index 684be80a..496df5d8 100644 --- a/liteeth/test/common.py +++ b/liteeth/test/common.py @@ -19,15 +19,15 @@ def seed_to_data(seed, random=True): else: return seed -def split_bytes(v, n): +def split_bytes(v, n, endianness="big"): r = [] - r_bytes = v.to_bytes(n, byteorder="little") + r_bytes = v.to_bytes(n, byteorder=endianness) for byte in r_bytes: r.append(int(byte)) return r -def merge_bytes(b): - return int.from_bytes(bytes(b), "little") +def merge_bytes(b, endianness="big"): + return int.from_bytes(bytes(b), endianness) def get_field_data(field, datas): v = merge_bytes(datas[field.byte:field.byte+math.ceil(field.width/8)]) diff --git a/liteeth/test/model/arp.py b/liteeth/test/model/arp.py index e0a80f2c..ef4c2761 100644 --- a/liteeth/test/model/arp.py +++ b/liteeth/test/model/arp.py @@ -3,7 +3,6 @@ import math, binascii from liteeth.common import * from liteeth.mac.common import * from liteeth.test.common import * -from liteeth.test.mac import * def print_arp(s): print_with_prefix(s, "[ARP]") @@ -25,8 +24,9 @@ class ARPPacket(Packet): def encode(self): header = 0 for k, v in sorted(arp_header.items()): - header |= (getattr(self, k) << (v.byte*8+v.offset)) - for d in reversed(split_bytes(header, arp_header_len)): + 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): self.insert(0, d) def __repr__(self): @@ -84,7 +84,7 @@ class ARP(Module): self.process_reply(packet) def process_request(self, request): - if request.destination_ip_address = self.ip_address: + if request.destination_ip_address == self.ip_address: reply = ARPPacket([0]*(arp_packet_length-arp_header_length)) reply.hardware_type = arp_hwtype_ethernet reply.protocol_type = arp_proto_ip @@ -109,3 +109,37 @@ class ARP(Module): request.source_ip_address = self.ip_address request.destination_mac_address = 0xffffffffffff request.destination_ip_address = ip_address + +if __name__ == "__main__": + from liteeth.test.model.dumps import * + from liteeth.test.model.mac import * + errors = 0 + # ARP request + packet = MACPacket(arp_request) + packet.decode_remove_header() + packet = ARPPacket(packet) + # check decoding + packet.decode() + #print(packet) + errors += verify_packet(packet, arp_request_infos) + # check encoding + packet.encode() + packet.decode() + #print(packet) + errors += verify_packet(packet, arp_request_infos) + + # ARP Reply + packet = MACPacket(arp_reply) + packet.decode_remove_header() + packet = ARPPacket(packet) + # check decoding + packet.decode() + #print(packet) + errors += verify_packet(packet, arp_reply_infos) + # check encoding + packet.encode() + packet.decode() + #print(packet) + errors += verify_packet(packet, arp_reply_infos) + + print("arp errors " + str(errors)) \ No newline at end of file diff --git a/liteeth/test/model/dumps.py b/liteeth/test/model/dumps.py new file mode 100644 index 00000000..64684f5b --- /dev/null +++ b/liteeth/test/model/dumps.py @@ -0,0 +1,76 @@ +import re + +def format_dump(dump): + return [int(s, 16) for s in re.split(r'[;,\s\n]\s*', dump) if s is not ""] + +def verify_packet(packet, infos): + errors = 0 + for k, v in infos.items(): + if hasattr(packet, k): + if getattr(packet, k) != v: + print("[Error] " + k) + errors += 1 + return errors + +arp_request = format_dump(""" +00 22 19 22 54 9e 00 12 3f 97 92 01 08 06 00 01 +08 00 06 04 00 01 00 12 3f 97 92 01 a9 fe ff 42 +00 22 19 22 54 9e a9 fe 64 62""") + +arp_request_infos = { + "source_mac_address" : 0x00123f979201, + "destination_mac_address" : 0x00221922549e, + "ethernet_type" : 0x806, + "hardware_type" : 0x1, + "operation" : 0x1, + "protocol_address_length" : 0x4, + "protocol_type" : 0x800, + "source_ip_address" : 0xa9feff42, + "destination_ip_address" : 0xa9fe6462 + +} + +arp_reply = format_dump(""" +00 12 3f 97 92 01 00 22 19 22 54 9e 08 06 00 01 +08 00 06 04 00 02 00 22 19 22 54 9e a9 fe 64 62 +00 12 3f 97 92 01 a9 fe ff 42 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00""") + +arp_reply_infos = { + "source_mac_address" : 0x00221922549e, + "destination_mac_address" : 0x00123f979201, + "ethernet_type" : 0x806, + "hardware_type" : 0x1, + "operation" : 0x2, + "protocol_address_length" : 0x4, + "protocol_type" : 0x800, + "source_ip_address" : 0xa9fe6462, + "destination_ip_address" : 0xa9feff42 +} + +ping_request = format_dump(""" +ff 03 00 21 45 00 00 64 00 00 00 00 ff 01 a7 96 +0a 00 00 01 0a 00 00 02 08 00 d6 7f 00 00 00 00 +00 00 00 00 00 02 a7 c8 ab cd ab cd ab cd ab cd +ab cd ab cd ab cd ab cd ab cd ab cd ab cd ab cd +ab cd ab cd ab cd ab cd ab cd ab cd ab cd ab cd +ab cd ab cd ab cd ab cd ab cd ab cd ab cd ab cd +ab cd ab cd ab cd ab cd""") + +icmp_echo = format_dump(""" +ff 03 00 21 45 00 00 64 00 00 00 00 ff 01 a7 96 +0a 00 00 02 0a 00 00 01 00 00 de 7f 00 00 00 00 +00 00 00 00 00 02 a7 c8 ab cd ab cd ab cd ab cd +ab cd ab cd ab cd ab cd ab cd ab cd ab cd ab cd +ab cd ab cd ab cd ab cd ab cd ab cd ab cd ab cd +ab cd ab cd ab cd ab cd ab cd ab cd ab cd ab cd +ab cd ab cd ab cd ab cd""") + +udp = format_dump(""" +d0 7a b5 96 cd 0a 00 14 0b 33 33 27 08 00 45 00 +00 5f 31 16 00 00 80 11 87 77 c0 a8 01 65 b2 7b +0d 78 a6 3f 69 0f 00 4b 6a 54 64 31 3a 61 64 32 +3a 69 64 32 30 3a 5a fa 29 99 3a 5e ce 19 d1 8b +aa 9b 4e 4d f9 2e 51 52 fe ff 65 31 3a 71 34 3a +70 69 6e 67 31 3a 74 34 3a 85 72 00 00 31 3a 76 +34 3a 55 54 7e 62 31 3a 79 31 3a 71 65""") diff --git a/liteeth/test/model/mac.py b/liteeth/test/model/mac.py index 7af991be..26e4a13c 100644 --- a/liteeth/test/model/mac.py +++ b/liteeth/test/model/mac.py @@ -7,11 +7,11 @@ from liteeth.test.common import * def print_mac(s): print_with_prefix(s, "[MAC]") -preamble = split_bytes(eth_preamble, 8) +preamble = split_bytes(eth_preamble, 8, "little") def crc32(l): crc = [] - crc_bytes = split_bytes(binascii.crc32(bytes(l)), 4) + crc_bytes = split_bytes(binascii.crc32(bytes(l)), 4, "little") for byte in crc_bytes: crc.append(int(byte)) return crc @@ -57,8 +57,9 @@ class MACPacket(Packet): def encode_header(self): header = 0 for k, v in sorted(mac_header.items()): - header |= (getattr(self, k) << (v.byte*8+v.offset)) - for d in reversed(split_bytes(header, mac_header_len)): + 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): self.insert(0, d) def insert_crc(self): @@ -135,3 +136,26 @@ class MAC(Module): if len(self.tx_packets) != 0: tx_packet = self.tx_packets.pop(0) yield from self.phy.send(tx_packet) + +if __name__ == "__main__": + from liteeth.test.model.dumps import * + errors = 0 + packet = MACPacket(arp_request) + packet.decode_remove_header() + #print(packet) + errors += verify_packet(packet, arp_request_infos) + packet.encode_header() + packet.decode_remove_header() + #print(packet) + errors += verify_packet(packet, arp_request_infos) + + #print(packet) + packet = MACPacket(arp_reply) + packet.decode_remove_header() + errors += verify_packet(packet, arp_reply_infos) + packet.encode_header() + packet.decode_remove_header() + #print(packet) + errors += verify_packet(packet, arp_reply_infos) + + print("mac errors " + str(errors))