generic: add crossbar and use it in mac/ip/udp
This commit is contained in:
parent
f0993ea422
commit
3187a93984
|
@ -1,7 +1,8 @@
|
||||||
from liteeth.common import *
|
from liteeth.common import *
|
||||||
from liteeth.generic.depacketizer import LiteEthDepacketizer
|
from liteeth.generic.depacketizer import LiteEthDepacketizer
|
||||||
from liteeth.generic.packetizer import LiteEthPacketizer
|
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):
|
class LiteEthIPV4Depacketizer(LiteEthDepacketizer):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
|
@ -19,6 +20,17 @@ class LiteEthIPV4Packetizer(LiteEthPacketizer):
|
||||||
ipv4_header,
|
ipv4_header,
|
||||||
ipv4_header_len)
|
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):
|
class LiteEthIPV4Checksum(Module):
|
||||||
def __init__(self, words_per_clock_cycle=1, skip_checksum=False):
|
def __init__(self, words_per_clock_cycle=1, skip_checksum=False):
|
||||||
self.reset = Signal() # XXX FIXME InsertReset generates incorrect verilog
|
self.reset = Signal() # XXX FIXME InsertReset generates incorrect verilog
|
||||||
|
|
|
@ -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)
|
|
|
@ -1,7 +1,8 @@
|
||||||
from liteeth.common import *
|
from liteeth.common import *
|
||||||
from liteeth.generic.depacketizer import LiteEthDepacketizer
|
from liteeth.generic.depacketizer import LiteEthDepacketizer
|
||||||
from liteeth.generic.packetizer import LiteEthPacketizer
|
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):
|
class LiteEthUDPDepacketizer(LiteEthDepacketizer):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
|
@ -19,6 +20,33 @@ class LiteEthUDPPacketizer(LiteEthPacketizer):
|
||||||
udp_header,
|
udp_header,
|
||||||
udp_header_len)
|
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):
|
class LiteEthUDPTX(Module):
|
||||||
def __init__(self, ip_address):
|
def __init__(self, ip_address):
|
||||||
self.sink = sink = Sink(eth_udp_user_description(8))
|
self.sink = sink = Sink(eth_udp_user_description(8))
|
||||||
|
|
|
@ -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)
|
|
|
@ -8,7 +8,7 @@ class Arbiter(Module):
|
||||||
pass
|
pass
|
||||||
elif len(sources) == 1:
|
elif len(sources) == 1:
|
||||||
self.grant = Signal()
|
self.grant = Signal()
|
||||||
self.comb += Record.connect(sources[0], sink)
|
self.comb += Record.connect(sources.pop(), sink)
|
||||||
else:
|
else:
|
||||||
self.submodules.rr = RoundRobin(len(sources))
|
self.submodules.rr = RoundRobin(len(sources))
|
||||||
self.grant = self.rr.grant
|
self.grant = self.rr.grant
|
||||||
|
|
|
@ -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)
|
|
@ -6,7 +6,7 @@ class Dispatcher(Module):
|
||||||
if len(sinks) == 0:
|
if len(sinks) == 0:
|
||||||
self.sel = Signal()
|
self.sel = Signal()
|
||||||
elif len(sinks) == 1:
|
elif len(sinks) == 1:
|
||||||
self.comb += Record.connect(source, sinks[0])
|
self.comb += Record.connect(source, sinks.pop())
|
||||||
self.sel = Signal()
|
self.sel = Signal()
|
||||||
else:
|
else:
|
||||||
if one_hot:
|
if one_hot:
|
||||||
|
|
|
@ -1,9 +1,10 @@
|
||||||
from liteeth.common import *
|
from liteeth.common import *
|
||||||
from liteeth.generic.depacketizer import LiteEthDepacketizer
|
from liteeth.generic.depacketizer import LiteEthDepacketizer
|
||||||
from liteeth.generic.packetizer import LiteEthPacketizer
|
from liteeth.generic.packetizer import LiteEthPacketizer
|
||||||
|
from liteeth.generic.crossbar import LiteEthCrossbar
|
||||||
from liteeth.mac.core import LiteEthMACCore
|
from liteeth.mac.core import LiteEthMACCore
|
||||||
|
from liteeth.mac.frontend.common import *
|
||||||
from liteeth.mac.frontend.wishbone import LiteEthMACWishboneInterface
|
from liteeth.mac.frontend.wishbone import LiteEthMACWishboneInterface
|
||||||
from liteeth.mac.frontend.crossbar import LiteEthMACCrossbar
|
|
||||||
|
|
||||||
class LiteEthMACDepacketizer(LiteEthDepacketizer):
|
class LiteEthMACDepacketizer(LiteEthDepacketizer):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
|
@ -21,6 +22,17 @@ class LiteEthMACPacketizer(LiteEthPacketizer):
|
||||||
mac_header,
|
mac_header,
|
||||||
mac_header_len)
|
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):
|
class LiteEthMAC(Module, AutoCSR):
|
||||||
def __init__(self, phy, dw, interface="crossbar", endianness="big",
|
def __init__(self, phy, dw, interface="crossbar", endianness="big",
|
||||||
with_hw_preamble_crc=True):
|
with_hw_preamble_crc=True):
|
||||||
|
|
|
@ -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)
|
|
Loading…
Reference in New Issue