create LiteEthIPStack skeleton
This commit is contained in:
parent
5b37068393
commit
51c9f84ef0
|
@ -0,0 +1,29 @@
|
||||||
|
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)
|
||||||
|
|
||||||
|
|
|
@ -29,6 +29,9 @@ mac_header = {
|
||||||
"ethernet_type": HField(12, 0, 16)
|
"ethernet_type": HField(12, 0, 16)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ethernet_type_ip = 0x800
|
||||||
|
ethernet_type_arp = 0x806
|
||||||
|
|
||||||
arp_header_len = 28
|
arp_header_len = 28
|
||||||
arp_header = {
|
arp_header = {
|
||||||
"hardware_type": HField( 0, 0, 16),
|
"hardware_type": HField( 0, 0, 16),
|
||||||
|
|
|
@ -0,0 +1,27 @@
|
||||||
|
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)
|
|
@ -0,0 +1,39 @@
|
||||||
|
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)
|
|
@ -21,12 +21,19 @@ class LiteEthMACPacketizer(LiteEthDepacketizer):
|
||||||
mac_header_length)
|
mac_header_length)
|
||||||
|
|
||||||
class LiteEthMAC(Module, AutoCSR):
|
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):
|
with_hw_preamble_crc=True):
|
||||||
self.submodules.core = LiteEthMACCore(phy, dw, endianness, with_hw_preamble_crc)
|
self.submodules.core = LiteEthMACCore(phy, dw, endianness, with_hw_preamble_crc)
|
||||||
self.csrs = None
|
self.csrs = None
|
||||||
if interface == "core":
|
if interface == "mac":
|
||||||
self.sink, self.source = self.core.sink, self.core.source
|
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":
|
elif interface == "wishbone":
|
||||||
self.submodules.interface = wishbone.LiteEthMACWishboneInterface(dw, 2, 2)
|
self.submodules.interface = wishbone.LiteEthMACWishboneInterface(dw, 2, 2)
|
||||||
self.comb += [
|
self.comb += [
|
||||||
|
|
|
@ -4,7 +4,7 @@ from migen.bus.transactions import *
|
||||||
from migen.sim.generic import run_simulation
|
from migen.sim.generic import run_simulation
|
||||||
|
|
||||||
from liteeth.common import *
|
from liteeth.common import *
|
||||||
from liteeth.mac import LiteEthMAC
|
from liteeth.mac.core import LiteEthMACCore
|
||||||
|
|
||||||
from liteeth.test.common import *
|
from liteeth.test.common import *
|
||||||
from liteeth.test.model import phy, mac
|
from liteeth.test.model import phy, mac
|
||||||
|
@ -13,7 +13,7 @@ class TB(Module):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.submodules.hostphy = phy.PHY(8, debug=False)
|
self.submodules.hostphy = phy.PHY(8, debug=False)
|
||||||
self.submodules.hostmac = mac.MAC(self.hostphy, debug=False, loopback=True)
|
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 = PacketStreamer(eth_phy_description(32), last_be=1)
|
||||||
self.submodules.streamer_randomizer = AckRandomizer(eth_phy_description(32), level=50)
|
self.submodules.streamer_randomizer = AckRandomizer(eth_phy_description(32), level=50)
|
||||||
|
@ -33,8 +33,8 @@ class TB(Module):
|
||||||
|
|
||||||
self.comb += [
|
self.comb += [
|
||||||
Record.connect(self.streamer.source, self.streamer_randomizer.sink),
|
Record.connect(self.streamer.source, self.streamer_randomizer.sink),
|
||||||
Record.connect(self.streamer_randomizer.source, self.ethmac.sink),
|
Record.connect(self.streamer_randomizer.source, self.core.sink),
|
||||||
Record.connect(self.ethmac.source, self.logger_randomizer.sink),
|
Record.connect(self.core.source, self.logger_randomizer.sink),
|
||||||
Record.connect(self.logger_randomizer.source, self.logger.sink)
|
Record.connect(self.logger_randomizer.source, self.logger.sink)
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue