generic: add crossbar and use it in mac/ip/udp
authorFlorent Kermarrec <florent@enjoy-digital.fr>
Tue, 10 Feb 2015 14:11:06 +0000 (15:11 +0100)
committerFlorent Kermarrec <florent@enjoy-digital.fr>
Tue, 10 Feb 2015 14:16:35 +0000 (15:16 +0100)
liteeth/core/ip/__init__.py
liteeth/core/ip/crossbar.py [deleted file]
liteeth/core/udp/__init__.py
liteeth/core/udp/crossbar.py [deleted file]
liteeth/generic/arbiter.py
liteeth/generic/crossbar.py [new file with mode: 0644]
liteeth/generic/dispatcher.py
liteeth/mac/__init__.py
liteeth/mac/frontend/crossbar.py [deleted file]

index 64a386fd04a9269629fd2ad212e4e9b3a172122b..8e522a994e8685a679c81098be97b823adc97978 100644 (file)
@@ -1,7 +1,8 @@
 from liteeth.common import *
 from liteeth.generic.depacketizer import LiteEthDepacketizer
 from liteeth.generic.packetizer import LiteEthPacketizer
-from liteeth.core.ip.crossbar import LiteEthIPV4Crossbar
+from liteeth.generic.crossbar import LiteEthCrossbar
+from liteeth.core.ip.common import *
 
 class LiteEthIPV4Depacketizer(LiteEthDepacketizer):
        def __init__(self):
@@ -19,6 +20,17 @@ class LiteEthIPV4Packetizer(LiteEthPacketizer):
                        ipv4_header,
                        ipv4_header_len)
 
+class LiteEthIPV4Crossbar(LiteEthCrossbar):
+       def __init__(self):
+               LiteEthCrossbar.__init__(self, LiteEthIPV4MasterPort, "protocol")
+
+       def get_port(self, protocol):
+               if protocol in self.users.keys():
+                       raise ValueError("Protocol {0:#x} already assigned".format(protocol))
+               port = LiteEthIPV4UserPort(8)
+               self.users[protocol] = port
+               return port
+
 class LiteEthIPV4Checksum(Module):
        def __init__(self, words_per_clock_cycle=1, skip_checksum=False):
                self.reset = Signal() # XXX FIXME InsertReset generates incorrect verilog
diff --git a/liteeth/core/ip/crossbar.py b/liteeth/core/ip/crossbar.py
deleted file mode 100644 (file)
index edff815..0000000
+++ /dev/null
@@ -1,33 +0,0 @@
-from collections import OrderedDict
-
-from liteeth.common import *
-from liteeth.generic.arbiter import Arbiter
-from liteeth.generic.dispatcher import Dispatcher
-from liteeth.core.ip.common import *
-
-class LiteEthIPV4Crossbar(Module):
-       def __init__(self):
-               self.users = OrderedDict()
-               self.master = LiteEthIPV4MasterPort(8)
-
-       def get_port(self, protocol):
-               if protocol in self.users.keys():
-                       raise ValueError("Protocol {0:#x} already assigned".format(protocol))
-               port = LiteEthIPV4UserPort(8)
-               self.users[protocol] = port
-               return port
-
-       def do_finalize(self):
-               # TX arbitrate
-               sinks = [port.sink for port in self.users.values()]
-               self.submodules.ip_arbiter = Arbiter(sinks, self.master.source)
-
-               # RX dispatch
-               sources = [port.source for port in self.users.values()]
-               self.submodules.ip_dispatcher = Dispatcher(self.master.sink, sources, one_hot=True)
-               cases = {}
-               cases["default"] = self.ip_dispatcher.sel.eq(0)
-               for i, (k, v) in enumerate(self.users.items()):
-                       cases[k] = self.ip_dispatcher.sel.eq(2**i)
-               self.comb += \
-                       Case(self.master.sink.protocol, cases)
index 7a8ae5f0140eda4d51d3934024b123d3c6a08fe9..55f6241492e34067570cc7db697163d4fcf6ef3a 100644 (file)
@@ -1,7 +1,8 @@
 from liteeth.common import *
 from liteeth.generic.depacketizer import LiteEthDepacketizer
 from liteeth.generic.packetizer import LiteEthPacketizer
