103 lines
3.4 KiB
Python
103 lines
3.4 KiB
Python
from migen.fhdl.std import *
|
|
from migen.flow.actor import *
|
|
from migen.flow.network import *
|
|
from migen.actorlib import structuring, spi
|
|
from migen.bank.description import *
|
|
from migen.bank.eventmanager import *
|
|
from migen.genlib.record import Record
|
|
|
|
from misoclib.mem.sdram.frontend import dma_lasmi
|
|
from misoclib.com.liteusb.common import *
|
|
|
|
|
|
class LiteUSBDMAWriter(Module, AutoCSR):
|
|
def __init__(self, lasmim):
|
|
self.sink = sink = Sink(user_description(8))
|
|
|
|
# Pack data
|
|
pack_factor = lasmim.dw//8
|
|
pack = structuring.Pack(phy_description(8), pack_factor, reverse=True)
|
|
cast = structuring.Cast(pack.source.payload.layout, lasmim.dw)
|
|
|
|
# DMA
|
|
writer = dma_lasmi.Writer(lasmim)
|
|
self._reset = CSR()
|
|
self.dma = InsertReset(spi.DMAWriteController(writer, mode=spi.MODE_SINGLE_SHOT))
|
|
self.comb += self.dma.reset.eq(self._reset.r & self._reset.re)
|
|
|
|
# Remove sop/eop/length/dst fields from payload
|
|
self.comb += [
|
|
pack.sink.stb.eq(sink.stb),
|
|
pack.sink.payload.eq(sink.payload),
|
|
sink.ack.eq(pack.sink.ack)
|
|
]
|
|
|
|
# Graph
|
|
g = DataFlowGraph()
|
|
g.add_pipeline(pack, cast, self.dma)
|
|
self.submodules += CompositeActor(g)
|
|
|
|
# IRQ
|
|
self.submodules.ev = EventManager()
|
|
self.ev.done = EventSourcePulse()
|
|
self.ev.finalize()
|
|
self.comb += self.ev.done.trigger.eq(sink.stb & sink.eop)
|
|
|
|
# CRC
|
|
self._crc_failed = CSRStatus()
|
|
self.sync += \
|
|
If(sink.stb & sink.eop,
|
|
self._crc_failed.status.eq(sink.error)
|
|
)
|
|
|
|
|
|
class LiteUSBDMAReader(Module, AutoCSR):
|
|
def __init__(self, lasmim, tag):
|
|
self.source = source = Source(user_description(8))
|
|
|
|
reader = dma_lasmi.Reader(lasmim)
|
|
self.dma = spi.DMAReadController(reader, mode=spi.MODE_SINGLE_SHOT)
|
|
|
|
pack_factor = lasmim.dw//8
|
|
packed_dat = structuring.pack_layout(8, pack_factor)
|
|
cast = structuring.Cast(lasmim.dw, packed_dat)
|
|
unpack = structuring.Unpack(pack_factor, phy_description(8), reverse=True)
|
|
|
|
# Graph
|
|
cnt = Signal(32)
|
|
self.sync += \
|
|
If(self.dma.generator._shoot.re,
|
|
cnt.eq(0)
|
|
).Elif(source.stb & source.ack,
|
|
cnt.eq(cnt + 1)
|
|
)
|
|
g = DataFlowGraph()
|
|
g.add_pipeline(self.dma, cast, unpack)
|
|
self.submodules += CompositeActor(g)
|
|
self.comb += [
|
|
source.stb.eq(unpack.source.stb),
|
|
source.sop.eq(cnt == 0),
|
|
source.eop.eq(cnt == (self.dma.length*pack_factor-1)),
|
|
source.length.eq(self.dma.length*pack_factor),
|
|
source.data.eq(unpack.source.data),
|
|
source.dst.eq(tag),
|
|
unpack.source.ack.eq(source.ack)
|
|
]
|
|
|
|
# IRQ
|
|
self.submodules.ev = EventManager()
|
|
self.ev.done = EventSourcePulse()
|
|
self.ev.finalize()
|
|
self.comb += self.ev.done.trigger.eq(source.stb & source.eop)
|
|
|
|
|
|
class LiteUSBDMA(Module, AutoCSR):
|
|
def __init__(self, port, lasmim_dma_wr, lasmim_dma_rd):
|
|
self.submodules.writer = LiteUSBDMAWriter(lasmim_dma_wr)
|
|
self.submodules.reader = LiteUSBDMAReader(lasmim_dma_rd, port.tag)
|
|
self.submodules.ev = SharedIRQ(self.writer.ev, self.reader.ev)
|
|
self.comb += [
|
|
Record.connect(port.source, self.writer.sink),
|
|
Record.connect(self.reader.source, port.sink),
|
|
]
|