From 124a041fbd28abaf3315ee7ca426e5ba8efe8041 Mon Sep 17 00:00:00 2001 From: Florent Kermarrec Date: Fri, 30 Jan 2015 16:27:56 +0100 Subject: [PATCH] mac: add crossbar to simplify usage --- liteeth/__init__.py | 16 +++------------- liteeth/arp/__init__.py | 9 ++++++--- liteeth/common.py | 2 +- liteeth/ip/__init__.py | 9 +++++++-- liteeth/mac/__init__.py | 23 +++++++++++----------- liteeth/mac/frontend/common.py | 27 ++++++++++++++++++++++++++ liteeth/mac/frontend/crossbar.py | 33 ++++++++++++++++++++++++++++++++ liteeth/test/arp_tb.py | 10 +++------- liteeth/test/ip_tb.py | 6 +++--- 9 files changed, 95 insertions(+), 40 deletions(-) create mode 100644 liteeth/mac/frontend/common.py create mode 100644 liteeth/mac/frontend/crossbar.py diff --git a/liteeth/__init__.py b/liteeth/__init__.py index 38f150ce..c3fdcb4f 100644 --- a/liteeth/__init__.py +++ b/liteeth/__init__.py @@ -9,16 +9,6 @@ class LiteEthIPStack(Module, AutoCSR): def __init__(self, phy, mac_address, ip_address): self.phy = phy self.submodules.mac = mac = LiteEthMAC(phy, 8, interface="mac", with_hw_preamble_crc=True) - self.submodules.arp = arp = LiteEthARP(mac_address, ip_address) - self.submodules.ip = ip = LiteEthIP(ip_address, arp.table) - - # MAC dispatch - self.submodules.mac_dispatcher = Dispatcher(mac.source, [arp.sink, ip.sink], one_hot=True) - self.comb += \ - Case(mac.source.ethernet_type, { - ethernet_type_arp : [self.mac_dispatcher.sel.eq(1)], - ethernet_type_ip : [self.mac_dispatcher.sel.eq(2)], - "default" : [self.mac_dispatcher.sel.eq(0)], - }) - # MAC arbitrate - self.submodules.mac_arbiter = Arbiter([arp.source, ip.source], mac.sink) + self.submodules.arp = arp = LiteEthARP(mac, mac_address, ip_address) + self.submodules.ip = ip = LiteEthIP(mac, ip_address, arp.table) + self.sink, self.source = self.ip.sink, self.ip.source diff --git a/liteeth/arp/__init__.py b/liteeth/arp/__init__.py index 9d6551d2..08a406ab 100644 --- a/liteeth/arp/__init__.py +++ b/liteeth/arp/__init__.py @@ -221,7 +221,7 @@ class LiteEthARPTable(Module): ) class LiteEthARP(Module): - def __init__(self, mac_address, ip_address): + def __init__(self, mac, mac_address, ip_address): self.submodules.tx = LiteEthARPTX(mac_address, ip_address) self.submodules.rx = LiteEthARPRX(mac_address, ip_address) self.submodules.table = LiteEthARPTable() @@ -229,5 +229,8 @@ class LiteEthARP(Module): Record.connect(self.rx.source, self.table.sink), Record.connect(self.table.source, self.tx.sink) ] - self.sink, self.source = self.rx.sink, self.tx.source - self.request, self.response = self.table.request, self.table.response + mac_port = mac.crossbar.get_port(ethernet_type_arp) + self.comb += [ + Record.connect(self.tx.source, mac_port.sink), + Record.connect(mac_port.source, self.rx.sink) + ] diff --git a/liteeth/common.py b/liteeth/common.py index d1ce2cc2..c9ed17ce 100644 --- a/liteeth/common.py +++ b/liteeth/common.py @@ -78,7 +78,7 @@ udp_header = { } def reverse_bytes(v): - n = math.ceil(flen(v)//8) + n = math.ceil(flen(v)/8) r = [] for i in reversed(range(n)): r.append(v[i*8:min((i+1)*8, flen(v))]) diff --git a/liteeth/ip/__init__.py b/liteeth/ip/__init__.py index 1aa47367..8673fe94 100644 --- a/liteeth/ip/__init__.py +++ b/liteeth/ip/__init__.py @@ -103,7 +103,12 @@ class LiteEthIPRX(Module): ) class LiteEthIP(Module): - def __init__(self, ip_address, arp_table): + def __init__(self, mac, ip_address, arp_table): self.submodules.tx = LiteEthIPTX(ip_address, arp_table) self.submodules.rx = LiteEthIPRX(ip_address) - self.sink, self.source = self.rx.sink, self.tx.source + mac_port = mac.crossbar.get_port(ethernet_type_ip) + self.comb += [ + 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 diff --git a/liteeth/mac/__init__.py b/liteeth/mac/__init__.py index 320f32b1..b46b501b 100644 --- a/liteeth/mac/__init__.py +++ b/liteeth/mac/__init__.py @@ -1,8 +1,9 @@ from liteeth.common import * -from liteeth.mac.core import LiteEthMACCore -from liteeth.mac.frontend import wishbone from liteeth.generic.depacketizer import LiteEthDepacketizer from liteeth.generic.packetizer import LiteEthPacketizer +from liteeth.mac.core import LiteEthMACCore +from liteeth.mac.frontend.wishbone import LiteEthMACWishboneInterface +from liteeth.mac.frontend.crossbar import LiteEthMACCrossbar class LiteEthMACDepacketizer(LiteEthDepacketizer): def __init__(self): @@ -21,20 +22,20 @@ class LiteEthMACPacketizer(LiteEthPacketizer): mac_header_len) class LiteEthMAC(Module, AutoCSR): - def __init__(self, phy, dw, interface="mac", endianness="be", + def __init__(self, phy, dw, interface="crossbar", endianness="be", with_hw_preamble_crc=True): self.submodules.core = LiteEthMACCore(phy, dw, endianness, with_hw_preamble_crc) self.csrs = None - if interface == "mac": - packetizer = LiteEthMACPacketizer() - depacketizer = LiteEthMACDepacketizer() - self.submodules += packetizer, depacketizer + if interface == "crossbar": + self.submodules.crossbar = LiteEthMACCrossbar() + self.submodules.packetizer = LiteEthMACPacketizer() + self.submodules.depacketizer = LiteEthMACDepacketizer() self.comb += [ - Record.connect(packetizer.source, self.core.sink), - Record.connect(self.core.source, depacketizer.sink) + Record.connect(self.crossbar.master.source, self.packetizer.sink), + Record.connect(self.packetizer.source, self.core.sink), + Record.connect(self.core.source, self.depacketizer.sink), + Record.connect(self.depacketizer.source, self.crossbar.master.sink) ] - self.sink, self.source = packetizer.sink, depacketizer.source - pass elif interface == "wishbone": self.submodules.interface = wishbone.LiteEthMACWishboneInterface(dw, 2, 2) self.comb += [ diff --git a/liteeth/mac/frontend/common.py b/liteeth/mac/frontend/common.py new file mode 100644 index 00000000..b945ded4 --- /dev/null +++ b/liteeth/mac/frontend/common.py @@ -0,0 +1,27 @@ +from liteeth.common import * + +class LiteEthMACMasterPort: + def __init__(self, dw): + self.source = Source(eth_mac_description(dw)) + self.sink = Sink(eth_mac_description(dw)) + + def connect(self, slave): + return [ + Record.connect(self.source, slave.sink), + Record.connect(slave.source, self.sink) + ] + +class LiteEthMACSlavePort: + def __init__(self, dw): + self.sink = Sink(eth_mac_description(dw)) + self.source = Source(eth_mac_description(dw)) + + def connect(self, master): + return [ + Record.connect(self.sink, master.source), + Record.connect(master.sink, self.source) + ] + +class LiteEthMACUserPort(LiteEthMACSlavePort): + def __init__(self, dw): + LiteEthMACSlavePort.__init__(self, dw) diff --git a/liteeth/mac/frontend/crossbar.py b/liteeth/mac/frontend/crossbar.py new file mode 100644 index 00000000..696e353e --- /dev/null +++ b/liteeth/mac/frontend/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.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 {} already used") + 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) diff --git a/liteeth/test/arp_tb.py b/liteeth/test/arp_tb.py index 27e34a4a..89f6fe9c 100644 --- a/liteeth/test/arp_tb.py +++ b/liteeth/test/arp_tb.py @@ -19,8 +19,8 @@ class TB(Module): self.submodules.mac_model = mac.MAC(self.phy_model, debug=True, loopback=False) self.submodules.arp_model = arp.ARP(self.mac_model, mac_address, ip_address, debug=True) - self.submodules.core = LiteEthMAC(phy=self.phy_model, dw=8, with_hw_preamble_crc=True) - self.submodules.arp = LiteEthARP(mac_address, ip_address) + self.submodules.mac = LiteEthMAC(self.phy_model, dw=8, with_hw_preamble_crc=True) + self.submodules.arp = LiteEthARP(self.mac, mac_address, ip_address) # use sys_clk for each clock_domain self.clock_domains.cd_eth_rx = ClockDomain() @@ -32,11 +32,6 @@ class TB(Module): self.cd_eth_tx.rst.eq(ResetSignal()), ] - self.comb += [ - Record.connect(self.arp.source, self.core.sink), - Record.connect(self.core.source, self.arp.sink) - ] - def gen_simulation(self, selfp): selfp.cd_eth_rx.rst = 1 selfp.cd_eth_tx.rst = 1 @@ -55,6 +50,7 @@ class TB(Module): while selfp.arp.table.response.stb != 1: selfp.arp.table.response.ack = 1 yield + print("Model MAC : 0x%12x" %selfp.arp.table.response.mac_address) if __name__ == "__main__": diff --git a/liteeth/test/ip_tb.py b/liteeth/test/ip_tb.py index fa751b60..83a20055 100644 --- a/liteeth/test/ip_tb.py +++ b/liteeth/test/ip_tb.py @@ -40,9 +40,9 @@ class TB(Module): for i in range(100): yield - #selfp.ip.sink.stb = 1 - #selfp.ip.sink.destination_ip_address = 0x12345678 - #selfp.ip.sink.source_ip_address = ip_address + selfp.ip.sink.stb = 1 + selfp.ip.sink.destination_ip_address = 0x12345678 + selfp.ip.sink.source_ip_address = ip_address if __name__ == "__main__": run_simulation(TB(), ncycles=2048, vcd_name="my.vcd", keep_files=True) -- 2.30.2