test integration in MiSoC (fixes/cleanup)

This commit is contained in:
Florent Kermarrec 2015-01-28 11:45:19 +01:00
parent 09537523a6
commit e42fdb4232
11 changed files with 143 additions and 119 deletions

View File

@ -2,18 +2,29 @@ from collections import OrderedDict
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 = [
("d", dw),
("data", dw),
("error", dw//8)
]
return EndpointDescription(layout, packetized=True)
def eth_mac_description(dw):
layout = [
("data", dw),
("last_be", dw//8),
("error", dw//8)
]

View File

@ -3,15 +3,20 @@ from liteeth.mac.core import LiteEthMACCore
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

View File

@ -1,11 +1,11 @@
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)
@ -29,14 +29,14 @@ class LiteEthMACCore(Module, AutoCSR):
# 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"})

View File

@ -9,7 +9,7 @@ class LiteEthMACCRCEngine(Module):
Parameters
----------
dat_width : int
data_width : int
Width of the data bus.
width : int
Width of the CRC.
@ -18,15 +18,15 @@ class LiteEthMACCRCEngine(Module):
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)
@ -51,7 +51,7 @@ class LiteEthMACCRCEngine(Module):
# 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))):
@ -66,7 +66,7 @@ class LiteEthMACCRCEngine(Module):
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)
@ -78,7 +78,7 @@ class LiteEthMACCRC32(Module):
Parameters
----------
dat_width : int
data_width : int
Width of the data bus.
Attributes
@ -94,18 +94,18 @@ class LiteEthMACCRC32(Module):
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]),
@ -119,8 +119,8 @@ class LiteEthMACCRCInserter(Module):
Parameters
----------
layout : layout
Layout of the dataflow.
description : description
description of the dataflow.
Attributes
----------
@ -129,14 +129,14 @@ class LiteEthMACCRCInserter(Module):
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
@ -151,7 +151,7 @@ class LiteEthMACCRCInserter(Module):
)
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,
@ -164,7 +164,7 @@ class LiteEthMACCRCInserter(Module):
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"))
@ -181,14 +181,14 @@ class LiteEthMACCRCInserter(Module):
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
@ -197,8 +197,8 @@ class LiteEthMACCRCChecker(Module):
Parameters
----------
layout : layout
Layout of the dataflow.
description : description
description of the dataflow.
Attributes
----------
@ -208,20 +208,20 @@ class LiteEthMACCRCChecker(Module):
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")
@ -255,14 +255,14 @@ class LiteEthMACCRCChecker(Module):
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,
@ -272,6 +272,6 @@ class LiteEthMACCRCChecker(Module):
)
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)

View File

@ -2,15 +2,13 @@ from liteeth.common import *
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,
@ -18,19 +16,23 @@ class LiteEthMACTXLastBE(Module):
)
)
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)
]

View File

@ -2,14 +2,14 @@ from liteeth.common import *
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()
@ -34,7 +34,7 @@ class LiteEthMACPreambleInserter(Module):
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(
@ -51,14 +51,14 @@ class LiteEthMACPreambleInserter(Module):
)
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()
@ -91,11 +91,11 @@ class LiteEthMACPreambleChecker(Module):
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")

View File

@ -1,9 +1,12 @@
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)
@ -69,7 +72,7 @@ class LiteEthMACSRAMWriter(Module, AutoCSR):
inc_cnt.eq(sink.stb),
If(sink.stb & sink.sop,
ongoing.eq(1),
If(fifo.writable,
If(fifo.sink.ack,
NextState("WRITE")
)
)
@ -92,17 +95,17 @@ class LiteEthMACSRAMWriter(Module, AutoCSR):
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
@ -118,7 +121,7 @@ class LiteEthMACSRAMWriter(Module, AutoCSR):
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)
)
@ -128,7 +131,7 @@ class LiteEthMACSRAMWriter(Module, AutoCSR):
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
@ -149,10 +152,10 @@ class LiteEthMACSRAMReader(Module, AutoCSR):
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
@ -177,7 +180,7 @@ class LiteEthMACSRAMReader(Module, AutoCSR):
fsm.act("IDLE",
clr_cnt.eq(1),
If(fifo.readable,
If(fifo.source.stb,
NextState("CHECK")
)
)
@ -188,7 +191,7 @@ class LiteEthMACSRAMReader(Module, AutoCSR):
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),
@ -210,7 +213,7 @@ class LiteEthMACSRAMReader(Module, AutoCSR):
)
)
fsm.act("END",
fifo.re.eq(1),
fifo.source.ack.eq(1),
self.ev.done.trigger.eq(1),
NextState("IDLE")
)
@ -223,11 +226,11 @@ class LiteEthMACSRAMReader(Module, AutoCSR):
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
@ -240,12 +243,12 @@ class LiteEthMACSRAMReader(Module, AutoCSR):
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

View File

@ -2,10 +2,13 @@ from liteeth.common import *
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
@ -17,10 +20,10 @@ class LiteEthMACWishboneInterface(Module, AutoCSR):
]
# 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

View File

@ -2,18 +2,18 @@ from liteeth.common import *
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)
@ -27,7 +27,7 @@ class LiteEthPHYGMIIRX(Module):
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)
@ -56,7 +56,7 @@ class LiteEthPHYGMIICRG(Module, AutoCSR):
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)

View File

@ -21,6 +21,6 @@ class LiteEthPHYLoopback(Module, AutoCSR):
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)

View File

@ -2,7 +2,7 @@ from liteeth.common import *
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)
@ -22,12 +22,12 @@ class LiteEthPHYMIITX(Module):
)
)
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,
@ -39,7 +39,7 @@ class LiteEthPHYMIITX(Module):
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()
@ -61,7 +61,7 @@ class LiteEthPHYMIIRX(Module):
hi.eq(pads.rx_data)
)
self.comb += [
source.d.eq(Cat(lo, hi))
source.data.eq(Cat(lo, hi))
]
fsm = FSM(reset_state="IDLE")