-from liteeth.core.udp.crossbar import LiteEthUDPCrossbar
+from liteeth.generic.crossbar import LiteEthCrossbar
+from liteeth.core.udp.common import *
 
 class LiteEthUDPDepacketizer(LiteEthDepacketizer):
        def __init__(self):
@@ -19,6 +20,33 @@ class LiteEthUDPPacketizer(LiteEthPacketizer):
                        udp_header,
                        udp_header_len)
 
+class LiteEthUDPCrossbar(LiteEthCrossbar):
+       def __init__(self):
+               LiteEthCrossbar.__init__(self, LiteEthUDPMasterPort, "dst_port")
+
+       def get_port(self, udp_port, dw=8):
+               if udp_port in self.users.keys():
+                       raise ValueError("Port {0:#x} already assigned".format(udp_port))
+               user_port = LiteEthUDPUserPort(dw)
+               internal_port = LiteEthUDPUserPort(8)
+               if dw != 8:
+                       converter = Converter(eth_udp_user_description(user_port.dw), eth_udp_user_description(8))
+                       self.submodules += converter
+                       self.comb += [
+                               Record.connect(user_port.sink, converter.sink),
+                               Record.connect(converter.source, internal_port.sink)
+                       ]
+                       converter = Converter(eth_udp_user_description(8), eth_udp_user_description(user_port.dw))
+                       self.submodules += converter
+                       self.comb += [
+                               Record.connect(internal_port.source, converter.sink),
+                               Record.connect(converter.source, user_port.source)
+                       ]
+                       self.users[udp_port] = internal_port
+               else:
+                       self.users[udp_port] = user_port
+               return user_port
+
 class LiteEthUDPTX(Module):
        def __init__(self, ip_address):
                self.sink = sink = Sink(eth_udp_user_description(8))
diff --git a/liteeth/core/udp/crossbar.py b/liteeth/core/udp/crossbar.py
deleted file mode 100644 (file)
index ccc7594..0000000
+++ /dev/null
@@ -1,49 +0,0 @@
-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, dw=8):
-               if udp_port in self.users.keys():
-                       raise ValueError("Port {0:#x} already assigned".format(udp_port))
-               user_port = LiteEthUDPUserPort(dw)
-               internal_port = LiteEthUDPUserPort(8)
-               if dw != 8:
-                       converter = Converter(eth_udp_user_description(user_port.dw), eth_udp_user_description(8))
-                       self.submodules += converter
-                       self.comb += [
-                               Record.connect(user_port.sink, converter.sink),
-                               Record.connect(converter.source, internal_port.sink)
-                       ]
-                       converter = Converter(eth_udp_user_description(8), eth_udp_user_description(user_port.dw))
-                       self.submodules += converter
-                       self.comb += [
-                               Record.connect(internal_port.source, converter.sink),
-                               Record.connect(converter.source, user_port.source)
-                       ]
-                       self.users[udp_port] = internal_port
-               else:
-                       self.users[udp_port] = user_port
-               return user_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 39f13db73e5685878ff75041383aa7a6a9a647b8..ca77377e556ec31968fd86cf96aaae9492f9e088 100644 (file)
@@ -8,7 +8,7 @@ class Arbiter(Module):
                        pass
                elif len(sources) == 1:
                        self.grant = Signal()
-                       self.comb += Record.connect(sources[0], sink)
+                       self.comb += Record.connect(sources.pop(), sink)
                else:
                        self.submodules.rr = RoundRobin(len(sources))
                        self.grant = self.rr.grant
