udp: add crossbar
authorFlorent Kermarrec <florent@enjoy-digital.fr>
Mon, 9 Feb 2015 10:19:26 +0000 (11:19 +0100)
committerFlorent Kermarrec <florent@enjoy-digital.fr>
Mon, 9 Feb 2015 10:59:36 +0000 (11:59 +0100)
liteeth/core/__init__.py
liteeth/core/udp/__init__.py
liteeth/core/udp/common.py [new file with mode: 0644]
liteeth/core/udp/crossbar.py [new file with mode: 0644]
liteeth/test/udp_tb.py
targets/udp.py

index 7783a15f134fff26b2f673990260dfdd56f612c1..6a143c9c682ab191525659f6e26a2b45d63c80c1 100644 (file)
@@ -13,8 +13,6 @@ class LiteEthIPCore(Module, AutoCSR):
                self.submodules.icmp = LiteEthICMP(self.ip, ip_address)
 
 class LiteEthUDPIPCore(LiteEthIPCore):
-       def __init__(self, phy, mac_address, ip_address, clk_freq, with_loopback=False):
+       def __init__(self, phy, mac_address, ip_address, clk_freq):
                LiteEthIPCore.__init__(self, phy, mac_address, ip_address, clk_freq)
-               self.submodules.udp = LiteEthUDP(self.ip, ip_address, with_loopback)
-               if not with_loopback:
-                       self.sink, self.source = self.udp.sink, self.udp.source
+               self.submodules.udp = LiteEthUDP(self.ip, ip_address)
index 9e6bd874cb88939cb6e46927393cbd79e8507303..f4df2e5e658fda8f1b1c66e85220a09d9945023d 100644 (file)
@@ -1,6 +1,7 @@
 from liteeth.common import *
 from liteeth.generic.depacketizer import LiteEthDepacketizer
 from liteeth.generic.packetizer import LiteEthPacketizer
+from liteeth.core.udp.crossbar import LiteEthUDPCrossbar
 
 class LiteEthUDPDepacketizer(LiteEthDepacketizer):
        def __init__(self):
@@ -108,7 +109,7 @@ class LiteEthUDPRX(Module):
                )
 
 class LiteEthUDP(Module):
-       def __init__(self, ip, ip_address, with_loopback):
+       def __init__(self, ip, ip_address):
                self.submodules.tx = tx = LiteEthUDPTX(ip_address)
                self.submodules.rx = rx = LiteEthUDPRX(ip_address)
                ip_port = ip.crossbar.get_port(udp_protocol)
@@ -116,11 +117,8 @@ class LiteEthUDP(Module):
                        Record.connect(tx.source, ip_port.sink),
                        Record.connect(ip_port.source, rx.sink)
                ]
