dma: set conversion granularity using bus width

This commit is contained in:
occheung 2021-11-08 12:28:26 +08:00 committed by Sébastien Bourdeauducq
parent 591507a7c0
commit 8da924ec0f
2 changed files with 17 additions and 38 deletions

View File

@ -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 += [

View File

@ -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()