mac: add crossbar to simplify usage
This commit is contained in:
parent
1d447f2ae1
commit
124a041fbd
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
]
|
||||
|
|
|
@ -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))])
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 += [
|
||||
|
|
|
@ -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)
|
|
@ -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)
|
|
@ -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__":
|
||||
|
|
|
@ -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)
|
||||
|
|
Loading…
Reference in New Issue