-               if with_loopback:
-                       self.submodules.fifo = fifo = SyncFIFO(eth_udp_user_description(8), 2048, buffered=True)
-                       self.comb += [
-                               Record.connect(rx.source, fifo.sink),
-                               Record.connect(fifo.source, tx.sink)
-                       ]
-               else:
-                       self.sink, self.source = self.tx.sink, self.rx.source
+               self.submodules.crossbar = crossbar = LiteEthUDPCrossbar()
+               self.comb += [
+                       Record.connect(crossbar.master.source, tx.sink),
+                       Record.connect(rx.source, crossbar.master.sink)
+               ]
diff --git a/liteeth/core/udp/common.py b/liteeth/core/udp/common.py
new file mode 100644 (file)
index 0000000..feb55bf
--- /dev/null
@@ -0,0 +1,27 @@
+from liteeth.common import *
+
+class LiteEthUDPMasterPort:
+       def __init__(self, dw):
+               self.source = Source(eth_udp_user_description(dw))
+               self.sink = Sink(eth_udp_user_description(dw))
+
+       def connect(self, slave):
+               return [
+                       Record.connect(self.source, slave.sink),
+                       Record.connect(slave.source, self.sink)
+               ]
+
+class LiteEthUDPSlavePort:
+       def __init__(self, dw):
+               self.sink = Sink(eth_udp_user_description(dw))
+               self.source = Source(eth_udp_user_description(dw))
+
+       def connect(self, master):
+               return [
+                       Record.connect(self.sink, master.source),
+                       Record.connect(master.sink, self.source)
+               ]
+
+class LiteEthUDPUserPort(LiteEthUDPSlavePort):
+       def __init__(self, dw):
+               LiteEthUDPSlavePort.__init__(self, dw)
diff --git a/liteeth/core/udp/crossbar.py b/liteeth/core/udp/crossbar.py
new file mode 100644 (file)
index 0000000..f533a67
--- /dev/null
@@ -0,0 +1,33 @@
+from collections import OrderedDict
+
+from liteeth.common import *
+from liteeth.generic.arbiter import Arbiter
+from liteeth.generic.dispatcher import Dispatcher
+from liteeth.core.udp.common import *
+
+class LiteEthUDPCrossbar(Module):
+       def __init__(self):
+               self.users = OrderedDict()
+               self.master = LiteEthUDPMasterPort(8)
+
+       def get_port(self, udp_port):
+               port = LiteEthUDPUserPort(8)
+               if udp_port in self.users.keys():
+                       raise ValueError("Port {0:#x} already assigned".format(udp_port))
+               self.users[udp_port] = port
+               return port
+
+       def do_finalize(self):
+               # TX arbitrate
+               sinks = [port.sink for port in self.users.values()]
+               self.submodules.udp_arbiter = Arbiter(sinks, self.master.source)
+
+               # RX dispatch
+               sources = [port.source for port in self.users.values()]
+               self.submodules.udp_dispatcher = Dispatcher(self.master.sink, sources, one_hot=True)
+               cases = {}
+               cases["default"] = self.udp_dispatcher.sel.eq(0)
+               for i, (k, v) in enumerate(self.users.items()):
+                       cases[k] = self.udp_dispatcher.sel.eq(2**i)
+               self.comb += \
+                       Case(self.master.sink.dst_port, cases)
index 4718cb940ca9a11c2d394d3c8fdb9b3766515bc2..b0274773cd0fb6fa8e8a38c0c719a267a870f525 100644 (file)
@@ -20,16 +20,17 @@ class TB(Module):
                self.submodules.ip_model = ip.IP(self.mac_model, mac_address, ip_address, debug=False, loopback=False)
                self.submodules.udp_model = udp.UDP(self.ip_model, ip_address, debug=False, loopback=True)
 
-               self.submodules.udp = LiteEthUDPIPCore(self.phy_model, mac_address, ip_address, 100000)
+               self.submodules.core = LiteEthUDPIPCore(self.phy_model, mac_address, ip_address, 100000)
+               udp_port = self.core.udp.crossbar.get_port(0x5678)
                self.submodules.streamer = PacketStreamer(eth_udp_user_description(8))
                self.submodules.logger = PacketLogger(eth_udp_user_description(8))
                self.comb += [
-                       Record.connect(self.streamer.source, self.udp.sink),
-                       self.udp.sink.ip_address.eq(0x12345678),
-                       self.udp.sink.src_port.eq(0x1234),
-                       self.udp.sink.dst_port.eq(0x5678),
-                       self.udp.sink.length.eq(64),
-                       Record.connect(self.udp.source, self.logger.sink)
+                       Record.connect(self.streamer.source, udp_port.sink),
+                       udp_port.sink.ip_address.eq(0x12345678),
+                       udp_port.sink.src_port.eq(0x1234),
+                       udp_port.sink.dst_port.eq(0x5678),
+                       udp_port.sink.length.eq(64),
+                       Record.connect(udp_port.source, self.logger.sink)
                ]
 
                # use sys_clk for each clock_domain
index 37bf990907cae94cdf5267ecaa6fffde4185357f..6491e6c02028aaee0ea90e68892054e5041bc3d5 100644 (file)
@@ -102,7 +102,7 @@ class UDPSoC(GenSoC, AutoCSR):
        default_platform = "kc705"
        csr_map = {
                "phy":          11,
-               "udp":          12
+               "core":         12
        }
        csr_map.update(GenSoC.csr_map)
        def __init__(self, platform):
@@ -112,7 +112,16 @@ class UDPSoC(GenSoC, AutoCSR):
 
                # Ethernet PHY and UDP/IP
                self.submodules.phy = LiteEthPHYGMII(platform.request("eth_clocks"), platform.request("eth"))
