mac: add crossbar to simplify usage

This commit is contained in:
Florent Kermarrec 2015-01-30 16:27:56 +01:00
parent 1d447f2ae1
commit 124a041fbd
9 changed files with 95 additions and 40 deletions

View File

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

View File

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

View File

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

View File

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

View File

@ -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 += [

View File

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

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

View File

@ -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__":

View File

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