create LiteEthIPStack skeleton
authorFlorent Kermarrec <florent@enjoy-digital.fr>
Thu, 29 Jan 2015 00:03:47 +0000 (01:03 +0100)
committerFlorent Kermarrec <florent@enjoy-digital.fr>
Thu, 29 Jan 2015 00:03:47 +0000 (01:03 +0100)
liteeth/__init__.py
liteeth/common.py
liteeth/generic/arbiter.py [new file with mode: 0644]
liteeth/generic/dispatcher.py [new file with mode: 0644]
liteeth/mac/__init__.py
liteeth/test/mac_core_tb.py

index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..a67e5b3806e73a566ffa98a23128b26ce527e960 100644 (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)
+
+
index 2fc2660f777cdf9b5094d3396a90d5fa98c5735f..d66e7c190aca2d3969a916183be9aa8cbc0a1ef5 100644 (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),
diff --git a/liteeth/generic/arbiter.py b/liteeth/generic/arbiter.py
new file mode 100644 (file)
index 0000000..f61182b
--- /dev/null
@@ -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)
diff --git a/liteeth/generic/dispatcher.py b/liteeth/generic/dispatcher.py
new file mode 100644 (file)
index 0000000..713dd61
--- /dev/null
@@ -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)
index a983c301cbafaaba0465e7ab7c1f2ef31acf7d2a..510faa77a4b9bce44b4d2c1b3780b71ff7925adf 100644 (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 += [
index fe1e42853cc85b417edc46a9550d374d213c24e9..33680bec08862a17a784100604f0106b479f530b 100644 (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)
                ]