create LiteEthIPStack skeleton

This commit is contained in:
Florent Kermarrec 2015-01-29 01:03:47 +01:00
parent 5b37068393
commit 51c9f84ef0
6 changed files with 112 additions and 7 deletions

View File

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

View File

@ -29,6 +29,9 @@ mac_header = {
"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),

View File

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

View File

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

View File

@ -21,12 +21,19 @@ class LiteEthMACPacketizer(LiteEthDepacketizer):
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 += [

View File

@ -4,7 +4,7 @@ from migen.bus.transactions import *
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
@ -13,7 +13,7 @@ class TB(Module):
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)
@ -33,8 +33,8 @@ class TB(Module):
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)
]