start code adaptation
This commit is contained in:
parent
0826811047
commit
8477974ef1
|
@ -0,0 +1,14 @@
|
||||||
|
from migen.fhdl.std import *
|
||||||
|
from migen.flow.actor import EndpointDescription
|
||||||
|
|
||||||
|
eth_mtu = 1532
|
||||||
|
eth_preamble = 0xD555555555555555
|
||||||
|
buffer_depth = 2**log2_int(eth_mtu, need_pow2=False)
|
||||||
|
|
||||||
|
def eth_description(dw):
|
||||||
|
layout = [
|
||||||
|
("d", dw),
|
||||||
|
("last_be", dw//8),
|
||||||
|
("error", dw//8)
|
||||||
|
]
|
||||||
|
return EndpointDescription(layout, packetized=True)
|
|
@ -1,66 +1,9 @@
|
||||||
# This file is Copyright (c) 2014 Florent Kermarrec <florent@enjoy-digital.fr>
|
from liteethernet.common import *
|
||||||
# License: BSD
|
from liteethernet.mac import LiteEthernetMAC
|
||||||
|
|
||||||
from migen.fhdl.std import *
|
class LiteEthernetMAC(Module, AutoCSR):
|
||||||
|
def __init__(self, phy, frontend="wishbone", with_hw_preamble_crc=True, endianness="be"):
|
||||||
from migen.bus import wishbone
|
self.submodules.core = LiteEthernetMAC(phy, with_hw_preamble, endianness)
|
||||||
from migen.actorlib.fifo import AsyncFIFO
|
|
||||||
from migen.actorlib.structuring import Converter, Pipeline
|
|
||||||
from migen.bank.eventmanager import SharedIRQ
|
|
||||||
from migen.bank.description import *
|
|
||||||
from migen.fhdl.simplify import *
|
|
||||||
|
|
||||||
from misoclib.ethmac.common import *
|
|
||||||
from misoclib.ethmac.preamble import PreambleInserter, PreambleChecker
|
|
||||||
from migen.actorlib.crc import CRC32Inserter, CRC32Checker
|
|
||||||
from misoclib.ethmac.last_be import TXLastBE, RXLastBE
|
|
||||||
from misoclib.ethmac.sram import SRAMWriter, SRAMReader
|
|
||||||
|
|
||||||
class EthMAC(Module, AutoCSR):
|
|
||||||
def __init__(self, phy, interface="wishbone", with_hw_preamble_crc=True, endianness="be"):
|
|
||||||
# Preamble / CRC (optional)
|
|
||||||
if with_hw_preamble_crc:
|
|
||||||
self._hw_preamble_crc = CSRStatus(reset=1)
|
|
||||||
# Preamble insert/check
|
|
||||||
preamble_inserter = PreambleInserter(phy.dw)
|
|
||||||
preamble_checker = PreambleChecker(phy.dw)
|
|
||||||
self.submodules += RenameClockDomains(preamble_inserter, "eth_tx")
|
|
||||||
self.submodules += RenameClockDomains(preamble_checker, "eth_rx")
|
|
||||||
|
|
||||||
# CRC insert/check
|
|
||||||
crc32_inserter = CRC32Inserter(eth_description(phy.dw))
|
|
||||||
crc32_checker = CRC32Checker(eth_description(phy.dw))
|
|
||||||
self.submodules += RenameClockDomains(crc32_inserter, "eth_tx")
|
|
||||||
self.submodules += RenameClockDomains(crc32_checker, "eth_rx")
|
|
||||||
|
|
||||||
# Delimiters
|
|
||||||
tx_last_be = TXLastBE(phy.dw)
|
|
||||||
rx_last_be = RXLastBE(phy.dw)
|
|
||||||
self.submodules += RenameClockDomains(tx_last_be, "eth_tx")
|
|
||||||
self.submodules += RenameClockDomains(rx_last_be, "eth_rx")
|
|
||||||
|
|
||||||
# Converters
|
|
||||||
reverse = endianness == "be"
|
|
||||||
tx_converter = Converter(eth_description(32), eth_description(phy.dw), reverse=reverse)
|
|
||||||
rx_converter = Converter(eth_description(phy.dw), eth_description(32), reverse=reverse)
|
|
||||||
self.submodules += RenameClockDomains(tx_converter, "eth_tx")
|
|
||||||
self.submodules += RenameClockDomains(rx_converter, "eth_rx")
|
|
||||||
|
|
||||||
# Cross Domain Crossing
|
|
||||||
tx_cdc = AsyncFIFO(eth_description(32), 4)
|
|
||||||
rx_cdc = AsyncFIFO(eth_description(32), 4)
|
|
||||||
self.submodules += RenameClockDomains(tx_cdc, {"write": "sys", "read": "eth_tx"})
|
|
||||||
self.submodules += RenameClockDomains(rx_cdc, {"write": "eth_rx", "read": "sys"})
|
|
||||||
|
|
||||||
# Graph
|
|
||||||
if with_hw_preamble_crc:
|
|
||||||
rx_pipeline = [phy, preamble_checker, crc32_checker, rx_last_be, rx_converter, rx_cdc]
|
|
||||||
tx_pipeline = [tx_cdc, tx_converter, tx_last_be, crc32_inserter, preamble_inserter, phy]
|
|
||||||
else:
|
|
||||||
rx_pipeline = [phy, rx_last_be, rx_converter, rx_cdc]
|
|
||||||
tx_pipeline = [tx_cdc, tx_converter, tx_last_be, phy]
|
|
||||||
self.submodules.rx_pipeline = Pipeline(*rx_pipeline)
|
|
||||||
self.submodules.tx_pipeline = Pipeline(*tx_pipeline)
|
|
||||||
|
|
||||||
if interface == "wishbone":
|
if interface == "wishbone":
|
||||||
nrxslots = 2
|
nrxslots = 2
|
||||||
|
|
|
@ -0,0 +1,54 @@
|
||||||
|
|
||||||
|
from liteethernet.common import *
|
||||||
|
from liteethernet.mac.common import *
|
||||||
|
from liteethernet.mac.preamble import PreambleInserter, PreambleChecker
|
||||||
|
from liteethernet.mac.crc import CRC32Inserter, CRC32Checker
|
||||||
|
from liteethernet.mac.last_be import TXLastBE, RXLastBE
|
||||||
|
|
||||||
|
class LiteEthernetMACCore(Module, AutoCSR):
|
||||||
|
def __init__(self, phy, with_hw_preamble_crc=True, endianness="be"):
|
||||||
|
# Preamble / CRC (optional)
|
||||||
|
if with_hw_preamble_crc:
|
||||||
|
self._hw_preamble_crc = CSRStatus(reset=1)
|
||||||
|
# Preamble insert/check
|
||||||
|
preamble_inserter = PreambleInserter(phy.dw)
|
||||||
|
preamble_checker = PreambleChecker(phy.dw)
|
||||||
|
self.submodules += RenameClockDomains(preamble_inserter, "eth_tx")
|
||||||
|
self.submodules += RenameClockDomains(preamble_checker, "eth_rx")
|
||||||
|
|
||||||
|
# CRC insert/check
|
||||||
|
crc32_inserter = CRC32Inserter(eth_description(phy.dw))
|
||||||
|
crc32_checker = CRC32Checker(eth_description(phy.dw))
|
||||||
|
self.submodules += RenameClockDomains(crc32_inserter, "eth_tx")
|
||||||
|
self.submodules += RenameClockDomains(crc32_checker, "eth_rx")
|
||||||
|
|
||||||
|
# Delimiters
|
||||||
|
tx_last_be = TXLastBE(phy.dw)
|
||||||
|
rx_last_be = RXLastBE(phy.dw)
|
||||||
|
self.submodules += RenameClockDomains(tx_last_be, "eth_tx")
|
||||||
|
self.submodules += RenameClockDomains(rx_last_be, "eth_rx")
|
||||||
|
|
||||||
|
# Converters
|
||||||
|
reverse = endianness == "be"
|
||||||
|
tx_converter = Converter(eth_description(32), eth_description(phy.dw), reverse=reverse)
|
||||||
|
rx_converter = Converter(eth_description(phy.dw), eth_description(32), reverse=reverse)
|
||||||
|
self.submodules += RenameClockDomains(tx_converter, "eth_tx")
|
||||||
|
self.submodules += RenameClockDomains(rx_converter, "eth_rx")
|
||||||
|
|
||||||
|
# Cross Domain Crossing
|
||||||
|
tx_cdc = AsyncFIFO(eth_description(32), 4)
|
||||||
|
rx_cdc = AsyncFIFO(eth_description(32), 4)
|
||||||
|
self.submodules += RenameClockDomains(tx_cdc, {"write": "sys", "read": "eth_tx"})
|
||||||
|
self.submodules += RenameClockDomains(rx_cdc, {"write": "eth_rx", "read": "sys"})
|
||||||
|
|
||||||
|
# Graph
|
||||||
|
if with_hw_preamble_crc:
|
||||||
|
rx_pipeline = [phy, preamble_checker, crc32_checker, rx_last_be, rx_converter, rx_cdc]
|
||||||
|
tx_pipeline = [tx_cdc, tx_converter, tx_last_be, crc32_inserter, preamble_inserter, phy]
|
||||||
|
else:
|
||||||
|
rx_pipeline = [phy, rx_last_be, rx_converter, rx_cdc]
|
||||||
|
tx_pipeline = [tx_cdc, tx_converter, tx_last_be, phy]
|
||||||
|
self.submodules.rx_pipeline = Pipeline(*rx_pipeline)
|
||||||
|
self.submodules.tx_pipeline = Pipeline(*tx_pipeline)
|
||||||
|
|
||||||
|
self.sink, self.source = self.tx_pipeline.sink, self.rx_pipeline.source
|
|
@ -0,0 +1,284 @@
|
||||||
|
from migen.fhdl.std import *
|
||||||
|
from migen.genlib.fsm import FSM, NextState
|
||||||
|
from migen.genlib.record import *
|
||||||
|
from migen.genlib.misc import optree, chooser
|
||||||
|
from migen.genlib.crc import *
|
||||||
|
from migen.flow.actor import Sink, Source
|
||||||
|
from migen.actorlib.fifo import SyncFIFO
|
||||||
|
|
||||||
|
from collections import OrderedDict
|
||||||
|
|
||||||
|
class CRCEngine(Module):
|
||||||
|
"""Cyclic Redundancy Check Engine
|
||||||
|
|
||||||
|
Compute next CRC value from last CRC value and data input using
|
||||||
|
an optimized asynchronous LFSR.
|
||||||
|
|
||||||
|
Parameters
|
||||||
|
----------
|
||||||
|
dat_width : int
|
||||||
|
Width of the data bus.
|
||||||
|
width : int
|
||||||
|
Width of the CRC.
|
||||||
|
polynom : int
|
||||||
|
Polynom of the CRC (ex: 0x04C11DB7 for IEEE 802.3 CRC)
|
||||||
|
|
||||||
|
Attributes
|
||||||
|
----------
|
||||||
|
d : in
|
||||||
|
Data input.
|
||||||
|
last : in
|
||||||
|
last CRC value.
|
||||||
|
next :
|
||||||
|
next CRC value.
|
||||||
|
"""
|
||||||
|
def __init__(self, dat_width, width, polynom):
|
||||||
|
self.d = Signal(dat_width)
|
||||||
|
self.last = Signal(width)
|
||||||
|
self.next = Signal(width)
|
||||||
|
|
||||||
|
###
|
||||||
|
|
||||||
|
def _optimize_eq(l):
|
||||||
|
"""
|
||||||
|
Replace even numbers of XORs in the equation
|
||||||
|
with an equivalent XOR
|
||||||
|
"""
|
||||||
|
d = OrderedDict()
|
||||||
|
for e in l:
|
||||||
|
if e in d:
|
||||||
|
d[e] += 1
|
||||||
|
else:
|
||||||
|
d[e] = 1
|
||||||
|
r = []
|
||||||
|
for key, value in d.items():
|
||||||
|
if value%2 != 0:
|
||||||
|
r.append(key)
|
||||||
|
return r
|
||||||
|
|
||||||
|
# compute and optimize CRC's LFSR
|
||||||
|
curval = [[("state", i)] for i in range(width)]
|
||||||
|
for i in range(dat_width):
|
||||||
|
feedback = curval.pop() + [("din", i)]
|
||||||
|
for j in range(width-1):
|
||||||
|
if (polynom & (1<<(j+1))):
|
||||||
|
curval[j] += feedback
|
||||||
|
curval[j] = _optimize_eq(curval[j])
|
||||||
|
curval.insert(0, feedback)
|
||||||
|
|
||||||
|
# implement logic
|
||||||
|
for i in range(width):
|
||||||
|
xors = []
|
||||||
|
for t, n in curval[i]:
|
||||||
|
if t == "state":
|
||||||
|
xors += [self.last[n]]
|
||||||
|
elif t == "din":
|
||||||
|
xors += [self.d[n]]
|
||||||
|
self.comb += self.next[i].eq(optree("^", xors))
|
||||||
|
|
||||||
|
@DecorateModule(InsertReset)
|
||||||
|
@DecorateModule(InsertCE)
|
||||||
|
class CRC32(Module):
|
||||||
|
"""IEEE 802.3 CRC
|
||||||
|
|
||||||
|
Implement an IEEE 802.3 CRC generator/checker.
|
||||||
|
|
||||||
|
Parameters
|
||||||
|
----------
|
||||||
|
dat_width : int
|
||||||
|
Width of the data bus.
|
||||||
|
|
||||||
|
Attributes
|
||||||
|
----------
|
||||||
|
d : in
|
||||||
|
Data input.
|
||||||
|
value : out
|
||||||
|
CRC value (used for generator).
|
||||||
|
error : out
|
||||||
|
CRC error (used for checker).
|
||||||
|
"""
|
||||||
|
width = 32
|
||||||
|
polynom = 0x04C11DB7
|
||||||
|
init = 2**width-1
|
||||||
|
check = 0xC704DD7B
|
||||||
|
def __init__(self, dat_width):
|
||||||
|
self.d = Signal(dat_width)
|
||||||
|
self.value = Signal(self.width)
|
||||||
|
self.error = Signal()
|
||||||
|
|
||||||
|
###
|
||||||
|
|
||||||
|
self.submodules.engine = CRCEngine(dat_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.last.eq(reg),
|
||||||
|
|
||||||
|
self.value.eq(~reg[::-1]),
|
||||||
|
self.error.eq(self.engine.next != self.check)
|
||||||
|
]
|
||||||
|
|
||||||
|
class CRCInserter(Module):
|
||||||
|
"""CRC Inserter
|
||||||
|
|
||||||
|
Append a CRC at the end of each packet.
|
||||||
|
|
||||||
|
Parameters
|
||||||
|
----------
|
||||||
|
layout : layout
|
||||||
|
Layout of the dataflow.
|
||||||
|
|
||||||
|
Attributes
|
||||||
|
----------
|
||||||
|
sink : in
|
||||||
|
Packets input without CRC.
|
||||||
|
source : out
|
||||||
|
Packets output with CRC.
|
||||||
|
"""
|
||||||
|
def __init__(self, crc_class, layout):
|
||||||
|
self.sink = sink = Sink(layout)
|
||||||
|
self.source = source = Source(layout)
|
||||||
|
self.busy = Signal()
|
||||||
|
|
||||||
|
###
|
||||||
|
|
||||||
|
dw = flen(sink.d)
|
||||||
|
crc = crc_class(dw)
|
||||||
|
fsm = FSM(reset_state="IDLE")
|
||||||
|
self.submodules += crc, fsm
|
||||||
|
|
||||||
|
fsm.act("IDLE",
|
||||||
|
crc.reset.eq(1),
|
||||||
|
sink.ack.eq(1),
|
||||||
|
If(sink.stb & sink.sop,
|
||||||
|
sink.ack.eq(0),
|
||||||
|
NextState("COPY"),
|
||||||
|
)
|
||||||
|
)
|
||||||
|
fsm.act("COPY",
|
||||||
|
crc.ce.eq(sink.stb & source.ack),
|
||||||
|
crc.d.eq(sink.d),
|
||||||
|
Record.connect(sink, source),
|
||||||
|
source.eop.eq(0),
|
||||||
|
If(sink.stb & sink.eop & source.ack,
|
||||||
|
NextState("INSERT"),
|
||||||
|
)
|
||||||
|
)
|
||||||
|
ratio = crc.width//dw
|
||||||
|
if ratio > 1:
|
||||||
|
cnt = Signal(max=ratio, reset=ratio-1)
|
||||||
|
cnt_done = Signal()
|
||||||
|
fsm.act("INSERT",
|
||||||
|
source.stb.eq(1),
|
||||||
|
chooser(crc.value, cnt, source.d, reverse=True),
|
||||||
|
If(cnt_done,
|
||||||
|
source.eop.eq(1),
|
||||||
|
If(source.ack, NextState("IDLE"))
|
||||||
|
)
|
||||||
|
)
|
||||||
|
self.comb += cnt_done.eq(cnt == 0)
|
||||||
|
self.sync += \
|
||||||
|
If(fsm.ongoing("IDLE"),
|
||||||
|
cnt.eq(cnt.reset)
|
||||||
|
).Elif(fsm.ongoing("INSERT") & ~cnt_done,
|
||||||
|
cnt.eq(cnt - source.ack)
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
fsm.act("INSERT",
|
||||||
|
source.stb.eq(1),
|
||||||
|
source.eop.eq(1),
|
||||||
|
source.d.eq(crc.value),
|
||||||
|
If(source.ack, NextState("IDLE"))
|
||||||
|
)
|
||||||
|
self.comb += self.busy.eq(~fsm.ongoing("IDLE"))
|
||||||
|
|
||||||
|
class CRC32Inserter(CRCInserter):
|
||||||
|
def __init__(self, layout):
|
||||||
|
CRCInserter.__init__(self, CRC32, layout)
|
||||||
|
|
||||||
|
class CRCChecker(Module):
|
||||||
|
"""CRC Checker
|
||||||
|
|
||||||
|
Check CRC at the end of each packet.
|
||||||
|
|
||||||
|
Parameters
|
||||||
|
----------
|
||||||
|
layout : layout
|
||||||
|
Layout of the dataflow.
|
||||||
|
|
||||||
|
Attributes
|
||||||
|
----------
|
||||||
|
sink : in
|
||||||
|
Packets input with CRC.
|
||||||
|
source : out
|
||||||
|
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)
|
||||||
|
self.busy = Signal()
|
||||||
|
|
||||||
|
###
|
||||||
|
|
||||||
|
dw = flen(sink.d)
|
||||||
|
crc = crc_class(dw)
|
||||||
|
self.submodules += crc
|
||||||
|
ratio = crc.width//dw
|
||||||
|
|
||||||
|
error = Signal()
|
||||||
|
fifo = InsertReset(SyncFIFO(layout, ratio + 1))
|
||||||
|
self.submodules += fifo
|
||||||
|
|
||||||
|
fsm = FSM(reset_state="RESET")
|
||||||
|
self.submodules += fsm
|
||||||
|
|
||||||
|
fifo_in = Signal()
|
||||||
|
fifo_out = Signal()
|
||||||
|
fifo_full = Signal()
|
||||||
|
|
||||||
|
self.comb += [
|
||||||
|
fifo_full.eq(fifo.fifo.level == ratio),
|
||||||
|
fifo_in.eq(sink.stb & (~fifo_full | fifo_out)),
|
||||||
|
fifo_out.eq(source.stb & source.ack),
|
||||||
|
|
||||||
|
Record.connect(sink, fifo.sink),
|
||||||
|
fifo.sink.stb.eq(fifo_in),
|
||||||
|
self.sink.ack.eq(fifo_in),
|
||||||
|
|
||||||
|
source.stb.eq(sink.stb & fifo_full),
|
||||||
|
source.sop.eq(fifo.source.sop),
|
||||||
|
source.eop.eq(sink.eop),
|
||||||
|
fifo.source.ack.eq(fifo_out),
|
||||||
|
source.payload.eq(fifo.source.payload),
|
||||||
|
|
||||||
|
source.error.eq(sink.error | crc.error),
|
||||||
|
]
|
||||||
|
|
||||||
|
fsm.act("RESET",
|
||||||
|
crc.reset.eq(1),
|
||||||
|
fifo.reset.eq(1),
|
||||||
|
NextState("IDLE"),
|
||||||
|
)
|
||||||
|
fsm.act("IDLE",
|
||||||
|
crc.d.eq(sink.d),
|
||||||
|
If(sink.stb & sink.sop & sink.ack,
|
||||||
|
crc.ce.eq(1),
|
||||||
|
NextState("COPY")
|
||||||
|
)
|
||||||
|
)
|
||||||
|
fsm.act("COPY",
|
||||||
|
crc.d.eq(sink.d),
|
||||||
|
If(sink.stb & sink.ack,
|
||||||
|
crc.ce.eq(1),
|
||||||
|
If(sink.eop,
|
||||||
|
NextState("RESET")
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
self.comb += self.busy.eq(~fsm.ongoing("IDLE"))
|
||||||
|
|
||||||
|
class CRC32Checker(CRCChecker):
|
||||||
|
def __init__(self, layout):
|
||||||
|
CRCChecker.__init__(self, CRC32, layout)
|
|
@ -2,7 +2,8 @@ from migen.fhdl.std import *
|
||||||
from migen.genlib.record import *
|
from migen.genlib.record import *
|
||||||
from migen.flow.actor import Sink, Source
|
from migen.flow.actor import Sink, Source
|
||||||
|
|
||||||
from misoclib.ethmac.common import *
|
from liteethernet.common import *
|
||||||
|
from liteethernet.mac.common import *
|
||||||
|
|
||||||
class TXLastBE(Module):
|
class TXLastBE(Module):
|
||||||
def __init__(self, d_w):
|
def __init__(self, d_w):
|
||||||
|
|
|
@ -4,7 +4,8 @@ from migen.genlib.misc import chooser
|
||||||
from migen.genlib.record import *
|
from migen.genlib.record import *
|
||||||
from migen.flow.actor import Sink, Source
|
from migen.flow.actor import Sink, Source
|
||||||
|
|
||||||
from misoclib.ethmac.common import *
|
from liteethernet.common import *
|
||||||
|
from liteethernet.ethmac.common import *
|
||||||
|
|
||||||
class PreambleInserter(Module):
|
class PreambleInserter(Module):
|
||||||
def __init__(self, d_w):
|
def __init__(self, d_w):
|
||||||
|
|
|
@ -6,7 +6,8 @@ from migen.flow.actor import Sink, Source
|
||||||
from migen.bank.description import *
|
from migen.bank.description import *
|
||||||
from migen.bank.eventmanager import *
|
from migen.bank.eventmanager import *
|
||||||
|
|
||||||
from misoclib.ethmac.common import *
|
from liteethernet.common import *
|
||||||
|
from liteethernet.mac.common import *
|
||||||
|
|
||||||
class SRAMWriter(Module, AutoCSR):
|
class SRAMWriter(Module, AutoCSR):
|
||||||
def __init__(self, depth, nslots=2):
|
def __init__(self, depth, nslots=2):
|
||||||
|
|
|
@ -0,0 +1,39 @@
|
||||||
|
from liteethernet.common import *
|
||||||
|
from liteethernet.mac import LiteEthernetMAC
|
||||||
|
|
||||||
|
class LiteEthernetMACWishboneInterface(Module, AutoCSR):
|
||||||
|
def __init__(self, nrxslots=2, ntxslots=2):
|
||||||
|
self.sink = Sink(mac_description(dw))
|
||||||
|
self.source = Source(max_description(dw))
|
||||||
|
self.bus = wishbone.Interface()
|
||||||
|
|
||||||
|
###
|
||||||
|
|
||||||
|
# SRAM Storage
|
||||||
|
sram_depth = buffer_depth//(32//8)
|
||||||
|
self.submodules.sram_writer = SRAMWriter(sram_depth, nrxslots)
|
||||||
|
self.submodules.sram_reader = SRAMReader(sram_depth, ntxslots)
|
||||||
|
self.submodules.ev = SharedIRQ(self.sram_writer.ev, self.sram_reader.ev)
|
||||||
|
self.comb += [
|
||||||
|
Record.connect(self.sink, self.sram_writer.sink),
|
||||||
|
Record.connect(self.sram_reader.source, self.source)
|
||||||
|
]
|
||||||
|
|
||||||
|
# Interface
|
||||||
|
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))
|
||||||
|
for n in range(ntxslots)]
|
||||||
|
wb_sram_ifs = wb_rx_sram_ifs + wb_tx_sram_ifs
|
||||||
|
|
||||||
|
wb_slaves = []
|
||||||
|
decoderoffset = log2_int(sram_depth)
|
||||||
|
decoderbits = log2_int(len(wb_sram_ifs))
|
||||||
|
for n, wb_sram_if in enumerate(wb_sram_ifs):
|
||||||
|
def slave_filter(a, v=n):
|
||||||
|
return a[decoderoffset:decoderoffset+decoderbits] == v
|
||||||
|
wb_slaves.append((slave_filter, wb_sram_if.bus))
|
||||||
|
self.submodules += wb_sram_if
|
||||||
|
wb_con = wishbone.Decoder(self.bus, wb_slaves, register=True)
|
||||||
|
self.submodules += wb_con
|
|
@ -3,14 +3,12 @@ from migen.flow.actor import Sink, Source
|
||||||
from migen.bank.description import *
|
from migen.bank.description import *
|
||||||
from migen.genlib.resetsync import AsyncResetSynchronizer
|
from migen.genlib.resetsync import AsyncResetSynchronizer
|
||||||
|
|
||||||
from misoclib.ethmac.common import *
|
from liteethernet.common import *
|
||||||
|
|
||||||
class GMIIPHYTX(Module):
|
class GMIIPHYTX(Module):
|
||||||
def __init__(self, pads):
|
def __init__(self, pads):
|
||||||
self.sink = sink = Sink(eth_description(8))
|
self.sink = sink = Sink(eth_description(8))
|
||||||
|
|
||||||
###
|
###
|
||||||
|
|
||||||
self.sync += [
|
self.sync += [
|
||||||
pads.tx_er.eq(0),
|
pads.tx_er.eq(0),
|
||||||
pads.tx_en.eq(sink.stb),
|
pads.tx_en.eq(sink.stb),
|
||||||
|
@ -21,9 +19,7 @@ class GMIIPHYTX(Module):
|
||||||
class GMIIPHYRX(Module):
|
class GMIIPHYRX(Module):
|
||||||
def __init__(self, pads):
|
def __init__(self, pads):
|
||||||
self.source = source = Source(eth_description(8))
|
self.source = source = Source(eth_description(8))
|
||||||
|
|
||||||
###
|
###
|
||||||
|
|
||||||
dv_d = Signal()
|
dv_d = Signal()
|
||||||
self.sync += dv_d.eq(pads.dv)
|
self.sync += dv_d.eq(pads.dv)
|
||||||
|
|
||||||
|
@ -45,9 +41,7 @@ class GMIIPHYRX(Module):
|
||||||
class GMIIPHYCRG(Module, AutoCSR):
|
class GMIIPHYCRG(Module, AutoCSR):
|
||||||
def __init__(self, clock_pads, pads):
|
def __init__(self, clock_pads, pads):
|
||||||
self._reset = CSRStorage()
|
self._reset = CSRStorage()
|
||||||
|
|
||||||
###
|
###
|
||||||
|
|
||||||
self.clock_domains.cd_eth_rx = ClockDomain()
|
self.clock_domains.cd_eth_rx = ClockDomain()
|
||||||
self.clock_domains.cd_eth_tx = ClockDomain()
|
self.clock_domains.cd_eth_tx = ClockDomain()
|
||||||
self.specials += [
|
self.specials += [
|
|
@ -3,14 +3,12 @@ from migen.flow.actor import Sink, Source
|
||||||
from migen.bank.description import *
|
from migen.bank.description import *
|
||||||
from migen.genlib.record import *
|
from migen.genlib.record import *
|
||||||
|
|
||||||
from misoclib.ethmac.common import *
|
from liteethernet.common import *
|
||||||
|
|
||||||
class LoopbackPHYCRG(Module, AutoCSR):
|
class LoopbackPHYCRG(Module, AutoCSR):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self._reset = CSRStorage()
|
self._reset = CSRStorage()
|
||||||
|
|
||||||
###
|
###
|
||||||
|
|
||||||
self.clock_domains.cd_eth_rx = ClockDomain()
|
self.clock_domains.cd_eth_rx = ClockDomain()
|
||||||
self.clock_domains.cd_eth_tx = ClockDomain()
|
self.clock_domains.cd_eth_tx = ClockDomain()
|
||||||
self.comb += [
|
self.comb += [
|
|
@ -4,14 +4,12 @@ from migen.flow.actor import Sink, Source
|
||||||
from migen.bank.description import *
|
from migen.bank.description import *
|
||||||
from migen.genlib.resetsync import AsyncResetSynchronizer
|
from migen.genlib.resetsync import AsyncResetSynchronizer
|
||||||
|
|
||||||
from misoclib.ethmac.common import *
|
from liteethernet.common import *
|
||||||
|
|
||||||
class MIIPHYTX(Module):
|
class MIIPHYTX(Module):
|
||||||
def __init__(self, pads):
|
def __init__(self, pads):
|
||||||
self.sink = sink = Sink(eth_description(8))
|
self.sink = sink = Sink(eth_description(8))
|
||||||
|
|
||||||
###
|
###
|
||||||
|
|
||||||
tx_en_r = Signal()
|
tx_en_r = Signal()
|
||||||
tx_data_r = Signal(4)
|
tx_data_r = Signal(4)
|
||||||
self.sync += [
|
self.sync += [
|
||||||
|
@ -48,9 +46,7 @@ class MIIPHYTX(Module):
|
||||||
class MIIPHYRX(Module):
|
class MIIPHYRX(Module):
|
||||||
def __init__(self, pads):
|
def __init__(self, pads):
|
||||||
self.source = source = Source(eth_description(8))
|
self.source = source = Source(eth_description(8))
|
||||||
|
|
||||||
###
|
###
|
||||||
|
|
||||||
sop = source.sop
|
sop = source.sop
|
||||||
set_sop = Signal()
|
set_sop = Signal()
|
||||||
clr_sop = Signal()
|
clr_sop = Signal()
|
||||||
|
@ -102,9 +98,7 @@ class MIIPHYRX(Module):
|
||||||
class MIIPHYCRG(Module, AutoCSR):
|
class MIIPHYCRG(Module, AutoCSR):
|
||||||
def __init__(self, clock_pads, pads):
|
def __init__(self, clock_pads, pads):
|
||||||
self._reset = CSRStorage()
|
self._reset = CSRStorage()
|
||||||
|
|
||||||
###
|
###
|
||||||
|
|
||||||
self.sync.base50 += clock_pads.phy.eq(~clock_pads.phy)
|
self.sync.base50 += clock_pads.phy.eq(~clock_pads.phy)
|
||||||
|
|
||||||
self.clock_domains.cd_eth_rx = ClockDomain()
|
self.clock_domains.cd_eth_rx = ClockDomain()
|
Loading…
Reference in New Issue