From 90abd1902240d74b35b66ff09e5225498e691c50 Mon Sep 17 00:00:00 2001 From: Florent Kermarrec Date: Wed, 4 Feb 2015 20:50:49 +0100 Subject: [PATCH] udp: add skeleton --- liteeth/common.py | 11 +++++ liteeth/core/ip.py | 1 - liteeth/core/udp.py | 103 +++++++++++++++++++++++++++++++++++++++++++- 3 files changed, 112 insertions(+), 3 deletions(-) diff --git a/liteeth/common.py b/liteeth/common.py index ec006492..5c5b06ec 100644 --- a/liteeth/common.py +++ b/liteeth/common.py @@ -149,6 +149,17 @@ def eth_udp_description(dw): ] return EndpointDescription(layout, packetized=True) +def eth_udp_user_description(dw): + layout = [ + ("source_port", 16), + ("destination_port", 16), + ("ip_address", 32), + ("length", 16), + ("data", dw), + ("error", dw//8) + ] + return EndpointDescription(layout, packetized=True) + # Generic modules @DecorateModule(InsertReset) @DecorateModule(InsertCE) diff --git a/liteeth/core/ip.py b/liteeth/core/ip.py index e495972e..d1978682 100644 --- a/liteeth/core/ip.py +++ b/liteeth/core/ip.py @@ -104,7 +104,6 @@ class LiteEthIPTX(Module): self.source.ethernet_type.eq(ethernet_type_ip), self.source.destination_mac_address.eq(destination_mac_address), self.source.source_mac_address.eq(mac_address), - # XXX compute check sum If(self.source.stb & self.source.eop & self.source.ack, # XXX manage failed NextState("IDLE") diff --git a/liteeth/core/udp.py b/liteeth/core/udp.py index 296abe6d..b4afd936 100644 --- a/liteeth/core/udp.py +++ b/liteeth/core/udp.py @@ -5,7 +5,7 @@ from liteeth.generic.packetizer import LiteEthPacketizer class LiteEthUDPDepacketizer(LiteEthDepacketizer): def __init__(self): LiteEthDepacketizer.__init__(self, - eth_ipv4_description(8), + eth_ipv4_user_description(8), eth_udp_description(8), udp_header, udp_header_len) @@ -14,6 +14,105 @@ class LiteEthUDPPacketizer(LiteEthPacketizer): def __init__(self): LiteEthPacketizer.__init__(self, eth_udp_description(8), - eth_ipv4_description(8), + eth_ipv4_user_description(8), udp_header, udp_header_len) + +class LiteEthUDPTX(Module): + def __init__(self, ip_address): + self.sink = Sink(eth_udp_user_description(8)) + self.source = Source(eth_ipv4_user_description(8)) + ### + packetizer = LiteEthUDPV4Packetizer() + self.submodules += packetizer + self.comb += [ + packetizer.sink.stb.eq(self.sink.stb), + packetizer.sink.sop.eq(self.sink.sop), + packetizer.sink.eop.eq(self.sink.eop), + self.sink.eq(packetizer.sink.ack), + packetizer.sink.source_port.eq(self.sink.source_port), + packetizer.sink.destination_port.eq(self.sink.destination_port), + packetizer.sink.length.eq(self.sink.length + udp_header_len), + packetizer.sink.checksum.eq(0), + ] + sink = packetizer.source + + fsm = FSM(reset_state="IDLE") + self.submodules += fsm + fsm.act("IDLE", + sink.ack.eq(1), + If(sink.stb & sink.sop, + sink.ack.eq(0), + NextState("SEND") + ) + ) + fsm.act("SEND", + Record.connect(packetizer.source, self.source), + self.source.length.eq(), + self.source.protocol.eq(udp_protocol), + self.source.ip_address.eq(self.sink.ip_address), + If(self.source.stb & self.source.eop & self.source.ack, + NextState("IDLE") + ) + ) + +class LiteEthUDPRX(Module): + def __init__(self, ip_address): + self.sink = Sink(eth_ipv4_user_description(8)) + self.source = source = Source(eth_udp_user_description(8)) + ### + depacketizer = LiteEthUDPV4Depacketizer() + self.submodules += depacketizer + self.comb += Record.connect(self.sink, depacketizer.sink) + sink = depacketizer.source + + fsm = FSM(reset_state="IDLE") + self.submodules += fsm + fsm.act("IDLE", + sink.ack.eq(1), + If(sink.stb & sink.sop, + sink.ack.eq(0), + NextState("CHECK") + ) + ) + valid = Signal() + self.comb += valid.eq( + sink.stb & + (sink.protocol == udp_protocol) & + (sink.ip_address == ip_address) + ) + + fsm.act("CHECK", + If(valid, + NextState("PRESENT") + ).Else( + NextState("DROP") + ) + ), + fsm.act("PRESENT", + source.stb.eq(sink.stb), + source.sop.eq(sink.sop), + source.eop.eq(sink.eop), + sink.ack.eq(source.ack), + source.source_port.eq(sink.source_port), + source.destination_port.eq(sink.destination_port), + source.ip_address.eq(0), + source.length.eq(sink.length - udp_header_len), + source.data.eq(sink.data), + source.error.eq(sink.error), + If(source.stb & source.eop & source.ack, + NextState("IDLE") + ) + ) + fsm.act("DROP", + sink.ack.eq(1), + If(source.stb & source.eop & source.ack, + NextState("IDLE") + ) + ) + +class LiteEthUDP(Module): + def __init__(self, ip_address): + self.submodules.tx = LiteEthUDPTX(ip_address) + self.submodules.rx = LiteEthUDPRX(ip_address) + self.sink, self.source = self.tx.sink, self.rx.source -- 2.30.2