diff --git a/liteeth/generic/crossbar.py b/liteeth/generic/crossbar.py
new file mode 100644 (file)
index 0000000..4f89785
--- /dev/null
@@ -0,0 +1,30 @@
+from collections import OrderedDict
+
+from liteeth.common import *
+from liteeth.generic.arbiter import Arbiter
+from liteeth.generic.dispatcher import Dispatcher
+
+class LiteEthCrossbar(Module):
+       def __init__(self, master_port, dispatch_param):
+               self.users = OrderedDict()
+               self.master = master_port(8)
+               self.dispatch_param = dispatch_param
+
+       # overload this in derived classes
+       def get_port(self, *args, **kwargs):
+               pass
+
+       def do_finalize(self):
+               # TX arbitrate
+               sinks = [port.sink for port in self.users.values()]
+               self.submodules.arbiter = Arbiter(sinks, self.master.source)
+
+               # RX dispatch
+               sources = [port.source for port in self.users.values()]
+               self.submodules.dispatcher = Dispatcher(self.master.sink, sources, one_hot=True)
+               cases = {}
+               cases["default"] = self.dispatcher.sel.eq(0)
+               for i, (k, v) in enumerate(self.users.items()):
+                       cases[k] = self.dispatcher.sel.eq(2**i)
+               self.comb += \
+                       Case(getattr(self.master.sink, self.dispatch_param), cases)
index a9ecd5d11b4416ed86459b8609f3d7d61104def3..3acb9f90d1bbb02ae5cfaeee62c48dfa486679a5 100644 (file)
@@ -6,7 +6,7 @@ class Dispatcher(Module):
                if len(sinks) == 0:
                        self.sel = Signal()
                elif len(sinks) == 1:
-                       self.comb += Record.connect(source, sinks[0])
+                       self.comb += Record.connect(source, sinks.pop())
                        self.sel = Signal()
                else:
                        if one_hot:
index 2b9cfb638de89d3a257d7c185af5ec3eb0691ee3..e2032d89a70fa43670f61ad97b105b6494131d68 100644 (file)
@@ -1,9 +1,10 @@
 from liteeth.common import *
 from liteeth.generic.depacketizer import LiteEthDepacketizer
 from liteeth.generic.packetizer import LiteEthPacketizer
+from liteeth.generic.crossbar import LiteEthCrossbar
 from liteeth.mac.core import LiteEthMACCore
+from liteeth.mac.frontend.common import *
 from liteeth.mac.frontend.wishbone import LiteEthMACWishboneInterface
-from liteeth.mac.frontend.crossbar import LiteEthMACCrossbar
 
 class LiteEthMACDepacketizer(LiteEthDepacketizer):
        def __init__(self):
@@ -21,6 +22,17 @@ class LiteEthMACPacketizer(LiteEthPacketizer):
                        mac_header,
                        mac_header_len)
 
+class LiteEthMACCrossbar(LiteEthCrossbar):
+       def __init__(self):
+               LiteEthCrossbar.__init__(self, LiteEthMACMasterPort, "ethernet_type")
+
+       def get_port(self, ethernet_type):
+               port = LiteEthMACUserPort(8)
+               if ethernet_type in self.users.keys():
+                       raise ValueError("Ethernet type {0:#x} already assigned".format(ethernet_type))
+               self.users[ethernet_type] = port
+               return port
+
 class LiteEthMAC(Module, AutoCSR):
        def __init__(self, phy, dw, interface="crossbar", endianness="big",
                        with_hw_preamble_crc=True):
diff --git a/liteeth/mac/frontend/crossbar.py b/liteeth/mac/frontend/crossbar.py
deleted file mode 100644 (file)
index 94fab8a..0000000
+++ /dev/null
@@ -1,33 +0,0 @@
-from collections import OrderedDict
-
-from liteeth.common import *
-from liteeth.generic.arbiter import Arbiter
-from liteeth.generic.dispatcher import Dispatcher
-from liteeth.mac.frontend.common import *
-
-class LiteEthMACCrossbar(Module):
-       def __init__(self):
-               self.users = OrderedDict()
-               self.master = LiteEthMACMasterPort(8)
-
-       def get_port(self, ethernet_type):
-               port = LiteEthMACUserPort(8)
-               if ethernet_type in self.users.keys():
-                       raise ValueError("Ethernet type {0:#x} already assigned".format(ethernet_type))
-               self.users[ethernet_type] = port
-               return port
-
-       def do_finalize(self):
-               # TX arbitrate
-               sinks = [port.sink for port in self.users.values()]
-               self.submodules.mac_arbiter = Arbiter(sinks, self.master.source)
-
-               # RX dispatch
-               sources = [port.source for port in self.users.values()]
-               self.submodules.mac_dispatcher = Dispatcher(self.master.sink, sources, one_hot=True)
-               cases = {}
-               cases["default"] = self.mac_dispatcher.sel.eq(0)
-               for i, (k, v) in enumerate(self.users.items()):
-                       cases[k] = self.mac_dispatcher.sel.eq(2**i)
-               self.comb += \
-                       Case(self.master.sink.ethernet_type, cases)