kasli: implement DRTIO-over-EEM

This commit is contained in:
Sebastien Bourdeauducq 2023-08-25 12:47:33 +08:00
parent 737ff79ae7
commit f5cbca9c29
2 changed files with 53 additions and 10 deletions

View File

@ -19,7 +19,7 @@ from artiq.gateware import rtio
from artiq.gateware.rtio.phy import ttl_simple, ttl_serdes_7series, edge_counter from artiq.gateware.rtio.phy import ttl_simple, ttl_serdes_7series, edge_counter
from artiq.gateware.rtio.xilinx_clocking import fix_serdes_timing_path from artiq.gateware.rtio.xilinx_clocking import fix_serdes_timing_path
from artiq.gateware import eem from artiq.gateware import eem
from artiq.gateware.drtio.transceiver import gtp_7series from artiq.gateware.drtio.transceiver import gtp_7series, eem_serdes
from artiq.gateware.drtio.siphaser import SiPhaser7Series from artiq.gateware.drtio.siphaser import SiPhaser7Series
from artiq.gateware.drtio.rx_synchronizer import XilinxRXSynchronizer from artiq.gateware.drtio.rx_synchronizer import XilinxRXSynchronizer
from artiq.gateware.drtio import * from artiq.gateware.drtio import *
@ -288,17 +288,17 @@ class MasterBase(MiniSoC, AMPSoC):
self.submodules.rtio_tsc = rtio.TSC(glbl_fine_ts_width=3) self.submodules.rtio_tsc = rtio.TSC(glbl_fine_ts_width=3)
drtio_csr_group = [] self.drtio_csr_group = []
drtioaux_csr_group = [] self.drtioaux_csr_group = []
drtioaux_memory_group = [] self.drtioaux_memory_group = []
self.drtio_cri = [] self.drtio_cri = []
for i in range(len(self.drtio_transceiver.channels)): for i in range(len(self.drtio_transceiver.channels)):
core_name = "drtio" + str(i) core_name = "drtio" + str(i)
coreaux_name = "drtioaux" + str(i) coreaux_name = "drtioaux" + str(i)
memory_name = "drtioaux" + str(i) + "_mem" memory_name = "drtioaux" + str(i) + "_mem"
drtio_csr_group.append(core_name) self.drtio_csr_group.append(core_name)
drtioaux_csr_group.append(coreaux_name) self.drtioaux_csr_group.append(coreaux_name)
drtioaux_memory_group.append(memory_name) self.drtioaux_memory_group.append(memory_name)
cdr = ClockDomainsRenamer({"rtio_rx": "rtio_rx" + str(i)}) cdr = ClockDomainsRenamer({"rtio_rx": "rtio_rx" + str(i)})
@ -317,9 +317,6 @@ class MasterBase(MiniSoC, AMPSoC):
self.add_memory_region(memory_name, memory_address | self.shadow_base, 0x800) self.add_memory_region(memory_name, memory_address | self.shadow_base, 0x800)
self.config["HAS_DRTIO"] = None self.config["HAS_DRTIO"] = None
self.config["HAS_DRTIO_ROUTING"] = None self.config["HAS_DRTIO_ROUTING"] = None
self.add_csr_group("drtio", drtio_csr_group)
self.add_csr_group("drtioaux", drtioaux_csr_group)
self.add_memory_group("drtioaux_mem", drtioaux_memory_group)
rtio_clk_period = 1e9/rtio_clk_freq rtio_clk_period = 1e9/rtio_clk_freq
gtp = self.drtio_transceiver.gtps[0] gtp = self.drtio_transceiver.gtps[0]
@ -367,6 +364,41 @@ class MasterBase(MiniSoC, AMPSoC):
self.get_native_sdram_if(), cpu_dw=self.cpu_dw) self.get_native_sdram_if(), cpu_dw=self.cpu_dw)
self.csr_devices.append("rtio_analyzer") self.csr_devices.append("rtio_analyzer")
def add_eem_drtio(self, eem_drtio_channels):
self.submodules.eem_transceiver = eem_serdes.EEMSerdes(self.platform, eem_drtio_channels)
self.csr_devices.append("eem_transceiver")
self.config["HAS_DRTIO_EEM"] = None
self.config["EEM_DRTIO_COUNT"] = len(eem_drtio_channels)
cdr = ClockDomainsRenamer({"rtio_rx": "sys"})
for i in range(len(self.eem_transceiver.channels)):
channel = i + len(self.drtio_transceiver.channels)
core_name = "drtio" + str(channel)
coreaux_name = "drtioaux" + str(channel)
memory_name = "drtioaux" + str(channel) + "_mem"
self.drtio_csr_group.append(core_name)
self.drtioaux_csr_group.append(coreaux_name)
self.drtioaux_memory_group.append(memory_name)
core = cdr(DRTIOMaster(self.rtio_tsc, self.eem_transceiver.channels[i]))
setattr(self.submodules, core_name, core)
self.drtio_cri.append(core.cri)
self.csr_devices.append(core_name)
coreaux = cdr(DRTIOAuxController(core.link_layer, self.cpu_dw))
setattr(self.submodules, coreaux_name, coreaux)
self.csr_devices.append(coreaux_name)
memory_address = self.mem_map["drtioaux"] + 0x800*channel
self.add_wb_slave(memory_address, 0x800,
coreaux.bus)
self.add_memory_region(memory_name, memory_address | self.shadow_base, 0x800)
def add_drtio_cpuif_groups(self):
self.add_csr_group("drtio", self.drtio_csr_group)
self.add_csr_group("drtioaux", self.drtioaux_csr_group)
self.add_memory_group("drtioaux_mem", self.drtioaux_memory_group)
# Never running out of stupid features, GTs on A7 make you pack # Never running out of stupid features, GTs on A7 make you pack
# unrelated transceiver PLLs into one GTPE2_COMMON yourself. # unrelated transceiver PLLs into one GTPE2_COMMON yourself.
def create_qpll(self): def create_qpll(self):

