From: Florent Kermarrec Date: Thu, 5 Feb 2015 23:54:05 +0000 (+0100) Subject: ip: add crossbar X-Git-Tag: 24jan2021_ls180~2604^2~72 X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=c0814ac63f3277a965db80dedc56cbc1acae0fdd;p=litex.git ip: add crossbar --- diff --git a/liteeth/core/__init__.py b/liteeth/core/__init__.py index 545b7a0f..5fd6ac4d 100644 --- a/liteeth/core/__init__.py +++ b/liteeth/core/__init__.py @@ -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): diff --git a/liteeth/core/ip/__init__.py b/liteeth/core/ip/__init__.py index 04be1ce7..c22069be 100644 --- a/liteeth/core/ip/__init__.py +++ b/liteeth/core/ip/__init__.py @@ -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) + ] diff --git a/liteeth/core/ip/common.py b/liteeth/core/ip/common.py new file mode 100644 index 00000000..fef6d2d4 --- /dev/null +++ b/liteeth/core/ip/common.py @@ -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) diff --git a/liteeth/core/ip/crossbar.py b/liteeth/core/ip/crossbar.py new file mode 100644 index 00000000..f7f676b6 --- /dev/null +++ b/liteeth/core/ip/crossbar.py @@ -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) diff --git a/liteeth/core/udp/__init__.py b/liteeth/core/udp/__init__.py index 7a6c503f..59ea5cfd 100644 --- a/liteeth/core/udp/__init__.py +++ b/liteeth/core/udp/__init__.py @@ -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 diff --git a/liteeth/mac/frontend/crossbar.py b/liteeth/mac/frontend/crossbar.py index 696e353e..826db90b 100644 --- a/liteeth/mac/frontend/crossbar.py +++ b/liteeth/mac/frontend/crossbar.py @@ -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 diff --git a/liteeth/test/ip_tb.py b/liteeth/test/ip_tb.py index eb68916f..96b6d341 100644 --- a/liteeth/test/ip_tb.py +++ b/liteeth/test/ip_tb.py @@ -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.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.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_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