ip: add crossbar
This commit is contained in:
parent
81343e9961
commit
c0814ac63f
|
@ -9,7 +9,6 @@ class LiteEthIPCore(Module, AutoCSR):
|
||||||
self.submodules.mac = LiteEthMAC(phy, 8, interface="crossbar", with_hw_preamble_crc=True)
|
self.submodules.mac = LiteEthMAC(phy, 8, interface="crossbar", with_hw_preamble_crc=True)
|
||||||
self.submodules.arp = LiteEthARP(self.mac, mac_address, ip_address, clk_freq)
|
self.submodules.arp = LiteEthARP(self.mac, mac_address, ip_address, clk_freq)
|
||||||
self.submodules.ip = LiteEthIP(self.mac, mac_address, ip_address, self.arp.table)
|
self.submodules.ip = LiteEthIP(self.mac, mac_address, ip_address, self.arp.table)
|
||||||
self.sink, self.source = self.ip.sink, self.ip.source
|
|
||||||
|
|
||||||
class LiteEthUDPIPCore(LiteEthIPCore):
|
class LiteEthUDPIPCore(LiteEthIPCore):
|
||||||
def __init__(self, phy, mac_address, ip_address, clk_freq):
|
def __init__(self, phy, mac_address, ip_address, clk_freq):
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
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
|
||||||
|
|
||||||
class LiteEthIPV4Depacketizer(LiteEthDepacketizer):
|
class LiteEthIPV4Depacketizer(LiteEthDepacketizer):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
|
@ -185,4 +186,8 @@ class LiteEthIP(Module):
|
||||||
Record.connect(self.tx.source, mac_port.sink),
|
Record.connect(self.tx.source, mac_port.sink),
|
||||||
Record.connect(mac_port.source, self.rx.sink)
|
Record.connect(mac_port.source, self.rx.sink)
|
||||||
]
|
]
|
||||||
self.sink, self.source = self.tx.sink, self.rx.source
|
self.submodules.crossbar = LiteEthIPV4Crossbar()
|
||||||
|
self.comb += [
|
||||||
|
Record.connect(self.crossbar.master.source, self.tx.sink),
|
||||||
|
Record.connect(self.rx.source, self.crossbar.master.sink)
|
||||||
|
]
|
||||||
|
|
|
@ -0,0 +1,27 @@
|
||||||
|
from liteeth.common import *
|
||||||
|
|
||||||
|
class LiteEthIPV4MasterPort:
|
||||||
|
def __init__(self, dw):
|
||||||
|
self.source = Source(eth_ipv4_user_description(dw))
|
||||||
|
self.sink = Sink(eth_ipv4_user_description(dw))
|
||||||
|
|
||||||
|
def connect(self, slave):
|
||||||
|
return [
|
||||||
|
Record.connect(self.source, slave.sink),
|
||||||
|
Record.connect(slave.source, self.sink)
|
||||||
|
]
|
||||||
|
|
||||||
|
class LiteEthIPV4SlavePort:
|
||||||
|
def __init__(self, dw):
|
||||||
|
self.sink = Sink(eth_ipv4_user_description(dw))
|
||||||
|
self.source = Source(eth_ipv4_user_description(dw))
|
||||||
|
|
||||||
|
def connect(self, master):
|
||||||
|
return [
|
||||||
|
Record.connect(self.sink, master.source),
|
||||||
|
Record.connect(master.sink, self.source)
|
||||||
|
]
|
||||||
|
|
||||||
|
class LiteEthIPV4UserPort(LiteEthIPV4SlavePort):
|
||||||
|
def __init__(self, dw):
|
||||||
|
LiteEthIPV4SlavePort.__init__(self, dw)
|
|
@ -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.ip.common import *
|
||||||
|
|
||||||
|
class LiteEthIPV4Crossbar(Module):
|
||||||
|
def __init__(self):
|
||||||
|
self.users = OrderedDict()
|
||||||
|
self.master = LiteEthIPV4MasterPort(8)
|
||||||
|
|
||||||
|
def get_port(self, protocol):
|
||||||
|
port = LiteEthIPV4UserPort(8)
|
||||||
|
if protocol in self.users.keys():
|
||||||
|
raise ValueError("Protocol {} already used".format(protocol))
|
||||||
|
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)
|
|
@ -116,8 +116,9 @@ class LiteEthUDP(Module):
|
||||||
def __init__(self, ip, ip_address):
|
def __init__(self, ip, ip_address):
|
||||||
self.submodules.tx = LiteEthUDPTX(ip_address)
|
self.submodules.tx = LiteEthUDPTX(ip_address)
|
||||||
self.submodules.rx = LiteEthUDPRX(ip_address)
|
self.submodules.rx = LiteEthUDPRX(ip_address)
|
||||||
|
ip_port = ip.crossbar.get_port(udp_protocol)
|
||||||
self.comb += [
|
self.comb += [
|
||||||
Record.connect(self.tx.source, ip.sink),
|
Record.connect(self.tx.source, ip_port.sink),
|
||||||
Record.connect(ip.source, self.rx.sink)
|
Record.connect(ip_port.source, self.rx.sink)
|
||||||
]
|
]
|
||||||
self.sink, self.source = self.tx.sink, self.rx.source
|
self.sink, self.source = self.tx.sink, self.rx.source
|
||||||
|
|
|
@ -13,7 +13,7 @@ class LiteEthMACCrossbar(Module):
|
||||||
def get_port(self, ethernet_type):
|
def get_port(self, ethernet_type):
|
||||||
port = LiteEthMACUserPort(8)
|
port = LiteEthMACUserPort(8)
|
||||||
if ethernet_type in self.users.keys():
|
if ethernet_type in self.users.keys():
|
||||||
raise ValueError("Ethernet type {} already used")
|
raise ValueError("Ethernet type {} already used".format(ethernet_type))
|
||||||
self.users[ethernet_type] = port
|
self.users[ethernet_type] = port
|
||||||
return port
|
return port
|
||||||
|
|
||||||
|
|
|
@ -20,6 +20,7 @@ class TB(Module):
|
||||||
self.submodules.ip_model = ip.IP(self.mac_model, mac_address, ip_address, debug=False, loopback=True)
|
self.submodules.ip_model = ip.IP(self.mac_model, mac_address, ip_address, debug=False, loopback=True)
|
||||||
|
|
||||||
self.submodules.ip = LiteEthIPCore(self.phy_model, mac_address, ip_address, 100000)
|
self.submodules.ip = LiteEthIPCore(self.phy_model, mac_address, ip_address, 100000)
|
||||||
|
self.ip_port = self.ip.ip.crossbar.get_port(udp_protocol)
|
||||||
|
|
||||||
# use sys_clk for each clock_domain
|
# use sys_clk for each clock_domain
|
||||||
self.clock_domains.cd_eth_rx = ClockDomain()
|
self.clock_domains.cd_eth_rx = ClockDomain()
|
||||||
|
@ -42,15 +43,15 @@ class TB(Module):
|
||||||
yield
|
yield
|
||||||
|
|
||||||
while True:
|
while True:
|
||||||
selfp.ip.sink.stb = 1
|
selfp.ip_port.sink.stb = 1
|
||||||
selfp.ip.sink.sop = 1
|
selfp.ip_port.sink.sop = 1
|
||||||
selfp.ip.sink.eop = 1
|
selfp.ip_port.sink.eop = 1
|
||||||
selfp.ip.sink.ip_address = 0x12345678
|
selfp.ip_port.sink.ip_address = 0x12345678
|
||||||
selfp.ip.sink.protocol = udp_protocol
|
selfp.ip_port.sink.protocol = udp_protocol
|
||||||
|
|
||||||
selfp.ip.source.ack = 1
|
selfp.ip_port.source.ack = 1
|
||||||
if selfp.ip.source.stb == 1 and selfp.ip.source.sop == 1:
|
if selfp.ip_port.source.stb == 1 and selfp.ip_port.source.sop == 1:
|
||||||
print("IP Packet / from ip_address %08x" %selfp.ip.sink.ip_address)
|
print("IP Packet / from ip_address %08x" %selfp.ip_port.sink.ip_address)
|
||||||
|
|
||||||
yield
|
yield
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue