generic: add crossbar and use it in mac/ip/udp

This commit is contained in:
Florent Kermarrec 2015-02-10 15:11:06 +01:00
parent f0993ea422
commit 3187a93984
9 changed files with 87 additions and 120 deletions

View File

@ -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

View File

@ -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)

View File

@ -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))

View File

@ -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)

View File

@ -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

View File

@ -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)

View File

@ -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:

View File

@ -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):

View File

@ -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)