+from liteeth.common import *
+from liteeth.generic.arbiter import Arbiter
+from liteeth.generic.dispatcher import Dispatcher
+from liteeth.mac import LiteEthMAC
+
+class LiteEthIPStack(Module, AutoCSR):
+ def __init__(self, phy):
+ self.phy = phy
+ self.submodules.mac = mac = LiteEthMAC(phy, 8, interface="mac", with_hw_preamble_crc=True)
+ self.submodules.arp = arp = LiteEthARP()
+ self.submodules.ip = ip = LiteEthMACIP()
+
+ # MAC dispatch
+ self.submodules.unknown_sink = unknown_sink = Sink(eth_mac_description(8))
+ self.comb += unknown_sink.ack.eq(1)
+ self.submodules.mac_dispatcher = mac_dispatcher = Dispatcher(mac.source, [arp.sink, ip.sink, unknown_sink])
+ self.comb += [
+ If(mac.source.eth_type == ethernet_type_arp,
+ mac_dispatcher.sel.eq(0)
+ ).Elif(mac.source.eth_type == ethernet_type_ip,
+ mac_dispatcher.sel.eq(1)
+ ).Else(
+ mac_dispatcher.sel.eq(2) # connect to unknown sink that always acknowledge data
+ )
+ ]
+ # MAC arbitrate
+ self.submodules.mac_arbiter = mac_arbiter = Arbiter([arp.source, ip.source], mac.sink)
+
+
"ethernet_type": HField(12, 0, 16)
}
+ethernet_type_ip = 0x800
+ethernet_type_arp = 0x806
+
arp_header_len = 28
arp_header = {
"hardware_type": HField( 0, 0, 16),
--- /dev/null
+from migen.fhdl.std import *
+from migen.genlib.roundrobin import *
+from migen.genlib.record import *
+
+class Arbiter(Module):
+ def __init__(self, sources, sink):
+ if len(sources) == 0:
+ pass
+ elif len(sources) == 1:
+ self.grant = Signal()
+ self.comb += Record.connect(sources[0], sink)
+ else:
+ self.rr = RoundRobin(len(sources))
+ self.grant = self.rr.grant
+ cases = {}
+ for i, source in enumerate(sources):
+ sop = Signal()
+ eop = Signal()
+ ongoing = Signal()
+ self.comb += [
+ sop.eq(source.stb & source.sop),
+ eop.eq(source.stb & source.eop & source.ack),
+ ]
+ self.sync += ongoing.eq((sop | ongoing) & ~eop)
+ self.comb += self.rr.request[i].eq((sop | ongoing) & ~eop)
+ cases[i] = [Record.connect(source, sink)]
+ self.comb += Case(self.grant, cases)
--- /dev/null
+from migen.fhdl.std import *
+from migen.genlib.record import *
+
+class Dispatcher(Module):
+ def __init__(self, source, sinks, one_hot=False):
+ if len(sinks) == 0:
+ self.sel = Signal()
+ elif len(sinks) == 1:
+ self.comb += Record.connect(source, sinks[0])
+ self.sel = Signal()
+ else:
+ if one_hot:
+ self.sel = Signal(len(sinks))
+ else:
+ self.sel = Signal(max=len(sinks))
+ ###
+ sop = Signal()
+ self.comb += sop.eq(source.stb & source.sop)
+ sel = Signal(max=len(sinks))
+ sel_r = Signal(max=len(sinks))
+ self.sync += \
+ If(sop,
+ sel_r.eq(self.sel)
+ )
+ self.comb += \
+ If(sop,
+ sel.eq(self.sel)
+ ).Else(
+ sel.eq(sel_r)
+ )
+ cases = {}
+ for i, sink in enumerate(sinks):
+ if one_hot:
+ idx = 2**i
+ else:
+ idx = i
+ cases[idx] = [Record.connect(source, sink)]
+ cases["default"] = [source.ack.eq(1)]
+ self.comb += Case(sel, cases)
mac_header_length)
class LiteEthMAC(Module, AutoCSR):
- def __init__(self, phy, dw, interface="core", endianness="be",
+ def __init__(self, phy, dw, interface="mac", endianness="be",
with_hw_preamble_crc=True):
self.submodules.core = LiteEthMACCore(phy, dw, endianness, with_hw_preamble_crc)
self.csrs = None
- if interface == "core":
- self.sink, self.source = self.core.sink, self.core.source
+ if interface == "mac":
+ packetizer = LiteEthMACPacketizer()
+ depacketizer = LiteEthMACDepacketizer()
+ self.submodules += packetizer, depacketizer
+ self.comb += [
+ Record.connect(packetizer.source, self.core.sink),
+ Record.connect(self.core.source, depacketizer.sink)
+ ]
+ self.sink, self.source = packetizer.sink, depacketizer.source
elif interface == "wishbone":
self.submodules.interface = wishbone.LiteEthMACWishboneInterface(dw, 2, 2)
self.comb += [
from migen.sim.generic import run_simulation
from liteeth.common import *
-from liteeth.mac import LiteEthMAC
+from liteeth.mac.core import LiteEthMACCore
from liteeth.test.common import *
from liteeth.test.model import phy, mac
def __init__(self):
self.submodules.hostphy = phy.PHY(8, debug=False)
self.submodules.hostmac = mac.MAC(self.hostphy, debug=False, loopback=True)
- self.submodules.ethmac = LiteEthMAC(phy=self.hostphy, dw=32, interface="core", with_hw_preamble_crc=True)
+ self.submodules.core = LiteEthMACCore(phy=self.hostphy, dw=32, with_hw_preamble_crc=True)
self.submodules.streamer = PacketStreamer(eth_phy_description(32), last_be=1)
self.submodules.streamer_randomizer = AckRandomizer(eth_phy_description(32), level=50)
self.comb += [
Record.connect(self.streamer.source, self.streamer_randomizer.sink),
- Record.connect(self.streamer_randomizer.source, self.ethmac.sink),
- Record.connect(self.ethmac.source, self.logger_randomizer.sink),
+ Record.connect(self.streamer_randomizer.source, self.core.sink),
+ Record.connect(self.core.source, self.logger_randomizer.sink),
Record.connect(self.logger_randomizer.source, self.logger.sink)
]