-               self.submodules.udp = LiteEthUDPIPCore(self.phy, 0x10e2d5000000, convert_ip("192.168.1.40"), clk_freq, with_loopback=True)
+               self.submodules.core = LiteEthUDPIPCore(self.phy, 0x10e2d5000000, convert_ip("192.168.1.40"), clk_freq)
+
+               # Create loopback on UDP port 6000
+               loopback_port = self.core.udp.crossbar.get_port(6000)
+               loopback_fifo = SyncFIFO(eth_udp_user_description(8), 2048, buffered=True)
+               self.submodules += loopback_fifo
+               self.comb += [
+                       Record.connect(loopback_port.source, loopback_fifo.sink),
+                       Record.connect(loopback_fifo.source, loopback_port.sink)
+               ]
 
 class UDPSoCDevel(UDPSoC, AutoCSR):
        csr_map = {
@@ -122,48 +131,48 @@ class UDPSoCDevel(UDPSoC, AutoCSR):
        def __init__(self, platform):
                UDPSoC.__init__(self, platform)
 
-               self.udp_icmp_rx_fsm_state = Signal(4)
-               self.udp_icmp_tx_fsm_state = Signal(4)
-               self.udp_udp_rx_fsm_state = Signal(4)
-               self.udp_udp_tx_fsm_state = Signal(4)
-               self.udp_ip_rx_fsm_state = Signal(4)
-               self.udp_ip_tx_fsm_state = Signal(4)
-               self.udp_arp_rx_fsm_state = Signal(4)
-               self.udp_arp_tx_fsm_state = Signal(4)
-               self.udp_arp_table_fsm_state = Signal(4)
+               self.core_icmp_rx_fsm_state = Signal(4)
+               self.core_icmp_tx_fsm_state = Signal(4)
+               self.core_udp_rx_fsm_state = Signal(4)
+               self.core_udp_tx_fsm_state = Signal(4)
+               self.core_ip_rx_fsm_state = Signal(4)
+               self.core_ip_tx_fsm_state = Signal(4)
+               self.core_arp_rx_fsm_state = Signal(4)
+               self.core_arp_tx_fsm_state = Signal(4)
+               self.core_arp_table_fsm_state = Signal(4)
 
                debug = (
-                       self.udp.mac.core.sink.stb,
-                       self.udp.mac.core.sink.sop,
-                       self.udp.mac.core.sink.eop,
-                       self.udp.mac.core.sink.ack,
-                       self.udp.mac.core.sink.data,
-
-                       self.udp.mac.core.source.stb,
-                       self.udp.mac.core.source.sop,
-                       self.udp.mac.core.source.eop,
-                       self.udp.mac.core.source.ack,
-                       self.udp.mac.core.source.data,
-
-                       self.udp.icmp.echo.sink.stb,
-                       self.udp.icmp.echo.sink.sop,
-                       self.udp.icmp.echo.sink.eop,
-                       self.udp.icmp.echo.sink.ack,
-                       self.udp.icmp.echo.sink.data,
-
-                       self.udp.icmp.echo.source.stb,
-                       self.udp.icmp.echo.source.sop,
-                       self.udp.icmp.echo.source.eop,
-                       self.udp.icmp.echo.source.ack,
-                       self.udp.icmp.echo.source.data,
-
-                       self.udp.ip.crossbar.master.sink.stb,
-                       self.udp.ip.crossbar.master.sink.sop,
-                       self.udp.ip.crossbar.master.sink.eop,
-                       self.udp.ip.crossbar.master.sink.ack,
-                       self.udp.ip.crossbar.master.sink.data,
-                       self.udp.ip.crossbar.master.sink.ip_address,
-                       self.udp.ip.crossbar.master.sink.protocol,
+                       self.core.mac.core.sink.stb,
+                       self.core.mac.core.sink.sop,
+                       self.core.mac.core.sink.eop,
+                       self.core.mac.core.sink.ack,
+                       self.core.mac.core.sink.data,
+
+                       self.core.mac.core.source.stb,
+                       self.core.mac.core.source.sop,
+                       self.core.mac.core.source.eop,
+                       self.core.mac.core.source.ack,
+                       self.core.mac.core.source.data,
+
+                       self.core.icmp.echo.sink.stb,
+                       self.core.icmp.echo.sink.sop,
+                       self.core.icmp.echo.sink.eop,
+                       self.core.icmp.echo.sink.ack,
+                       self.core.icmp.echo.sink.data,
+
+                       self.core.icmp.echo.source.stb,
+                       self.core.icmp.echo.source.sop,
+                       self.core.icmp.echo.source.eop,
+                       self.core.icmp.echo.source.ack,
+                       self.core.icmp.echo.source.data,
+
+                       self.core.ip.crossbar.master.sink.stb,
+                       self.core.ip.crossbar.master.sink.sop,
+                       self.core.ip.crossbar.master.sink.eop,
+                       self.core.ip.crossbar.master.sink.ack,
+                       self.core.ip.crossbar.master.sink.data,
+                       self.core.ip.crossbar.master.sink.ip_address,
+                       self.core.ip.crossbar.master.sink.protocol,
 
                        self.phy.sink.stb,
                        self.phy.sink.sop,
@@ -177,15 +186,15 @@ class UDPSoCDevel(UDPSoC, AutoCSR):
                        self.phy.source.ack,
                        self.phy.source.data,
 
-                       self.udp_icmp_rx_fsm_state,
-                       self.udp_icmp_tx_fsm_state,
-                       self.udp_udp_rx_fsm_state,
-                       self.udp_udp_tx_fsm_state,
-                       self.udp_ip_rx_fsm_state,
-                       self.udp_ip_tx_fsm_state,
-                       self.udp_arp_rx_fsm_state,
-                       self.udp_arp_tx_fsm_state,
-                       self.udp_arp_table_fsm_state,
+                       self.core_icmp_rx_fsm_state,
+                       self.core_icmp_tx_fsm_state,
+                       self.core_udp_rx_fsm_state,
+                       self.core_udp_tx_fsm_state,
+                       self.core_ip_rx_fsm_state,
+                       self.core_ip_tx_fsm_state,
+                       self.core_arp_rx_fsm_state,
+                       self.core_arp_tx_fsm_state,
+                       self.core_arp_table_fsm_state,
                )
 
                self.submodules.la = LiteScopeLA(debug, 2048)
@@ -195,15 +204,15 @@ class UDPSoCDevel(UDPSoC, AutoCSR):
        def do_finalize(self):
                UDPSoC.do_finalize(self)
                self.comb += [
-                       self.udp_icmp_rx_fsm_state.eq(self.udp.icmp.rx.fsm.state),
-                       self.udp_icmp_tx_fsm_state.eq(self.udp.icmp.tx.fsm.state),
-                       self.udp_udp_rx_fsm_state.eq(self.udp.udp.rx.fsm.state),
-                       self.udp_udp_tx_fsm_state.eq(self.udp.udp.tx.fsm.state),
-                       self.udp_ip_rx_fsm_state.eq(self.udp.ip.rx.fsm.state),
-                       self.udp_ip_tx_fsm_state.eq(self.udp.ip.tx.fsm.state),
-                       self.udp_arp_rx_fsm_state.eq(self.udp.arp.rx.fsm.state),
-                       self.udp_arp_tx_fsm_state.eq(self.udp.arp.tx.fsm.state),
-                       self.udp_arp_table_fsm_state.eq(self.udp.arp.table.fsm.state)
+                       self.core_icmp_rx_fsm_state.eq(self.core.icmp.rx.fsm.state),
+                       self.core_icmp_tx_fsm_state.eq(self.core.icmp.tx.fsm.state),
+                       self.core_udp_rx_fsm_state.eq(self.core.udp.rx.fsm.state),
+                       self.core_udp_tx_fsm_state.eq(self.core.udp.tx.fsm.state),
+                       self.core_ip_rx_fsm_state.eq(self.core.ip.rx.fsm.state),
+                       self.core_ip_tx_fsm_state.eq(self.core.ip.tx.fsm.state),
+                       self.core_arp_rx_fsm_state.eq(self.core.arp.rx.fsm.state),
+                       self.core_arp_tx_fsm_state.eq(self.core.arp.tx.fsm.state),
+                       self.core_arp_table_fsm_state.eq(self.core.arp.table.fsm.state)
                ]
 
        def exit(self, platform):