From 9daf77bd58b77069b30a8d19b3bfff2c16d4c7f2 Mon Sep 17 00:00:00 2001 From: Harry Ho Date: Wed, 20 Jan 2021 14:51:10 +0800 Subject: [PATCH] kc705: add multichannel support on satellite * Two DRTIO channels (i.e. satellite and repeater) are enabled by default. * User can choose either the SFP or SMA as the satellite channel (by passing `--drtio-sat sfp` or --drtio-sat sma` to the argparser), and the unchosen would become the repeater channel. --- .../gateware/targets/kc705_drtio_satellite.py | 84 ++++++++++++++----- 1 file changed, 65 insertions(+), 19 deletions(-) diff --git a/artiq/gateware/targets/kc705_drtio_satellite.py b/artiq/gateware/targets/kc705_drtio_satellite.py index 4cb502fca..073d81343 100755 --- a/artiq/gateware/targets/kc705_drtio_satellite.py +++ b/artiq/gateware/targets/kc705_drtio_satellite.py @@ -31,13 +31,15 @@ class Satellite(BaseSoC): } mem_map.update(BaseSoC.mem_map) - def __init__(self, gateware_identifier_str=None, **kwargs): + def __init__(self, gateware_identifier_str=None, drtio_sat="sfp", **kwargs): BaseSoC.__init__(self, cpu_type="or1k", sdram_controller_type="minicon", l2_size=128*1024, integrated_sram_size=8192, **kwargs) + assert drtio_sat in ["sfp", "sma"] + add_identifier(self, gateware_identifier_str=gateware_identifier_str) if isinstance(self.platform.toolchain, XilinxVivadoToolchain): @@ -50,8 +52,15 @@ class Satellite(BaseSoC): platform = self.platform self.comb += platform.request("sfp_tx_disable_n").eq(1) - tx_pads = [platform.request("sfp_tx")] - rx_pads = [platform.request("sfp_rx")] + tx_pads = [ + platform.request("sfp_tx"), platform.request("user_sma_mgt_tx") + ] + rx_pads = [ + platform.request("sfp_rx"), platform.request("user_sma_mgt_rx") + ] + if drtio_sat == "sma": + tx_pads = tx_pads[::-1] + rx_pads = rx_pads[::-1] # 1000BASE_BX10 Ethernet compatible, 125MHz RTIO clock self.submodules.drtio_transceiver = gtx_7series.GTX( @@ -62,24 +71,49 @@ class Satellite(BaseSoC): self.csr_devices.append("drtio_transceiver") self.submodules.rtio_tsc = rtio.TSC("sync", glbl_fine_ts_width=3) - cdr = ClockDomainsRenamer({"rtio_rx": "rtio_rx0"}) - self.submodules.rx_synchronizer = cdr(XilinxRXSynchronizer()) - self.submodules.drtiosat = cdr(DRTIOSatellite( - self.rtio_tsc, self.drtio_transceiver.channels[0], self.rx_synchronizer)) - self.csr_devices.append("drtiosat") + drtioaux_csr_group = [] + drtioaux_memory_group = [] + drtiorep_csr_group = [] + self.drtio_cri = [] + for i in range(len(self.drtio_transceiver.channels)): + coreaux_name = "drtioaux" + str(i) + memory_name = "drtioaux" + str(i) + "_mem" + drtioaux_csr_group.append(coreaux_name) + drtioaux_memory_group.append(memory_name) - self.submodules.drtioaux0 = cdr(DRTIOAuxController( - self.drtiosat.link_layer)) - self.csr_devices.append("drtioaux0") - self.add_wb_slave(self.mem_map["drtioaux"], 0x800, - self.drtioaux0.bus) - self.add_memory_region("drtioaux0_mem", self.mem_map["drtioaux"] | self.shadow_base, 0x800) + cdr = ClockDomainsRenamer({"rtio_rx": "rtio_rx" + str(i)}) + # Satellite + if i == 0: + self.submodules.rx_synchronizer = cdr(XilinxRXSynchronizer()) + core = cdr(DRTIOSatellite( + self.rtio_tsc, self.drtio_transceiver.channels[0], self.rx_synchronizer)) + self.submodules.drtiosat = core + self.csr_devices.append("drtiosat") + # Repeaters + else: + corerep_name = "drtiorep" + str(i-1) + drtiorep_csr_group.append(corerep_name) + core = cdr(DRTIORepeater( + self.rtio_tsc, self.drtio_transceiver.channels[i])) + setattr(self.submodules, corerep_name, core) + self.drtio_cri.append(core.cri) + self.csr_devices.append(corerep_name) + + coreaux = cdr(DRTIOAuxController(core.link_layer)) + setattr(self.submodules, coreaux_name, coreaux) + self.csr_devices.append(coreaux_name) + + memory_address = self.mem_map["drtioaux"] + 0x800*i + self.add_wb_slave(memory_address, 0x800, + coreaux.bus) + self.add_memory_region(memory_name, memory_address | self.shadow_base, 0x800) self.config["HAS_DRTIO"] = None - self.add_csr_group("drtio", ["drtiosat"]) - self.add_csr_group("drtioaux", ["drtioaux0"]) - self.add_memory_group("drtioaux_mem", ["drtioaux0_mem"]) + self.config["HAS_DRTIO_ROUTING"] = None + self.add_csr_group("drtioaux", drtioaux_csr_group) + self.add_memory_group("drtioaux_mem", drtioaux_memory_group) + self.add_csr_group("drtiorep", drtiorep_csr_group) self.config["RTIO_FREQUENCY"] = str(self.drtio_transceiver.rtio_clk_freq/1e6) # Si5324 Phaser @@ -135,7 +169,13 @@ class Satellite(BaseSoC): self.submodules.local_io = SyncRTIO(self.rtio_tsc, rtio_channels) self.comb += self.drtiosat.async_errors.eq(self.local_io.async_errors) - self.comb += self.drtiosat.cri.connect(self.local_io.cri) + self.submodules.cri_con = rtio.CRIInterconnectShared( + [self.drtiosat.cri], + [self.local_io.cri] + self.drtio_cri, + mode="sync", enable_routing=True) + self.csr_devices.append("cri_con") + self.submodules.routing_table = rtio.RoutingTableAccess(self.cri_con) + self.csr_devices.append("routing_table") def main(): @@ -144,9 +184,15 @@ def main(): builder_args(parser) soc_kc705_args(parser) parser.set_defaults(output_dir="artiq_kc705/satellite") + parser.add_argument("--drtio-sat", default="sfp", + help="use the SFP or the SMA connectors (RX: J17, J18, TX: J19, J20) " + "as DRTIO satellite channel (choices: sfp, sma; default: sfp)") args = parser.parse_args() - soc = Satellite(**soc_kc705_argdict(args)) + argdict = dict() + argdict["drtio_sat"] = args.drtio_sat + + soc = Satellite(**soc_kc705_argdict(args), **argdict) build_artiq_soc(soc, builder_argdict(args))