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
)
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()
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)
+ ]
}
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))])
)
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
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):
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 += [
--- /dev/null
+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)
--- /dev/null
+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)
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()
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
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__":
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)