diff --git a/src/gateware/kasli_soc.py b/src/gateware/kasli_soc.py index a5cd3545..51a9fb0d 100755 --- a/src/gateware/kasli_soc.py +++ b/src/gateware/kasli_soc.py @@ -16,6 +16,11 @@ from artiq.coredevice import jsondesc from artiq.gateware import rtio, eem_7series from artiq.gateware.rtio.phy import ttl_simple +from artiq.gateware.drtio.transceiver import gtp_7series +from artiq.gateware.drtio.siphaser import SiPhaser7Series +from artiq.gateware.drtio.rx_synchronizer import XilinxRXSynchronizer +from artiq.gateware.drtio import * + import dma import analyzer import acpki @@ -159,15 +164,301 @@ class GenericStandalone(SoCCore): self.platform.add_false_path_constraints( self.rtio_crg.cd_rtio.clk, getattr(self, grabber).deserializer.cd_cl.clk) - + class GenericMaster(SoCCore): - def __init__(self, description, **kwargs): - raise NotImplementedError + mem_map = { + "drtioaux": 0x50000000 + } + mem_map.update(SoCCore.mem_map) + + def __init__(self, description, acpki=False): + rtio_clk_freq = 125e6 # should this be pulled from description? rtio freq isnt set + + self.acpki = acpki + self.rustc_cfg = dict() + + platform = kasli_soc.Platform() + platform.toolchain.bitstream_commands.extend([ + "set_property BITSTREAM.GENERAL.COMPRESS True [current_design]", + ]) + ident = self.__class__.__name__ + if self.acpki: + ident = "acpki_" + ident + SoCCore.__init__(self, platform=platform, csr_data_width=32, ident=ident) + + platform.add_platform_command("create_clock -name clk_fpga_0 -period 8 [get_pins \"PS7/FCLKCLK[0]\"]") + platform.add_platform_command("set_input_jitter clk_fpga_0 0.24") + + # kasli_soc has no SATA, but it has 4x SFP + # not sure yet why sfp0 is omitted in MasterMode + drtio_data_pads = [platform.request("sfp", i) for i in range(4)] + + self.submodules.drtio_transceiver = gtp_7series.GTP( + qpll_channel=self.drtio_qpll_channel, # todo figure out qpll + data_pads=drtio_data_pads, + sys_clk_freq=self.clk_freq, + rtio_clk_freq=rtio_clk_freq) + self.csr_devices.append("drtio_transceiver") + # todo figure out cdr lk clean + # self.sync += self.disable_cdr_clk_ibuf.eq( + # ~self.drtio_transceiver.stable_clkin.storage) + + # ====end drtio for now + + self.crg = self.ps7 # HACK for eem_7series to find the clock + self.submodules.rtio_crg = RTIOCRG(self.platform) + self.csr_devices.append("rtio_crg") + self.platform.add_period_constraint(self.rtio_crg.cd_rtio.clk, 8.) + self.platform.add_false_path_constraints( + self.ps7.cd_sys.clk, + self.rtio_crg.cd_rtio.clk) + + self.rtio_channels = [] + has_grabber = any(peripheral["type"] == "grabber" for peripheral in description["peripherals"]) + if has_grabber: + self.grabber_csr_group = [] + eem_7series.add_peripherals(self, description["peripherals"], iostandard=eem_iostandard) + for i in (0, 1): + print("USER LED at RTIO channel 0x{:06x}".format(len(self.rtio_channels))) + user_led = self.platform.request("user_led", i) + phy = ttl_simple.Output(user_led) + self.submodules += phy + self.rtio_channels.append(rtio.Channel.from_phy(phy)) + self.config["RTIO_LOG_CHANNEL"] = len(self.rtio_channels) + self.rtio_channels.append(rtio.LogChannel()) + + self.submodules.rtio_tsc = rtio.TSC("async", glbl_fine_ts_width=3) + + # lifted from MasterBase + + drtio_csr_group = [] + drtioaux_csr_group = [] + drtioaux_memory_group = [] + self.drtio_cri = [] + for i in range(len(self.drtio_transceiver.channels)): + core_name = "drtio" + str(i) + coreaux_name = "drtioaux" + str(i) + memory_name = "drtioaux" + str(i) + "_mem" + drtio_csr_group.append(core_name) + drtioaux_csr_group.append(coreaux_name) + drtioaux_memory_group.append(memory_name) + + cdr = ClockDomainsRenamer({"rtio_rx": "rtio_rx" + str(i)}) + + core = cdr(DRTIOMaster(self.rtio_tsc, self.drtio_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)) + 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.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) + + # lift end + + self.submodules.rtio_core = rtio.Core(self.rtio_tsc, self.rtio_channels) + self.csr_devices.append("rtio_core") + + if self.acpki: + self.rustc_cfg["ki_impl"] = "acp" + self.submodules.rtio = acpki.KernelInitiator(self.rtio_tsc, + bus=self.ps7.s_axi_acp, + user=self.ps7.s_axi_acp_user, + evento=self.ps7.event.o) + self.csr_devices.append("rtio") + else: + self.rustc_cfg["ki_impl"] = "csr" + self.submodules.rtio = rtio.KernelInitiator(self.rtio_tsc, now64=True) + self.csr_devices.append("rtio") + + self.submodules.rtio_dma = dma.DMA(self.ps7.s_axi_hp0) + self.csr_devices.append("rtio_dma") + + self.submodules.cri_con = rtio.CRIInterconnectShared( + [self.rtio.cri, self.rtio_dma.cri], + [self.rtio_core.cri]) + self.csr_devices.append("cri_con") + + self.submodules.rtio_moninj = rtio.MonInj(self.rtio_channels) + self.csr_devices.append("rtio_moninj") + + self.submodules.routing_table = rtio.RoutingTableAccess(self.cri_con) + self.csr_devices.append("routing_table") + + self.submodules.rtio_analyzer = analyzer.Analyzer(self.rtio_tsc, self.rtio_core.cri, + self.ps7.s_axi_hp1) + self.csr_devices.append("rtio_analyzer") + + if has_grabber: + self.rustc_cfg["has_grabber"] = None + self.add_csr_group("grabber", self.grabber_csr_group) + for grabber in self.grabber_csr_group: + self.platform.add_false_path_constraints( + self.rtio_crg.cd_rtio.clk, getattr(self, grabber).deserializer.cd_cl.clk) class GenericSatellite(SoCCore): - def __init__(self, description, **kwargs): - raise NotImplementedError + mem_map = { + "drtioaux": 0x50000000 + } + mem_map.update(SoCCore.mem_map) + + def __init__(self, description, acpki=False): + rtio_clk_freq = 125e6 # same thing as with master + + self.acpki = acpki + self.rustc_cfg = dict() + + platform = kasli_soc.Platform() + platform.toolchain.bitstream_commands.extend([ + "set_property BITSTREAM.GENERAL.COMPRESS True [current_design]", + ]) + ident = self.__class__.__name__ + if self.acpki: + ident = "acpki_" + ident + SoCCore.__init__(self, platform=platform, csr_data_width=32, ident=ident) + + platform.add_platform_command("create_clock -name clk_fpga_0 -period 8 [get_pins \"PS7/FCLKCLK[0]\"]") + platform.add_platform_command("set_input_jitter clk_fpga_0 0.24") + + drtio_data_pads = [platform.request("sfp", i) for i in range(4)] + + self.submodules.drtio_transceiver = gtp_7series.GTP( + qpll_channel=qpll.channels[0], # todo - figure out qpll + data_pads=drtio_data_pads, + sys_clk_freq=self.clk_freq, + rtio_clk_freq=rtio_clk_freq) + self.csr_devices.append("drtio_transceiver") + # same here - figure out the relations + # self.sync += disable_cdr_clk_ibuf.eq( + # ~self.drtio_transceiver.stable_clkin.storage) + + sfp_channels = self.drtio_transceiver.channels + + self.crg = self.ps7 # HACK for eem_7series to find the clock + self.submodules.rtio_crg = RTIOCRG(self.platform) + self.csr_devices.append("rtio_crg") + self.platform.add_period_constraint(self.rtio_crg.cd_rtio.clk, 8.) + self.platform.add_false_path_constraints( + self.ps7.cd_sys.clk, + self.rtio_crg.cd_rtio.clk) + + self.rtio_channels = [] + has_grabber = any(peripheral["type"] == "grabber" for peripheral in description["peripherals"]) + if has_grabber: + self.grabber_csr_group = [] + eem_7series.add_peripherals(self, description["peripherals"], iostandard=eem_iostandard) + for i in (0, 1): + print("USER LED at RTIO channel 0x{:06x}".format(len(self.rtio_channels))) + user_led = self.platform.request("user_led", i) + phy = ttl_simple.Output(user_led) + self.submodules += phy + self.rtio_channels.append(rtio.Channel.from_phy(phy)) + self.config["RTIO_LOG_CHANNEL"] = len(self.rtio_channels) + self.rtio_channels.append(rtio.LogChannel()) + + # TSC is set to "sync" not "async" in SatelliteBase + self.submodules.rtio_tsc = rtio.TSC("sync", glbl_fine_ts_width=3) + # there is also no core + + 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) + + cdr = ClockDomainsRenamer({"rtio_rx": "rtio_rx" + str(i)}) + + if i == 0: + self.submodules.rx_synchronizer = cdr(XilinxRXSynchronizer()) + core = cdr(DRTIOSatellite( + self.rtio_tsc, self.drtio_transceiver.channels[i], + self.rx_synchronizer)) + self.submodules.drtiosat = core + self.csr_devices.append("drtiosat") + 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.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) + + if self.acpki: + self.rustc_cfg["ki_impl"] = "acp" + self.submodules.rtio = acpki.KernelInitiator(self.rtio_tsc, + bus=self.ps7.s_axi_acp, + user=self.ps7.s_axi_acp_user, + evento=self.ps7.event.o) + self.csr_devices.append("rtio") + else: + self.rustc_cfg["ki_impl"] = "csr" + self.submodules.rtio = rtio.KernelInitiator(self.rtio_tsc, now64=True) + self.csr_devices.append("rtio") + + self.submodules.rtio_dma = dma.DMA(self.ps7.s_axi_hp0) + self.csr_devices.append("rtio_dma") + + self.submodules.cri_con = rtio.CRIInterconnectShared( + [self.rtio.cri, self.rtio_dma.cri], + [self.rtio_core.cri]) + self.csr_devices.append("cri_con") + + self.submodules.rtio_moninj = rtio.MonInj(self.rtio_channels) + self.csr_devices.append("rtio_moninj") + + self.submodules.rtio_analyzer = analyzer.Analyzer(self.rtio_tsc, self.rtio_core.cri, + self.ps7.s_axi_hp1) + self.csr_devices.append("rtio_analyzer") + + self.submodules.siphaser = SiPhaser7Series( + si5324_clkin=platform.request("cdr_clk"), + rx_synchronizer=self.rx_synchronizer, + ref_clk=self.crg.clk125_div2, ref_div2=True, + rtio_clk_freq=rtio_clk_freq) + platform.add_false_path_constraints( + self.crg.cd_sys.clk, self.siphaser.mmcm_freerun_output) + self.csr_devices.append("siphaser") + self.config["HAS_SI5324"] = None + self.config["SI5324_SOFT_RESET"] = None + + if has_grabber: + self.rustc_cfg["has_grabber"] = None + self.add_csr_group("grabber", self.grabber_csr_group) + for grabber in self.grabber_csr_group: + self.platform.add_false_path_constraints( + self.rtio_crg.cd_rtio.clk, getattr(self, grabber).deserializer.cd_cl.clk) + def write_csr_file(soc, filename):