ip: add crossbar

This commit is contained in:
Florent Kermarrec 2015-02-06 00:54:05 +01:00
parent 81343e9961
commit c0814ac63f
7 changed files with 79 additions and 13 deletions

View File

@ -9,7 +9,6 @@ class LiteEthIPCore(Module, AutoCSR):
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.ip = LiteEthIP(self.mac, mac_address, ip_address, self.arp.table)
self.sink, self.source = self.ip.sink, self.ip.source
class LiteEthUDPIPCore(LiteEthIPCore):
def __init__(self, phy, mac_address, ip_address, clk_freq):

View File

@ -1,6 +1,7 @@
from liteeth.common import *
from liteeth.generic.depacketizer import LiteEthDepacketizer
from liteeth.generic.packetizer import LiteEthPacketizer
from liteeth.core.ip.crossbar import LiteEthIPV4Crossbar
class LiteEthIPV4Depacketizer(LiteEthDepacketizer):
def __init__(self):
@ -185,4 +186,8 @@ class LiteEthIP(Module):
Record.connect(self.tx.source, mac_port.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)
]

27
liteeth/core/ip/common.py Normal file
View File

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

View File

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

View File

@ -116,8 +116,9 @@ class LiteEthUDP(Module):
def __init__(self, ip, ip_address):
self.submodules.tx = LiteEthUDPTX(ip_address)
self.submodules.rx = LiteEthUDPRX(ip_address)
ip_port = ip.crossbar.get_port(udp_protocol)
self.comb += [
Record.connect(self.tx.source, ip.sink),
Record.connect(ip.source, self.rx.sink)
Record.connect(self.tx.source, ip_port.sink),
Record.connect(ip_port.source, self.rx.sink)
]
self.sink, self.source = self.tx.sink, self.rx.source

View File

@ -13,7 +13,7 @@ class LiteEthMACCrossbar(Module):
def get_port(self, ethernet_type):
port = LiteEthMACUserPort(8)
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
return port

View File

@ -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 = 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
self.clock_domains.cd_eth_rx = ClockDomain()
@ -42,15 +43,15 @@ class TB(Module):
yield
while True:
selfp.ip.sink.stb = 1
selfp.ip.sink.sop = 1
selfp.ip.sink.eop = 1
selfp.ip.sink.ip_address = 0x12345678
selfp.ip.sink.protocol = udp_protocol
selfp.ip_port.sink.stb = 1
selfp.ip_port.sink.sop = 1
selfp.ip_port.sink.eop = 1
selfp.ip_port.sink.ip_address = 0x12345678
selfp.ip_port.sink.protocol = udp_protocol
selfp.ip.source.ack = 1
if selfp.ip.source.stb == 1 and selfp.ip.source.sop == 1:
print("IP Packet / from ip_address %08x" %selfp.ip.sink.ip_address)
selfp.ip_port.source.ack = 1
if selfp.ip_port.source.stb == 1 and selfp.ip_port.source.sop == 1:
print("IP Packet / from ip_address %08x" %selfp.ip_port.sink.ip_address)
yield