ip: add checksum computation on ip tx (maybe not optimal on ressources)
authorFlorent Kermarrec <florent@enjoy-digital.fr>
Wed, 4 Feb 2015 18:35:38 +0000 (19:35 +0100)
committerFlorent Kermarrec <florent@enjoy-digital.fr>
Wed, 4 Feb 2015 18:35:38 +0000 (19:35 +0100)
liteeth/generic/depacketizer.py
liteeth/generic/packetizer.py
liteeth/ip/__init__.py

index 0713b36e8fb6eef37bfc33cb9cd18787de5e8645..64a1974ef049f1acbed25a15ca4a8a456a0b72aa 100644 (file)
@@ -12,15 +12,15 @@ 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)
+               self.header = Signal(header_length*8)
                ###
                shift = Signal()
-               header = Signal(header_length*8)
                counter = Counter(max=header_length)
                self.submodules += counter
 
                self.sync += \
                        If(shift,
-                               header.eq(Cat(header[8:], sink.data))
+                               self.header.eq(Cat(self.header[8:], sink.data))
                        )
 
                fsm = FSM(reset_state="IDLE")
@@ -54,7 +54,7 @@ class LiteEthDepacketizer(Module):
                        source.eop.eq(sink.eop),
                        source.data.eq(sink.data),
                        source.error.eq(sink.error),
-                       _decode_header(header_type, header, source)
+                       _decode_header(header_type, self.header, source)
                ]
                fsm.act("COPY",
                        sink.ack.eq(source.ack),
index ebd42c0cf69baabd7dd79e2507d43d8714d54d65..ac9cc62074dd446d1ac30957e2e6bb35cbad7fe7 100644 (file)
@@ -12,18 +12,18 @@ 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)
+               self.header = Signal(header_length*8)
                ###
-               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 += _encode_header(header_type, header, sink)
+               self.comb += _encode_header(header_type, self.header, sink)
                self.sync += [
                        If(load,
-                               header_reg.eq(header)
+                               header_reg.eq(self.header)
                        ).Elif(shift,
                                header_reg.eq(Cat(header_reg[8:], Signal(8)))
                        )
@@ -40,7 +40,7 @@ class LiteEthPacketizer(Module):
                                source.stb.eq(1),
                                source.sop.eq(1),
                                source.eop.eq(0),
-                               source.data.eq(header[:8]),
+                               source.data.eq(self.header[:8]),
                                If(source.stb & source.ack,
                                        load.eq(1),
                                        NextState("SEND_HEADER"),
index 973423563b0748baadea2f1085cd6a9c83647ae1..84fd81773a6f7b9143cb64b9e68c25bd31596eed 100644 (file)
@@ -18,6 +18,26 @@ class LiteEthIPV4Packetizer(LiteEthPacketizer):
                        ipv4_header,
                        ipv4_header_len)
 
+class LiteEthIPV4Checksum(Module):
+       def __init__(self, skip_header=False):
+               self.header = Signal(ipv4_header_len*8)
+               self.value = Signal(16)
+
+               s = Signal(17)
+               r = Signal(17)
+               for i in range(ipv4_header_len//2):
+                       if skip_header and i == 5:
+                               pass
+                       else:
+                               s_next = Signal(17)
+                               r_next = Signal(17)
+                               self.comb += [
+                                       s_next.eq(r + self.header[i*16:(i+1)*16]),
+                                       r_next.eq(Cat(s_next[:16]+s_next[16], Signal()))
+                               ]
+                               s, r = s_next, r_next
+               self.comb += self.value.eq(~Cat(r[8:16], r[:8]))
+
 class LiteEthIPTX(Module):
        def __init__(self, mac_address, ip_address, arp_table):
                self.sink = Sink(eth_ipv4_user_description(8))
@@ -45,6 +65,13 @@ class LiteEthIPTX(Module):
                ]
                sink = packetizer.source
 
+               checksum = LiteEthIPV4Checksum(skip_header=True)
+               self.submodules += checksum
+               self.comb += [
+                       checksum.header.eq(packetizer.header),
+                       packetizer.sink.header_checksum.eq(checksum.value)
+               ]
+
                destination_mac_address = Signal(48)
 
                fsm = FSM(reset_state="IDLE")