View File

@ -71,10 +71,12 @@ class GenericMaster(MasterBase):
if hw_rev is None: if hw_rev is None:
hw_rev = description["hw_rev"] hw_rev = description["hw_rev"]
self.class_name_override = description["variant"] self.class_name_override = description["variant"]
has_drtio_over_eem = any(peripheral["type"] == "efc" for peripheral in description["peripherals"])
MasterBase.__init__(self, MasterBase.__init__(self,
hw_rev=hw_rev, hw_rev=hw_rev,
rtio_clk_freq=description["rtio_frequency"], rtio_clk_freq=description["rtio_frequency"],
enable_sata=description["enable_sata_drtio"], enable_sata=description["enable_sata_drtio"],
enable_sys5x=has_drtio_over_eem,
**kwargs) **kwargs)
self.config["DRTIO_ROLE"] = description["drtio_role"] self.config["DRTIO_ROLE"] = description["drtio_role"]
if "ext_ref_frequency" in description: if "ext_ref_frequency" in description:
@ -85,6 +87,8 @@ class GenericMaster(MasterBase):
# EEM clock fan-out from Si5324, not MMCX # EEM clock fan-out from Si5324, not MMCX
self.comb += self.platform.request("clk_sel").eq(1) self.comb += self.platform.request("clk_sel").eq(1)
if has_drtio_over_eem:
self.eem_drtio_channels = []
has_grabber = any(peripheral["type"] == "grabber" for peripheral in description["peripherals"]) has_grabber = any(peripheral["type"] == "grabber" for peripheral in description["peripherals"])
if has_grabber: if has_grabber:
self.grabber_csr_group = [] self.grabber_csr_group = []
@ -96,6 +100,9 @@ class GenericMaster(MasterBase):
self.rtio_channels.append(rtio.LogChannel()) self.rtio_channels.append(rtio.LogChannel())
self.add_rtio(self.rtio_channels, sed_lanes=description["sed_lanes"]) self.add_rtio(self.rtio_channels, sed_lanes=description["sed_lanes"])
if has_drtio_over_eem:
self.add_eem_drtio(self.eem_drtio_channels)
self.add_drtio_cpuif_groups()
if has_grabber: if has_grabber:
self.config["HAS_GRABBER"] = None self.config["HAS_GRABBER"] = None
self.add_csr_group("grabber", self.grabber_csr_group) self.add_csr_group("grabber", self.grabber_csr_group)
@ -168,6 +175,10 @@ def main():
else: else:
raise ValueError("Invalid DRTIO role") raise ValueError("Invalid DRTIO role")
has_efc = any(peripheral["type"] == "efc" for peripheral in description["peripherals"])
if has_efc and (description["drtio_role"] == "standalone"):
raise ValueError("EFC requires DRTIO, please switch role to master")
soc = cls(description, gateware_identifier_str=args.gateware_identifier_str, **soc_kasli_argdict(args)) soc = cls(description, gateware_identifier_str=args.gateware_identifier_str, **soc_kasli_argdict(args))
args.variant = description["variant"] args.variant = description["variant"]
build_artiq_soc(soc, builder_argdict(args)) build_artiq_soc(soc, builder_argdict(args))