"""Auxiliary controller, common to satellite and master""" from artiq.gateware.drtio.aux_controller import Transmitter, Receiver from migen.fhdl.simplify import FullMemoryWE from misoc.interconnect.csr import * from migen_axi.interconnect.sram import SRAM from migen_axi.interconnect import axi max_packet = 1024 # TODO: FullMemoryWE should be applied by migen.build @FullMemoryWE() class DRTIOAuxControllerAxi(Module): def __init__(self, link_layer): self.bus = axi.Interface() self.submodules.transmitter = Transmitter(link_layer, len(self.bus.w.data)) self.submodules.receiver = Receiver(link_layer, len(self.bus.w.data)) tx_sdram_if = SRAM(self.transmitter.mem, read_only=False) rx_sdram_if = SRAM(self.receiver.mem, read_only=True) aw_decoder = axi.AddressDecoder(self.bus.aw, [(lambda a: a[log2_int(max_packet)] == 0, tx_sdram_if.bus.aw), (lambda a: a[log2_int(max_packet)] == 1, rx_sdram_if.bus.aw)], register=True) ar_decoder = axi.AddressDecoder(self.bus.ar, [(lambda a: a[log2_int(max_packet)] == 0, tx_sdram_if.bus.ar), (lambda a: a[log2_int(max_packet)] == 1, rx_sdram_if.bus.ar)], register=True) # unlike wb, axi address decoder only connects ar/aw lanes, # the rest must also be connected! # not quite unlike an address decoder itself. # connect bus.b with tx.b self.comb += [tx_sdram_if.bus.b.ready.eq(self.bus.b.ready), self.bus.b.id.eq(tx_sdram_if.bus.b.id), self.bus.b.resp.eq(tx_sdram_if.bus.b.resp), self.bus.b.valid.eq(tx_sdram_if.bus.b.valid)] # connect bus.w with tx.w # no worries about w.valid and slave sel here, only tx will be written to self.comb += [tx_sdram_if.bus.w.id.eq(self.bus.w.id), tx_sdram_if.bus.w.data.eq(self.bus.w.data), tx_sdram_if.bus.w.strb.eq(self.bus.w.strb), tx_sdram_if.bus.w.last.eq(self.bus.w.last), tx_sdram_if.bus.w.valid.eq(self.bus.w.valid), self.bus.w.ready.eq(tx_sdram_if.bus.w.ready)] # connect bus.r with rx.r and tx.r w/o data self.comb += [self.bus.r.id.eq(rx_sdram_if.bus.r.id | tx_sdram_if.bus.r.id), #self.bus.r.data.eq(rx_sdram_if.bus.r.data | tx_sdram_if.bus.r.data), self.bus.r.resp.eq(rx_sdram_if.bus.r.resp | tx_sdram_if.bus.r.resp), self.bus.r.last.eq(rx_sdram_if.bus.r.last | tx_sdram_if.bus.r.last), self.bus.r.valid.eq(rx_sdram_if.bus.r.valid | tx_sdram_if.bus.r.valid), rx_sdram_if.bus.r.ready.eq(self.bus.r.ready), tx_sdram_if.bus.r.ready.eq(self.bus.r.ready)] # connect read data after being masked masked = [Replicate(rx_sdram_if.bus.r.valid, len(self.bus.r.data) ) & rx_sdram_if.bus.r.data, Replicate(tx_sdram_if.bus.r.valid, len(self.bus.r.data) ) & tx_sdram_if.bus.r.data] self.comb += self.bus.r.data.eq(reduce(or_, masked)) self.submodules += tx_sdram_if, rx_sdram_if, aw_decoder, ar_decoder def get_csrs(self): return self.transmitter.get_csrs() + self.receiver.get_csrs() @FullMemoryWE() class DRTIOAuxControllerBare(Module): # Barebones version of the AuxController. No SRAM, no decoders. # add memories manually from tx and rx in target code. def __init__(self, link_layer): self.bus = axi.Interface() self.submodules.transmitter = Transmitter(link_layer, len(self.bus.w.data)) self.submodules.receiver = Receiver(link_layer, len(self.bus.w.data)) def get_csrs(self): return self.transmitter.get_csrs() + self.receiver.get_csrs() def get_tx_port(self): return self.transmitter.mem.get_port(write_capable=True) def get_rx_port(self): return self.receiver.mem.get_port(write_capable=False) def get_mem_size(self): return max_packet