From 8da924ec0fb5a1358831510b967753adc344936a Mon Sep 17 00:00:00 2001 From: occheung Date: Mon, 8 Nov 2021 12:28:26 +0800 Subject: [PATCH] dma: set conversion granularity using bus width --- artiq/gateware/rtio/analyzer.py | 23 +++++------------------ artiq/gateware/rtio/dma.py | 32 ++++++++++++-------------------- 2 files changed, 17 insertions(+), 38 deletions(-) diff --git a/artiq/gateware/rtio/analyzer.py b/artiq/gateware/rtio/analyzer.py index 1818d3c43..ef154affa 100644 --- a/artiq/gateware/rtio/analyzer.py +++ b/artiq/gateware/rtio/analyzer.py @@ -3,6 +3,7 @@ from migen.genlib.record import Record, layout_len from misoc.interconnect.csr import * from misoc.interconnect import stream +from artiq.gateware.rtio import dma from artiq.gateware.rtio.cri import commands as cri_commands 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 -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): def __init__(self, tsc, cri, enable): self.source = stream.Endpoint([("data", message_len)]) @@ -150,7 +137,7 @@ class MessageEncoder(Module, AutoCSR): class DMAWriter(Module, AutoCSR): - def __init__(self, membus): + def __init__(self, membus, cpu_dw): aw = len(membus.adr) dw = len(membus.dat_w) messages_per_dw = dw//message_len @@ -175,7 +162,7 @@ class DMAWriter(Module, AutoCSR): membus.stb.eq(self.sink.stb), self.sink.ack.eq(membus.ack), 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: for i in range(dw//8): @@ -207,7 +194,7 @@ class DMAWriter(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 self.enable = CSRStorage() self.busy = CSRStatus() @@ -219,7 +206,7 @@ class Analyzer(Module, AutoCSR): self.submodules.converter = stream.Converter( message_len, len(membus.dat_w), reverse=True, report_valid_token_count=True) - self.submodules.dma = DMAWriter(membus) + self.submodules.dma = DMAWriter(membus, cpu_dw) enable_r = Signal() self.sync += [ diff --git a/artiq/gateware/rtio/dma.py b/artiq/gateware/rtio/dma.py index 84f79dfa8..f81559dde 100644 --- a/artiq/gateware/rtio/dma.py +++ b/artiq/gateware/rtio/dma.py @@ -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)))) -def reverse_bytes(s): - 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): +def convert_signal(signal, granularity): assert len(signal) % 8 == 0 nbytes = len(signal)//8 - assert nbytes % 4 == 0 - nwords = nbytes//4 + assert nbytes % granularity == 0 + nwords = nbytes//granularity 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) + signal_words.append(_reverse_bytes( + signal[i*granularity*8:(i+1)*granularity*8], 8)) + return Cat(signal_words) class WishboneReader(Module): - def __init__(self, bus): + def __init__(self, bus, cpu_dw): self.bus = bus aw = len(bus.adr) @@ -57,18 +49,18 @@ class WishboneReader(Module): If(self.source.ack, data_reg_loaded.eq(0)), If(bus.ack, 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) ) ] class DMAReader(Module, AutoCSR): - def __init__(self, membus, enable): + def __init__(self, membus, enable, cpu_dw): aw = len(membus.adr) 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 # All numbers in bytes @@ -344,11 +336,11 @@ class CRIMaster(Module, AutoCSR): class DMA(Module): - def __init__(self, membus): + def __init__(self, membus, cpu_dw): self.enable = CSR() 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.time_offset = TimeOffset() self.submodules.cri_master = CRIMaster()