mirror of https://github.com/m-labs/artiq.git
dma: set conversion granularity using bus width
This commit is contained in:
parent
591507a7c0
commit
8da924ec0f
|
@ -3,6 +3,7 @@ from migen.genlib.record import Record, layout_len
|
||||||
from misoc.interconnect.csr import *
|
from misoc.interconnect.csr import *
|
||||||
from misoc.interconnect import stream
|
from misoc.interconnect import stream
|
||||||
|
|
||||||
|
from artiq.gateware.rtio import dma
|
||||||
from artiq.gateware.rtio.cri import commands as cri_commands
|
from artiq.gateware.rtio.cri import commands as cri_commands
|
||||||
from artiq.coredevice.comm_analyzer import MessageType, ExceptionType
|
from artiq.coredevice.comm_analyzer import MessageType, ExceptionType
|
||||||
|
|
||||||
|
@ -42,20 +43,6 @@ assert layout_len(exception_layout) == message_len
|
||||||
assert layout_len(stopped_layout) == message_len
|
assert layout_len(stopped_layout) == message_len
|
||||||
|
|
||||||
|
|
||||||
def convert_signal(signal):
|
|
||||||
assert len(signal) % 8 == 0
|
|
||||||
nbytes = len(signal)//8
|
|
||||||
assert nbytes % 4 == 0
|
|
||||||
nwords = nbytes//4
|
|
||||||
signal_words = []
|
|
||||||
for i in range(nwords):
|
|
||||||
signal_bytes = []
|
|
||||||
for j in range(4):
|
|
||||||
signal_bytes.append(signal[8*(j+i*4):8*((j+i*4)+1)])
|
|
||||||
signal_words.extend(reversed(signal_bytes))
|
|
||||||
return Cat(*signal_words)
|
|
||||||
|
|
||||||
|
|
||||||
class MessageEncoder(Module, AutoCSR):
|
class MessageEncoder(Module, AutoCSR):
|
||||||
def __init__(self, tsc, cri, enable):
|
def __init__(self, tsc, cri, enable):
|
||||||
self.source = stream.Endpoint([("data", message_len)])
|
self.source = stream.Endpoint([("data", message_len)])
|
||||||
|
@ -150,7 +137,7 @@ class MessageEncoder(Module, AutoCSR):
|
||||||
|
|
||||||
|
|
||||||
class DMAWriter(Module, AutoCSR):
|
class DMAWriter(Module, AutoCSR):
|
||||||
def __init__(self, membus):
|
def __init__(self, membus, cpu_dw):
|
||||||
aw = len(membus.adr)
|
aw = len(membus.adr)
|
||||||
dw = len(membus.dat_w)
|
dw = len(membus.dat_w)
|
||||||
messages_per_dw = dw//message_len
|
messages_per_dw = dw//message_len
|
||||||
|
@ -175,7 +162,7 @@ class DMAWriter(Module, AutoCSR):
|
||||||
membus.stb.eq(self.sink.stb),
|
membus.stb.eq(self.sink.stb),
|
||||||
self.sink.ack.eq(membus.ack),
|
self.sink.ack.eq(membus.ack),
|
||||||
membus.we.eq(1),
|
membus.we.eq(1),
|
||||||
membus.dat_w.eq(convert_signal(self.sink.data))
|
membus.dat_w.eq(dma.convert_signal(self.sink.data, cpu_dw//8))
|
||||||
]
|
]
|
||||||
if messages_per_dw > 1:
|
if messages_per_dw > 1:
|
||||||
for i in range(dw//8):
|
for i in range(dw//8):
|
||||||
|
@ -207,7 +194,7 @@ class DMAWriter(Module, AutoCSR):
|
||||||
|
|
||||||
|
|
||||||
class Analyzer(Module, AutoCSR):
|
class Analyzer(Module, AutoCSR):
|
||||||
def __init__(self, tsc, cri, membus, fifo_depth=128):
|
def __init__(self, tsc, cri, membus, fifo_depth=128, cpu_dw=32):
|
||||||
# shutdown procedure: set enable to 0, wait until busy=0
|
# shutdown procedure: set enable to 0, wait until busy=0
|
||||||
self.enable = CSRStorage()
|
self.enable = CSRStorage()
|
||||||
self.busy = CSRStatus()
|
self.busy = CSRStatus()
|
||||||
|
@ -219,7 +206,7 @@ class Analyzer(Module, AutoCSR):
|
||||||
self.submodules.converter = stream.Converter(
|
self.submodules.converter = stream.Converter(
|
||||||
message_len, len(membus.dat_w), reverse=True,
|
message_len, len(membus.dat_w), reverse=True,
|
||||||
report_valid_token_count=True)
|
report_valid_token_count=True)
|
||||||
self.submodules.dma = DMAWriter(membus)
|
self.submodules.dma = DMAWriter(membus, cpu_dw)
|
||||||
|
|
||||||
enable_r = Signal()
|
enable_r = Signal()
|
||||||
self.sync += [
|
self.sync += [
|
||||||
|
|
|
@ -11,28 +11,20 @@ def _reverse_bytes(s, g):
|
||||||
return Cat(reversed(list(s[i*g:(i+1)*g] for i in range(len(s)//g))))
|
return Cat(reversed(list(s[i*g:(i+1)*g] for i in range(len(s)//g))))
|
||||||
|
|
||||||
|
|
||||||
def reverse_bytes(s):
|
def convert_signal(signal, granularity):
|
||||||
n = (len(s) + 7)//8
|
|
||||||
return Cat(*[s[i*8:min((i + 1)*8, len(s))]
|
|
||||||
for i in reversed(range(n))])
|
|
||||||
|
|
||||||
|
|
||||||
def convert_signal(signal):
|
|
||||||
assert len(signal) % 8 == 0
|
assert len(signal) % 8 == 0
|
||||||
nbytes = len(signal)//8
|
nbytes = len(signal)//8
|
||||||
assert nbytes % 4 == 0
|
assert nbytes % granularity == 0
|
||||||
nwords = nbytes//4
|
nwords = nbytes//granularity
|
||||||
signal_words = []
|
signal_words = []
|
||||||
for i in range(nwords):
|
for i in range(nwords):
|
||||||
signal_bytes = []
|
signal_words.append(_reverse_bytes(
|
||||||
for j in range(4):
|
signal[i*granularity*8:(i+1)*granularity*8], 8))
|
||||||
signal_bytes.append(signal[8*(j+i*4):8*((j+i*4)+1)])
|
return Cat(signal_words)
|
||||||
signal_words.extend(reversed(signal_bytes))
|
|
||||||
return Cat(*signal_words)
|
|
||||||
|
|
||||||
|
|
||||||
class WishboneReader(Module):
|
class WishboneReader(Module):
|
||||||
def __init__(self, bus):
|
def __init__(self, bus, cpu_dw):
|
||||||
self.bus = bus
|
self.bus = bus
|
||||||
|
|
||||||
aw = len(bus.adr)
|
aw = len(bus.adr)
|
||||||
|
@ -57,18 +49,18 @@ class WishboneReader(Module):
|
||||||
If(self.source.ack, data_reg_loaded.eq(0)),
|
If(self.source.ack, data_reg_loaded.eq(0)),
|
||||||
If(bus.ack,
|
If(bus.ack,
|
||||||
data_reg_loaded.eq(1),
|
data_reg_loaded.eq(1),
|
||||||
self.source.data.eq(convert_signal(bus.dat_r)),
|
self.source.data.eq(convert_signal(bus.dat_r, cpu_dw//8)),
|
||||||
self.source.eop.eq(self.sink.eop)
|
self.source.eop.eq(self.sink.eop)
|
||||||
)
|
)
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
class DMAReader(Module, AutoCSR):
|
class DMAReader(Module, AutoCSR):
|
||||||
def __init__(self, membus, enable):
|
def __init__(self, membus, enable, cpu_dw):
|
||||||
aw = len(membus.adr)
|
aw = len(membus.adr)
|
||||||
data_alignment = log2_int(len(membus.dat_w)//8)
|
data_alignment = log2_int(len(membus.dat_w)//8)
|
||||||
|
|
||||||
self.submodules.wb_reader = WishboneReader(membus)
|
self.submodules.wb_reader = WishboneReader(membus, cpu_dw)
|
||||||
self.source = self.wb_reader.source
|
self.source = self.wb_reader.source
|
||||||
|
|
||||||
# All numbers in bytes
|
# All numbers in bytes
|
||||||
|
@ -344,11 +336,11 @@ class CRIMaster(Module, AutoCSR):
|
||||||
|
|
||||||
|
|
||||||
class DMA(Module):
|
class DMA(Module):
|
||||||
def __init__(self, membus):
|
def __init__(self, membus, cpu_dw):
|
||||||
self.enable = CSR()
|
self.enable = CSR()
|
||||||
|
|
||||||
flow_enable = Signal()
|
flow_enable = Signal()
|
||||||
self.submodules.dma = DMAReader(membus, flow_enable)
|
self.submodules.dma = DMAReader(membus, flow_enable, cpu_dw)
|
||||||
self.submodules.slicer = RecordSlicer(len(membus.dat_w))
|
self.submodules.slicer = RecordSlicer(len(membus.dat_w))
|
||||||
self.submodules.time_offset = TimeOffset()
|
self.submodules.time_offset = TimeOffset()
|
||||||
self.submodules.cri_master = CRIMaster()
|
self.submodules.cri_master = CRIMaster()
|
||||||
|
|
Loading…
Reference in New Issue