from migen.fhdl.std import *
from migen.fhdl.std import *
-from migen.flow.actor import Sink, Source
-from migen.bank.description import *
from migen.genlib.resetsync import AsyncResetSynchronizer
+from migen.genlib.record import *
+from migen.genlib.fsm import FSM, NextState
from migen.flow.actor import EndpointDescription
+from migen.flow.actor import Sink, Source
+from migen.actorlib.structuring import Converter, Pipeline
+from migen.actorlib.fifo import SyncFIFO, AsyncFIFO
+from migen.bank.description import *
eth_mtu = 1532
eth_preamble = 0xD555555555555555
buffer_depth = 2**log2_int(eth_mtu, need_pow2=False)
-def eth_description(dw):
+def eth_phy_description(dw):
+ layout = [
+ ("data", dw),
+ ("error", dw//8)
+ ]
+ return EndpointDescription(layout, packetized=True)
+
+def eth_mac_description(dw):
layout = [
- ("d", dw),
+ ("data", dw),
("last_be", dw//8),
("error", dw//8)
]
from liteeth.mac.frontend import wishbone
class LiteEthMAC(Module, AutoCSR):
- def __init__(self, phy, interface="wishbone", dw, endianness="be",
+ def __init__(self, phy, dw, interface="wishbone", endianness="be",
with_hw_preamble_crc=True):
- self.submodules.core = LiteEthMACCore(phy, endianness, with_hw_preamble)
+ self.submodules.core = LiteEthMACCore(phy, dw, endianness, with_hw_preamble_crc)
+ self.csrs = None
if interface == "wishbone":
- self.interface = wishbone.LiteETHMACWishboneInterface(), dw, nrxslots, ntxslots)
+ self.interface = wishbone.LiteEthMACWishboneInterface(dw, 2, 2)
+ self.ev, self.bus = self.interface.sram.ev, self.interface.bus
+ self.csrs = self.interface.get_csrs()
elif interface == "dma":
raise NotImplementedError
elif interface == "core":
- self.sink = self.core.sink
- self.source = self.core.source
+ self.sink, self.source = self.core.sink, self.core.source
else:
raise ValueError("EthMAC only supports Wishbone, DMA or core interfaces")
+
+ def get_csrs(self):
+ return self.csrs
from liteeth.common import *
from liteeth.mac.common import *
-from liteeth.mac import preamble, crc, last_be
+from liteeth.mac.core import preamble, crc, last_be
class LiteEthMACCore(Module, AutoCSR):
def __init__(self, phy, dw, endianness="be", with_hw_preamble_crc=True):
- if dw > phy.dw:
- raise ValueError("Core data width must be larger than PHY data width")
+ if dw < phy.dw:
+ raise ValueError("Core data width({}) must be larger than PHY data width({})".format(dw, phy.dw))
# Preamble / CRC (optional)
if with_hw_preamble_crc:
self._hw_preamble_crc = CSRStatus(reset=1)
# Converters
reverse = endianness == "be"
- tx_converter = Converter(eth_description(dw), eth_description(phy.dw), reverse=reverse)
- rx_converter = Converter(eth_description(phy.dw), eth_description(dw), reverse=reverse)
+ tx_converter = Converter(eth_mac_description(dw), eth_mac_description(phy.dw), reverse=reverse)
+ rx_converter = Converter(eth_mac_description(phy.dw), eth_mac_description(dw), reverse=reverse)
self.submodules += RenameClockDomains(tx_converter, "eth_tx")
self.submodules += RenameClockDomains(rx_converter, "eth_rx")
# Cross Domain Crossing
- tx_cdc = AsyncFIFO(eth_description(dw), 4)
- rx_cdc = AsyncFIFO(eth_description(dw), 4)
+ tx_cdc = AsyncFIFO(eth_mac_description(dw), 4)
+ rx_cdc = AsyncFIFO(eth_mac_description(dw), 4)
self.submodules += RenameClockDomains(tx_cdc, {"write": "sys", "read": "eth_tx"})
self.submodules += RenameClockDomains(rx_cdc, {"write": "eth_rx", "read": "sys"})
Parameters
----------
- dat_width : int
+ data_width : int
Width of the data bus.
width : int
Width of the CRC.
Attributes
----------
- d : in
+ data : in
Data input.
last : in
last CRC value.
next :
next CRC value.
"""
- def __init__(self, dat_width, width, polynom):
- self.d = Signal(dat_width)
+ def __init__(self, data_width, width, polynom):
+ self.data = Signal(data_width)
self.last = Signal(width)
self.next = Signal(width)
# compute and optimize CRC's LFSR
curval = [[("state", i)] for i in range(width)]
- for i in range(dat_width):
+ for i in range(data_width):
feedback = curval.pop() + [("din", i)]
for j in range(width-1):
if (polynom & (1<<(j+1))):
if t == "state":
xors += [self.last[n]]
elif t == "din":
- xors += [self.d[n]]
+ xors += [self.data[n]]
self.comb += self.next[i].eq(optree("^", xors))
@DecorateModule(InsertReset)
Parameters
----------
- dat_width : int
+ data_width : int
Width of the data bus.
Attributes
polynom = 0x04C11DB7
init = 2**width-1
check = 0xC704DD7B
- def __init__(self, dat_width):
- self.d = Signal(dat_width)
+ def __init__(self, data_width):
+ self.data = Signal(data_width)
self.value = Signal(self.width)
self.error = Signal()
###
- self.submodules.engine = LiteEthCRCEngine(dat_width, self.width, self.polynom)
+ self.submodules.engine = LiteEthCRCEngine(data_width, self.width, self.polynom)
reg = Signal(self.width, reset=self.init)
self.sync += reg.eq(self.engine.next)
self.comb += [
- self.engine.d.eq(self.d),
+ self.engine.data.eq(self.data),
self.engine.last.eq(reg),
self.value.eq(~reg[::-1]),
Parameters
----------
- layout : layout
- Layout of the dataflow.
+ description : description
+ description of the dataflow.
Attributes
----------
source : out
Packets output with CRC.
"""
- def __init__(self, crc_class, layout):
- self.sink = sink = Sink(layout)
- self.source = source = Source(layout)
+ def __init__(self, crc_class, description):
+ self.sink = sink = Sink(description)
+ self.source = source = Source(description)
self.busy = Signal()
###
- dw = flen(sink.d)
+ dw = flen(sink.data)
crc = crc_class(dw)
fsm = FSM(reset_state="IDLE")
self.submodules += crc, fsm
)
fsm.act("COPY",
crc.ce.eq(sink.stb & source.ack),
- crc.d.eq(sink.d),
+ crc.data.eq(sink.data),
Record.connect(sink, source),
source.eop.eq(0),
If(sink.stb & sink.eop & source.ack,
cnt_done = Signal()
fsm.act("INSERT",
source.stb.eq(1),
- chooser(crc.value, cnt, source.d, reverse=True),
+ chooser(crc.value, cnt, source.data, reverse=True),
If(cnt_done,
source.eop.eq(1),
If(source.ack, NextState("IDLE"))
fsm.act("INSERT",
source.stb.eq(1),
source.eop.eq(1),
- source.d.eq(crc.value),
+ source.data.eq(crc.value),
If(source.ack, NextState("IDLE"))
)
self.comb += self.busy.eq(~fsm.ongoing("IDLE"))
-class LiteEthMACCRC32Inserter(CRCInserter):
- def __init__(self, layout):
- LiteEthMACCRCInserter.__init__(self, LiteEthMACCRC32, layout)
+class LiteEthMACCRC32Inserter(LiteEthMACCRCInserter):
+ def __init__(self, description):
+ LiteEthMACCRCInserter.__init__(self, LiteEthMACCRC32, description)
class LiteEthMACCRCChecker(Module):
"""CRC Checker
Parameters
----------
- layout : layout
- Layout of the dataflow.
+ description : description
+ description of the dataflow.
Attributes
----------
Packets output without CRC and "error" set to 0
on eop when CRC OK / set to 1 when CRC KO.
"""
- def __init__(self, crc_class, layout):
- self.sink = sink = Sink(layout)
- self.source = source = Source(layout)
+ def __init__(self, crc_class, description):
+ self.sink = sink = Sink(description)
+ self.source = source = Source(description)
self.busy = Signal()
###
- dw = flen(sink.d)
+ dw = flen(sink.data)
crc = crc_class(dw)
self.submodules += crc
ratio = crc.width//dw
error = Signal()
- fifo = InsertReset(SyncFIFO(layout, ratio + 1))
+ fifo = InsertReset(SyncFIFO(description, ratio + 1))
self.submodules += fifo
fsm = FSM(reset_state="RESET")
NextState("IDLE"),
)
fsm.act("IDLE",
- crc.d.eq(sink.d),
+ crc.d.eq(sink.data),
If(sink.stb & sink.sop & sink.ack,
crc.ce.eq(1),
NextState("COPY")
)
)
fsm.act("COPY",
- crc.d.eq(sink.d),
+ crc.d.eq(sink.data),
If(sink.stb & sink.ack,
crc.ce.eq(1),
If(sink.eop,
)
self.comb += self.busy.eq(~fsm.ongoing("IDLE"))
-class LiteEthMACCRC32Checker(CRCChecker):
- def __init__(self, layout):
- LiteEthMACCRCChecker.__init__(self, LiteEthMACCRC32, layout)
+class LiteEthMACCRC32Checker(LiteEthMACCRCChecker):
+ def __init__(self, description):
+ LiteEthMACCRCChecker.__init__(self, LiteEthMACCRC32, description)
from liteeth.mac.common import *
class LiteEthMACTXLastBE(Module):
- def __init__(self, d_w):
- self.sink = sink = Sink(eth_description(d_w))
- self.source = source = Source(eth_description(d_w))
-
+ def __init__(self, dw):
+ self.sink = sink = Sink(eth_mac_description(dw))
+ self.source = source = Source(eth_phy_description(dw))
###
-
ongoing = Signal()
self.sync += \
- If(self.sink.stb & self.sink.ack,
+ If(sink.stb & sink.ack,
If(sink.sop,
ongoing.eq(1)
).Elif(sink.last_be,
)
)
self.comb += [
- Record.connect(self.sink, self.source),
- self.source.eop.eq(self.sink.last_be),
- self.source.stb.eq(self.sink.stb & (self.sink.sop | ongoing))
+ source.stb.eq(sink.stb & (sink.sop | ongoing)),
+ source.sop.eq(sink.sop),
+ source.eop.eq(sink.last_be),
+ source.data.eq(sink.data),
+ sink.ack.eq(source.ack)
]
class LiteEthMACRXLastBE(Module):
- def __init__(self, d_w):
- self.sink = sink = Sink(eth_description(d_w))
- self.source = source = Source(eth_description(d_w))
-
+ def __init__(self, dw):
+ self.sink = sink = Sink(eth_phy_description(dw))
+ self.source = source = Source(eth_mac_description(dw))
###
-
self.comb += [
- Record.connect(self.sink, self.source),
- self.source.last_be.eq(self.sink.eop)
+ source.stb.eq(sink.stb),
+ source.sop.eq(sink.sop),
+ source.eop.eq(sink.eop),
+ source.data.eq(sink.data),
+ source.last_be.eq(sink.eop),
+ sink.ack.eq(source.ack)
]
from liteeth.mac.common import *
class LiteEthMACPreambleInserter(Module):
- def __init__(self, d_w):
- self.sink = Sink(eth_description(d_w))
- self.source = Source(eth_description(d_w))
+ def __init__(self, dw):
+ self.sink = Sink(eth_phy_description(dw))
+ self.source = Source(eth_phy_description(dw))
###
preamble = Signal(64, reset=eth_preamble)
- cnt_max = (64//d_w)-1
+ cnt_max = (64//dw)-1
cnt = Signal(max=cnt_max+1)
clr_cnt = Signal()
inc_cnt = Signal()
fsm.act("INSERT",
self.source.stb.eq(1),
self.source.sop.eq(cnt==0),
- chooser(preamble, cnt, self.source.d),
+ chooser(preamble, cnt, self.source.data),
If(cnt == cnt_max,
If(self.source.ack, NextState("COPY"))
).Else(
)
class LiteEthMACPreambleChecker(Module):
- def __init__(self, d_w):
- self.sink = Sink(eth_description(d_w))
- self.source = Source(eth_description(d_w))
+ def __init__(self, dw):
+ self.sink = Sink(eth_phy_description(dw))
+ self.source = Source(eth_phy_description(dw))
###
preamble = Signal(64, reset=eth_preamble)
- cnt_max = (64//d_w) - 1
+ cnt_max = (64//dw) - 1
cnt = Signal(max=cnt_max+1)
clr_cnt = Signal()
inc_cnt = Signal()
sop.eq(1)
)
- ref = Signal(d_w)
+ ref = Signal(dw)
match = Signal()
self.comb += [
chooser(preamble, cnt, ref),
- match.eq(self.sink.d == ref)
+ match.eq(self.sink.data == ref)
]
fsm = FSM(reset_state="IDLE")
from liteeth.common import *
from liteeth.mac.common import *
+from migen.bank.description import *
+from migen.bank.eventmanager import *
+
class LiteEthMACSRAMWriter(Module, AutoCSR):
def __init__(self, dw, depth, nslots=2):
- self.sink = sink = Sink(eth_description(dw))
+ self.sink = sink = Sink(eth_mac_description(dw))
self.crc_error = Signal()
slotbits = max(log2_int(nslots), 1)
inc_cnt.eq(sink.stb),
If(sink.stb & sink.sop,
ongoing.eq(1),
- If(fifo.writable,
+ If(fifo.sink.ack,
NextState("WRITE")
)
)
fsm.act("TERMINATE",
clr_cnt.eq(1),
inc_slot.eq(1),
- fifo.we.eq(1),
- fifo.din.slot.eq(slot),
- fifo.din.length.eq(cnt),
+ fifo.sink.stb.eq(1),
+ fifo.sink.slot.eq(slot),
+ fifo.sink.length.eq(cnt),
NextState("IDLE")
)
self.comb += [
- fifo.re.eq(self.ev.available.clear),
- self.ev.available.trigger.eq(fifo.readable),
- self._slot.status.eq(fifo.dout.slot),
- self._length.status.eq(fifo.dout.length),
+ fifo.source.ack.eq(self.ev.available.clear),
+ self.ev.available.trigger.eq(fifo.source.stb),
+ self._slot.status.eq(fifo.source.slot),
+ self._length.status.eq(fifo.source.length),
]
# memory
for n, port in enumerate(ports):
cases[n] = [
ports[n].adr.eq(cnt[2:]),
- ports[n].dat_w.eq(sink.d),
+ ports[n].dat_w.eq(sink.data),
If(sink.stb & ongoing,
ports[n].we.eq(0xf)
)
class LiteEthMACSRAMReader(Module, AutoCSR):
def __init__(self, dw, depth, nslots=2):
- self.source = source = Source(eth_description(dw))
+ self.source = source = Source(eth_mac_description(dw))
slotbits = max(log2_int(nslots), 1)
lengthbits = log2_int(depth*4) # length in bytes
fifo = SyncFIFO([("slot", slotbits), ("length", lengthbits)], nslots)
self.submodules += fifo
self.comb += [
- fifo.we.eq(self._start.re),
- fifo.din.slot.eq(self._slot.storage),
- fifo.din.length.eq(self._length.storage),
- self._ready.status.eq(fifo.writable)
+ fifo.sink.stb.eq(self._start.re),
+ fifo.sink.slot.eq(self._slot.storage),
+ fifo.sink.length.eq(self._length.storage),
+ self._ready.status.eq(fifo.sink.ack)
]
# length computation
fsm.act("IDLE",
clr_cnt.eq(1),
- If(fifo.readable,
+ If(fifo.source.stb,
NextState("CHECK")
)
)
NextState("END"),
)
)
- length_lsb = fifo.dout.length[0:2]
+ length_lsb = fifo.source.length[0:2]
fsm.act("SEND",
source.stb.eq(1),
source.sop.eq(first),
)
)
fsm.act("END",
- fifo.re.eq(1),
+ fifo.source.ack.eq(1),
self.ev.done.trigger.eq(1),
NextState("IDLE")
)
first.eq(0)
)
]
- self.comb += last.eq(cnt + 4 >= fifo.dout.length)
+ self.comb += last.eq(cnt + 4 >= fifo.source.length)
self.sync += last_d.eq(last)
# memory
- rd_slot = fifo.dout.slot
+ rd_slot = fifo.source.slot
mems = [None]*nslots
ports = [None]*nslots
cases = {}
for n, port in enumerate(ports):
self.comb += ports[n].adr.eq(cnt[2:])
- cases[n] = [source.d.eq(port.dat_r)]
+ cases[n] = [source.data.eq(port.dat_r)]
self.comb += Case(rd_slot, cases)
-class LiteMACEthMACSRAM(Module, AutoCSR):
+class LiteEthMACSRAM(Module, AutoCSR):
def __init__(self, dw, depth, nrxslots, ntxslots):
- self.submodules.writer = LiteEthSRAMWriter(dw, depth, nrxslots)
- self.submodules.reader = LiteEthSRAMReader(dw, depth, ntxslots)
+ self.submodules.writer = LiteEthMACSRAMWriter(dw, depth, nrxslots)
+ self.submodules.reader = LiteEthMACSRAMReader(dw, depth, ntxslots)
self.submodules.ev = SharedIRQ(self.writer.ev, self.reader.ev)
- self.sink, self.source = self.witer.sink, self.reader.source
+ self.sink, self.source = self.writer.sink, self.reader.source
from liteeth.mac.common import *
from liteeth.mac.frontend import sram
+from migen.bus import wishbone
+from migen.fhdl.simplify import FullMemoryWE
+
class LiteEthMACWishboneInterface(Module, AutoCSR):
def __init__(self, dw, nrxslots=2, ntxslots=2):
- self.sink = Sink(mac_description(dw))
- self.source = Source(max_description(dw))
+ self.sink = Sink(eth_mac_description(dw))
+ self.source = Source(eth_mac_description(dw))
self.bus = wishbone.Interface()
###
# storage in SRAM
]
# Wishbone interface
- wb_rx_sram_ifs = [wishbone.SRAM(self.sram_writer.mems[n], read_only=True)
+ wb_rx_sram_ifs = [wishbone.SRAM(self.sram.writer.mems[n], read_only=True)
for n in range(nrxslots)]
# TODO: FullMemoryWE should move to Mibuild
- wb_tx_sram_ifs = [FullMemoryWE(wishbone.SRAM(self.sram_reader.mems[n], read_only=False))
+ wb_tx_sram_ifs = [FullMemoryWE(wishbone.SRAM(self.sram.reader.mems[n], read_only=False))
for n in range(ntxslots)]
wb_sram_ifs = wb_rx_sram_ifs + wb_tx_sram_ifs
class LiteEthPHYGMIITX(Module):
def __init__(self, pads):
- self.sink = sink = Sink(eth_description(8))
+ self.sink = sink = Sink(eth_phy_description(8))
###
self.sync += [
pads.tx_er.eq(0),
pads.tx_en.eq(sink.stb),
- pads.tx_data.eq(sink.d)
+ pads.tx_data.eq(sink.data)
]
self.comb += sink.ack.eq(1)
class LiteEthPHYGMIIRX(Module):
def __init__(self, pads):
- self.source = source = Source(eth_description(8))
+ self.source = source = Source(eth_phy_description(8))
###
dv_d = Signal()
self.sync += dv_d.eq(pads.dv)
self.sync += [
source.stb.eq(pads.dv),
source.sop.eq(sop),
- source.d.eq(pads.rx_data)
+ source.data.eq(pads.rx_data)
]
self.comb += source.eop.eq(eop)
AsyncResetSynchronizer(self.cd_eth_rx, reset),
]
-class LiteEthPHYMII(Module, AutoCSR):
+class LiteEthPHYGMII(Module, AutoCSR):
def __init__(self, clock_pads, pads):
self.dw = 8
self.submodules.crg = LiteEthPHYGMIICRG(clock_pads, pads)
def __init__(self):
self.dw = 8
self.submodules.crg = LiteEthLoopbackPHYCRG()
- self.sink = sink = Sink(eth_description(8))
- self.source = source = Source(eth_description(8))
+ self.sink = sink = Sink(eth_phy_description(8))
+ self.source = source = Source(eth_phy_description(8))
self.comb += Record.connect(self.sink, self.source)
class LiteEthPHYMIITX(Module):
def __init__(self, pads):
- self.sink = sink = Sink(eth_description(8))
+ self.sink = sink = Sink(eth_phy_description(8))
###
tx_en_r = Signal()
tx_data_r = Signal(4)
)
)
fsm.act("SEND_LO",
- tx_data_r.eq(sink.d[0:4]),
+ tx_data_r.eq(sink.data[0:4]),
tx_en_r.eq(1),
NextState("SEND_HI")
)
fsm.act("SEND_HI",
- tx_data_r.eq(sink.d[4:8]),
+ tx_data_r.eq(sink.data[4:8]),
tx_en_r.eq(1),
sink.ack.eq(1),
If(sink.stb & sink.eop,
class LiteEthPHYMIIRX(Module):
def __init__(self, pads):
- self.source = source = Source(eth_description(8))
+ self.source = source = Source(eth_phy_description(8))
###
sop = source.sop
set_sop = Signal()
hi.eq(pads.rx_data)
)
self.comb += [
- source.d.eq(Cat(lo, hi))
+ source.data.eq(Cat(lo, hi))
]
fsm = FSM(reset_state="IDLE")