diff --git a/artiq/gateware/targets/kc705.py b/artiq/gateware/targets/kc705.py index 1481fd351..0c1c431b6 100755 --- a/artiq/gateware/targets/kc705.py +++ b/artiq/gateware/targets/kc705.py @@ -11,12 +11,16 @@ from migen.build.xilinx.ise import XilinxISEToolchain from misoc.interconnect.csr import * from misoc.cores import gpio, timer -from misoc.targets.kc705 import MiniSoC, soc_kc705_args, soc_kc705_argdict +from misoc.targets.kc705 import BaseSoC, MiniSoC, soc_kc705_args, soc_kc705_argdict from misoc.integration.builder import builder_args, builder_argdict from artiq.gateware.amp import AMPSoC from artiq.gateware import rtio, nist_clock, nist_qc2 from artiq.gateware.rtio.phy import ttl_simple, ttl_serdes_7series, dds, spi2 +from artiq.gateware.drtio.transceiver import gtx_7series +from artiq.gateware.drtio.siphaser import SiPhaser7Series +from artiq.gateware.drtio.rx_synchronizer import XilinxRXSynchronizer +from artiq.gateware.drtio import * from artiq.build_soc import * @@ -109,7 +113,6 @@ _sdcard_spi_33 = [ ] - class _StandaloneBase(MiniSoC, AMPSoC): mem_map = { "cri_con": 0x10000000, @@ -187,13 +190,294 @@ class _StandaloneBase(MiniSoC, AMPSoC): self.csr_devices.append("rtio_analyzer") -class NIST_CLOCK(_StandaloneBase): +class _MasterBase(MiniSoC, AMPSoC): + mem_map = { + "cri_con": 0x10000000, + "rtio": 0x20000000, + "rtio_dma": 0x30000000, + "drtioaux": 0x50000000, + "mailbox": 0x70000000 + } + mem_map.update(MiniSoC.mem_map) + + def __init__(self, gateware_identifier_str=None, **kwargs): + MiniSoC.__init__(self, + cpu_type="or1k", + sdram_controller_type="minicon", + l2_size=128*1024, + integrated_sram_size=8192, + ethmac_nrxslots=4, + ethmac_ntxslots=4, + **kwargs) + AMPSoC.__init__(self) + add_identifier(self, gateware_identifier_str=gateware_identifier_str) + + if isinstance(self.platform.toolchain, XilinxVivadoToolchain): + self.platform.toolchain.bitstream_commands.extend([ + "set_property BITSTREAM.GENERAL.COMPRESS True [current_design]", + ]) + if isinstance(self.platform.toolchain, XilinxISEToolchain): + self.platform.toolchain.bitgen_opt += " -g compress" + + platform = self.platform + platform.add_extension(_sma33_io) + platform.add_extension(_ams101_dac) + platform.add_extension(_sdcard_spi_33) + + self.comb += platform.request("sfp_tx_disable_n").eq(1) + tx_pads = [ + platform.request("sfp_tx"), platform.request("user_sma_mgt_tx") + ] + rx_pads = [ + platform.request("sfp_rx"), platform.request("user_sma_mgt_rx") + ] + + # 1000BASE_BX10 Ethernet compatible, 125MHz RTIO clock + self.submodules.drtio_transceiver = gtx_7series.GTX( + clock_pads=platform.request("si5324_clkout"), + tx_pads=tx_pads, + rx_pads=rx_pads, + sys_clk_freq=self.clk_freq) + self.csr_devices.append("drtio_transceiver") + + self.submodules.rtio_tsc = rtio.TSC("async", glbl_fine_ts_width=3) + + 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) + + self.config["RTIO_FREQUENCY"] = str(self.drtio_transceiver.rtio_clk_freq/1e6) + self.submodules.si5324_rst_n = gpio.GPIOOut(platform.request("si5324").rst_n) + self.csr_devices.append("si5324_rst_n") + i2c = self.platform.request("i2c") + self.submodules.i2c = gpio.GPIOTristate([i2c.scl, i2c.sda]) + self.csr_devices.append("i2c") + self.config["I2C_BUS_COUNT"] = 1 + self.config["HAS_SI5324"] = None + self.config["SI5324_AS_SYNTHESIZER"] = None + + self.comb += [ + platform.request("user_sma_clock_p").eq(ClockSignal("rtio_rx0")), + platform.request("user_sma_clock_n").eq(ClockSignal("rtio")) + ] + + rtio_clk_period = 1e9/self.drtio_transceiver.rtio_clk_freq + # Constrain TX & RX timing for the first transceiver channel + # (First channel acts as master for phase alignment for all channels' TX) + gtx0 = self.drtio_transceiver.gtxs[0] + platform.add_period_constraint(gtx0.txoutclk, rtio_clk_period) + platform.add_period_constraint(gtx0.rxoutclk, rtio_clk_period) + platform.add_false_path_constraints( + self.crg.cd_sys.clk, + gtx0.txoutclk, gtx0.rxoutclk) + # Constrain RX timing for the each transceiver channel + # (Each channel performs single-lane phase alignment for RX) + for gtx in self.drtio_transceiver.gtxs[1:]: + platform.add_period_constraint(gtx.rxoutclk, rtio_clk_period) + platform.add_false_path_constraints( + self.crg.cd_sys.clk, gtx0.txoutclk, gtx.rxoutclk) + + def add_rtio(self, rtio_channels): + self.submodules.rtio_moninj = rtio.MonInj(rtio_channels) + self.csr_devices.append("rtio_moninj") + + self.submodules.rtio_core = rtio.Core(self.rtio_tsc, rtio_channels) + self.csr_devices.append("rtio_core") + + self.submodules.rtio = rtio.KernelInitiator(self.rtio_tsc) + self.submodules.rtio_dma = ClockDomainsRenamer("sys_kernel")( + rtio.DMA(self.get_native_sdram_if())) + self.register_kernel_cpu_csrdevice("rtio") + self.register_kernel_cpu_csrdevice("rtio_dma") + self.submodules.cri_con = rtio.CRIInterconnectShared( + [self.rtio.cri, self.rtio_dma.cri], + [self.rtio_core.cri] + self.drtio_cri, + enable_routing=True) + self.register_kernel_cpu_csrdevice("cri_con") + self.submodules.routing_table = rtio.RoutingTableAccess(self.cri_con) + self.csr_devices.append("routing_table") + + +class _SatelliteBase(BaseSoC): + mem_map = { + "drtioaux": 0x50000000, + } + mem_map.update(BaseSoC.mem_map) + + def __init__(self, gateware_identifier_str=None, sma_as_sat=False, **kwargs): + BaseSoC.__init__(self, + cpu_type="or1k", + sdram_controller_type="minicon", + l2_size=128*1024, + integrated_sram_size=8192, + **kwargs) + add_identifier(self, gateware_identifier_str=gateware_identifier_str) + + if isinstance(self.platform.toolchain, XilinxVivadoToolchain): + self.platform.toolchain.bitstream_commands.extend([ + "set_property BITSTREAM.GENERAL.COMPRESS True [current_design]", + ]) + if isinstance(self.platform.toolchain, XilinxISEToolchain): + self.platform.toolchain.bitgen_opt += " -g compress" + + platform = self.platform + platform.add_extension(_sma33_io) + platform.add_extension(_ams101_dac) + platform.add_extension(_sdcard_spi_33) + + self.comb += platform.request("sfp_tx_disable_n").eq(1) + 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 sma_as_sat: + tx_pads = tx_pads[::-1] + rx_pads = rx_pads[::-1] + + # 1000BASE_BX10 Ethernet compatible, 125MHz RTIO clock + self.submodules.drtio_transceiver = gtx_7series.GTX( + clock_pads=platform.request("si5324_clkout"), + tx_pads=tx_pads, + rx_pads=rx_pads, + sys_clk_freq=self.clk_freq) + self.csr_devices.append("drtio_transceiver") + + self.submodules.rtio_tsc = rtio.TSC("sync", glbl_fine_ts_width=3) + + 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)}) + + # 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.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 + self.submodules.siphaser = SiPhaser7Series( + si5324_clkin=platform.request("si5324_clkin"), + rx_synchronizer=self.rx_synchronizer, + ultrascale=False, + rtio_clk_freq=self.drtio_transceiver.rtio_clk_freq) + platform.add_false_path_constraints( + self.crg.cd_sys.clk, self.siphaser.mmcm_freerun_output) + self.csr_devices.append("siphaser") + self.submodules.si5324_rst_n = gpio.GPIOOut(platform.request("si5324").rst_n) + self.csr_devices.append("si5324_rst_n") + i2c = self.platform.request("i2c") + self.submodules.i2c = gpio.GPIOTristate([i2c.scl, i2c.sda]) + self.csr_devices.append("i2c") + self.config["I2C_BUS_COUNT"] = 1 + self.config["HAS_SI5324"] = None + + self.comb += [ + platform.request("user_sma_clock_p").eq(ClockSignal("rtio_rx0")), + platform.request("user_sma_clock_n").eq(ClockSignal("rtio")) + ] + + rtio_clk_period = 1e9/self.drtio_transceiver.rtio_clk_freq + # Constrain TX & RX timing for the first transceiver channel + # (First channel acts as master for phase alignment for all channels' TX) + gtx0 = self.drtio_transceiver.gtxs[0] + platform.add_period_constraint(gtx0.txoutclk, rtio_clk_period) + platform.add_period_constraint(gtx0.rxoutclk, rtio_clk_period) + platform.add_false_path_constraints( + self.crg.cd_sys.clk, + gtx0.txoutclk, gtx0.rxoutclk) + # Constrain RX timing for the each transceiver channel + # (Each channel performs single-lane phase alignment for RX) + for gtx in self.drtio_transceiver.gtxs[1:]: + platform.add_period_constraint(gtx.rxoutclk, rtio_clk_period) + platform.add_false_path_constraints( + self.crg.cd_sys.clk, gtx.rxoutclk) + + def add_rtio(self, rtio_channels): + self.submodules.rtio_moninj = rtio.MonInj(rtio_channels) + self.csr_devices.append("rtio_moninj") + + self.submodules.local_io = SyncRTIO(self.rtio_tsc, rtio_channels) + self.comb += self.drtiosat.async_errors.eq(self.local_io.async_errors) + 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") + + +class _NIST_CLOCK_RTIO: """ NIST clock hardware, with old backplane and 11 DDS channels """ - def __init__(self, **kwargs): - _StandaloneBase.__init__(self, **kwargs) - + def __init__(self): platform = self.platform platform.add_extension(nist_clock.fmc_adapter_io) @@ -257,14 +541,12 @@ class NIST_CLOCK(_StandaloneBase): self.add_rtio(rtio_channels) -class NIST_QC2(_StandaloneBase): +class _NIST_QC2_RTIO: """ NIST QC2 hardware, as used in Quantum I and Quantum II, with new backplane and 24 DDS channels. Two backplanes are used. """ - def __init__(self, **kwargs): - _StandaloneBase.__init__(self, **kwargs) - + def __init__(self): platform = self.platform platform.add_extension(nist_qc2.fmc_adapter_io) @@ -327,94 +609,61 @@ class NIST_QC2(_StandaloneBase): self.add_rtio(rtio_channels) -_sma_spi = [ - ("sma_spi", 0, - Subsignal("clk", Pins("Y23")), # user_sma_gpio_p - Subsignal("cs_n", Pins("Y24")), # user_sma_gpio_n - Subsignal("mosi", Pins("L25")), # user_sma_clk_p - Subsignal("miso", Pins("K25")), # user_sma_clk_n - IOStandard("LVCMOS25")), -] - - -class SMA_SPI(_StandaloneBase): - """ - SPI on 4 SMA for PDQ2 test/demo. - """ +class NIST_CLOCK(_StandaloneBase, _NIST_CLOCK_RTIO): def __init__(self, **kwargs): _StandaloneBase.__init__(self, **kwargs) - - platform = self.platform - self.platform.add_extension(_sma_spi) - - rtio_channels = [] - - phy = ttl_simple.Output(platform.request("user_led", 2)) - self.submodules += phy - rtio_channels.append(rtio.Channel.from_phy(phy)) - - ams101_dac = self.platform.request("ams101_dac", 0) - phy = ttl_simple.Output(ams101_dac.ldac) - self.submodules += phy - rtio_channels.append(rtio.Channel.from_phy(phy)) - - phy = spi2.SPIMaster(ams101_dac) - self.submodules += phy - rtio_channels.append(rtio.Channel.from_phy( - phy, ififo_depth=4)) - - phy = spi2.SPIMaster(self.platform.request("sma_spi")) - self.submodules += phy - rtio_channels.append(rtio.Channel.from_phy( - phy, ififo_depth=128)) - - self.config["HAS_RTIO_LOG"] = None - self.config["RTIO_LOG_CHANNEL"] = len(rtio_channels) - rtio_channels.append(rtio.LogChannel()) - - self.add_rtio(rtio_channels) - - def add_rtio(self, rtio_channels): - self.submodules.rtio_crg = _RTIOCRG(self.platform, self.crg.cd_sys.clk, - use_sma=False) - self.csr_devices.append("rtio_crg") - self.config["HAS_RTIO_CLOCK_SWITCH"] = None - self.submodules.rtio_tsc = rtio.TSC("async", glbl_fine_ts_width=3) - self.submodules.rtio_core = rtio.Core(self.rtio_tsc, rtio_channels) - self.csr_devices.append("rtio_core") - self.submodules.rtio = rtio.KernelInitiator(self.rtio_tsc) - self.submodules.rtio_dma = ClockDomainsRenamer("sys_kernel")( - rtio.DMA(self.get_native_sdram_if())) - self.register_kernel_cpu_csrdevice("rtio") - self.register_kernel_cpu_csrdevice("rtio_dma") - self.submodules.cri_con = rtio.CRIInterconnectShared( - [self.rtio.cri, self.rtio_dma.cri], - [self.rtio_core.cri]) - self.submodules.rtio_moninj = rtio.MonInj(rtio_channels) - self.csr_devices.append("rtio_moninj") - - self.platform.add_period_constraint(self.rtio_crg.cd_rtio.clk, 8.) - self.platform.add_false_path_constraints( - self.crg.cd_sys.clk, - self.rtio_crg.cd_rtio.clk) - - self.submodules.rtio_analyzer = rtio.Analyzer(self.rtio_tsc, self.rtio_core.cri, - self.get_native_sdram_if()) - self.csr_devices.append("rtio_analyzer") + _NIST_CLOCK_RTIO.__init__(self) -VARIANTS = {cls.__name__.lower(): cls for cls in [NIST_CLOCK, NIST_QC2, SMA_SPI]} +class NIST_QC2(_StandaloneBase, _NIST_QC2_RTIO): + def __init__(self, **kwargs): + _StandaloneBase.__init__(self, **kwargs) + _NIST_QC2_RTIO.__init__(self) + + +class NIST_CLOCK_Master(_MasterBase, _NIST_CLOCK_RTIO): + def __init__(self, **kwargs): + _MasterBase.__init__(self, **kwargs) + _NIST_CLOCK_RTIO.__init__(self) + + +class NIST_QC2_Master(_MasterBase, _NIST_QC2_RTIO): + def __init__(self, **kwargs): + _MasterBase.__init__(self, **kwargs) + _NIST_QC2_RTIO.__init__(self) + + +class NIST_CLOCK_Satellite(_SatelliteBase, _NIST_CLOCK_RTIO): + def __init__(self, **kwargs): + _SatelliteBase.__init__(self, **kwargs) + _NIST_CLOCK_RTIO.__init__(self) + + +class NIST_QC2_Satellite(_SatelliteBase, _NIST_QC2_RTIO): + def __init__(self, **kwargs): + _SatelliteBase.__init__(self, **kwargs) + _NIST_QC2_RTIO.__init__(self) + + +VARIANT_CLS = [ + NIST_CLOCK, NIST_QC2, + NIST_CLOCK_Master, NIST_QC2_Master, + NIST_CLOCK_Satellite, NIST_QC2_Satellite, +] +VARIANTS = {cls.__name__.lower(): cls for cls in VARIANT_CLS} def main(): parser = argparse.ArgumentParser( - description="KC705 gateware and firmware builder") + description="ARTIQ device binary builder for KC705 systems") builder_args(parser) soc_kc705_args(parser) parser.set_defaults(output_dir="artiq_kc705") parser.add_argument("-V", "--variant", default="nist_clock", help="variant: " - "nist_clock/nist_qc2/sma_spi " + "[standalone: nist_clock/nist_qc2] " + "[DRTIO master: nist_clock_master/nist_qc2_master] " + "[DRTIO satellite: nist_clock_satellite/nist_qc2_satellite] " "(default: %(default)s)") parser.add_argument("--gateware-identifier-str", default=None, help="Override ROM identifier") diff --git a/artiq/gateware/targets/kc705_drtio_master.py b/artiq/gateware/targets/kc705_drtio_master.py deleted file mode 100755 index 78d5d054b..000000000 --- a/artiq/gateware/targets/kc705_drtio_master.py +++ /dev/null @@ -1,180 +0,0 @@ -#!/usr/bin/env python3 - -import argparse - -from migen import * -from migen.build.generic_platform import * -from migen.build.xilinx.vivado import XilinxVivadoToolchain -from migen.build.xilinx.ise import XilinxISEToolchain - -from misoc.cores import spi as spi_csr -from misoc.cores import gpio -from misoc.integration.builder import * -from misoc.targets.kc705 import MiniSoC, soc_kc705_args, soc_kc705_argdict - -from artiq.gateware.amp import AMPSoC -from artiq.gateware import rtio -from artiq.gateware.rtio.phy import ttl_simple -from artiq.gateware.drtio.transceiver import gtx_7series -from artiq.gateware.drtio import * -from artiq.build_soc import * - - -class Master(MiniSoC, AMPSoC): - mem_map = { - "cri_con": 0x10000000, - "rtio": 0x20000000, - "rtio_dma": 0x30000000, - "drtioaux": 0x50000000, - "mailbox": 0x70000000 - } - mem_map.update(MiniSoC.mem_map) - - def __init__(self, gateware_identifier_str=None, **kwargs): - MiniSoC.__init__(self, - cpu_type="or1k", - sdram_controller_type="minicon", - l2_size=128*1024, - integrated_sram_size=8192, - ethmac_nrxslots=4, - ethmac_ntxslots=4, - **kwargs) - AMPSoC.__init__(self) - add_identifier(self, gateware_identifier_str=gateware_identifier_str) - - if isinstance(self.platform.toolchain, XilinxVivadoToolchain): - self.platform.toolchain.bitstream_commands.extend([ - "set_property BITSTREAM.GENERAL.COMPRESS True [current_design]", - ]) - if isinstance(self.platform.toolchain, XilinxISEToolchain): - self.platform.toolchain.bitgen_opt += " -g compress" - - platform = self.platform - - self.comb += platform.request("sfp_tx_disable_n").eq(1) - tx_pads = [ - platform.request("sfp_tx"), platform.request("user_sma_mgt_tx") - ] - rx_pads = [ - platform.request("sfp_rx"), platform.request("user_sma_mgt_rx") - ] - - # 1000BASE_BX10 Ethernet compatible, 125MHz RTIO clock - self.submodules.drtio_transceiver = gtx_7series.GTX( - clock_pads=platform.request("si5324_clkout"), - tx_pads=tx_pads, - rx_pads=rx_pads, - sys_clk_freq=self.clk_freq) - self.csr_devices.append("drtio_transceiver") - - self.submodules.rtio_tsc = rtio.TSC("async", glbl_fine_ts_width=3) - - drtio_csr_group = [] - drtioaux_csr_group = [] - drtioaux_memory_group = [] - 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) - 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) - - self.config["RTIO_FREQUENCY"] = str(self.drtio_transceiver.rtio_clk_freq/1e6) - self.submodules.si5324_rst_n = gpio.GPIOOut(platform.request("si5324").rst_n) - self.csr_devices.append("si5324_rst_n") - i2c = self.platform.request("i2c") - self.submodules.i2c = gpio.GPIOTristate([i2c.scl, i2c.sda]) - self.csr_devices.append("i2c") - self.config["I2C_BUS_COUNT"] = 1 - self.config["HAS_SI5324"] = None - self.config["SI5324_AS_SYNTHESIZER"] = None - - self.comb += [ - platform.request("user_sma_clock_p").eq(ClockSignal("rtio_rx0")), - platform.request("user_sma_clock_n").eq(ClockSignal("rtio")) - ] - - rtio_clk_period = 1e9/self.drtio_transceiver.rtio_clk_freq - # Constrain TX & RX timing for the first transceiver channel - # (First channel acts as master for phase alignment for all channels' TX) - gtx0 = self.drtio_transceiver.gtxs[0] - platform.add_period_constraint(gtx0.txoutclk, rtio_clk_period) - platform.add_period_constraint(gtx0.rxoutclk, rtio_clk_period) - platform.add_false_path_constraints( - self.crg.cd_sys.clk, - gtx0.txoutclk, gtx0.rxoutclk) - # Constrain RX timing for the each transceiver channel - # (Each channel performs single-lane phase alignment for RX) - for gtx in self.drtio_transceiver.gtxs[1:]: - platform.add_period_constraint(gtx.rxoutclk, rtio_clk_period) - platform.add_false_path_constraints( - self.crg.cd_sys.clk, gtx0.txoutclk, gtx.rxoutclk) - - rtio_channels = [] - for i in range(8): - phy = ttl_simple.Output(platform.request("user_led", i)) - self.submodules += phy - rtio_channels.append(rtio.Channel.from_phy(phy)) - for sma in "user_sma_gpio_p", "user_sma_gpio_n": - phy = ttl_simple.InOut(platform.request(sma)) - self.submodules += phy - rtio_channels.append(rtio.Channel.from_phy(phy)) - - self.submodules.rtio_moninj = rtio.MonInj(rtio_channels) - self.csr_devices.append("rtio_moninj") - - self.submodules.rtio_core = rtio.Core(self.rtio_tsc, rtio_channels) - self.csr_devices.append("rtio_core") - - self.submodules.rtio = rtio.KernelInitiator(self.rtio_tsc) - self.submodules.rtio_dma = ClockDomainsRenamer("sys_kernel")( - rtio.DMA(self.get_native_sdram_if())) - self.register_kernel_cpu_csrdevice("rtio") - self.register_kernel_cpu_csrdevice("rtio_dma") - self.submodules.cri_con = rtio.CRIInterconnectShared( - [self.rtio.cri, self.rtio_dma.cri], - [self.rtio_core.cri] + drtio_cri, - enable_routing=True) - self.register_kernel_cpu_csrdevice("cri_con") - self.submodules.routing_table = rtio.RoutingTableAccess(self.cri_con) - self.csr_devices.append("routing_table") - - -def main(): - parser = argparse.ArgumentParser( - description="ARTIQ device binary builder / KC705 DRTIO master") - builder_args(parser) - soc_kc705_args(parser) - parser.set_defaults(output_dir="artiq_kc705/master") - args = parser.parse_args() - - soc = Master(**soc_kc705_argdict(args)) - build_artiq_soc(soc, builder_argdict(args)) - - -if __name__ == "__main__": - main() diff --git a/artiq/gateware/targets/kc705_drtio_satellite.py b/artiq/gateware/targets/kc705_drtio_satellite.py deleted file mode 100755 index 4ff346fdf..000000000 --- a/artiq/gateware/targets/kc705_drtio_satellite.py +++ /dev/null @@ -1,194 +0,0 @@ -#!/usr/bin/env python3 - -import argparse - -from migen import * -from migen.build.generic_platform import * -from migen.build.xilinx.vivado import XilinxVivadoToolchain -from migen.build.xilinx.ise import XilinxISEToolchain - -from misoc.cores import spi as spi_csr -from misoc.cores import gpio -from misoc.integration.builder import * -from misoc.targets.kc705 import BaseSoC, soc_kc705_args, soc_kc705_argdict - -from artiq.gateware import rtio -from artiq.gateware.rtio.phy import ttl_simple -from artiq.gateware.drtio.transceiver import gtx_7series -from artiq.gateware.drtio.siphaser import SiPhaser7Series -from artiq.gateware.drtio.rx_synchronizer import XilinxRXSynchronizer -from artiq.gateware.drtio import * -from artiq.build_soc import * - - -class Satellite(BaseSoC): - mem_map = { - "drtioaux": 0x50000000, - } - mem_map.update(BaseSoC.mem_map) - - def __init__(self, gateware_identifier_str=None, sma_as_sat=False, **kwargs): - BaseSoC.__init__(self, - cpu_type="or1k", - sdram_controller_type="minicon", - l2_size=128*1024, - integrated_sram_size=8192, - **kwargs) - add_identifier(self, gateware_identifier_str=gateware_identifier_str) - - if isinstance(self.platform.toolchain, XilinxVivadoToolchain): - self.platform.toolchain.bitstream_commands.extend([ - "set_property BITSTREAM.GENERAL.COMPRESS True [current_design]", - ]) - if isinstance(self.platform.toolchain, XilinxISEToolchain): - self.platform.toolchain.bitgen_opt += " -g compress" - - platform = self.platform - - self.comb += platform.request("sfp_tx_disable_n").eq(1) - 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 sma_as_sat: - tx_pads = tx_pads[::-1] - rx_pads = rx_pads[::-1] - - # 1000BASE_BX10 Ethernet compatible, 125MHz RTIO clock - self.submodules.drtio_transceiver = gtx_7series.GTX( - clock_pads=platform.request("si5324_clkout"), - tx_pads=tx_pads, - rx_pads=rx_pads, - sys_clk_freq=self.clk_freq) - self.csr_devices.append("drtio_transceiver") - - self.submodules.rtio_tsc = rtio.TSC("sync", glbl_fine_ts_width=3) - - 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)}) - - # 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.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 - self.submodules.siphaser = SiPhaser7Series( - si5324_clkin=platform.request("si5324_clkin"), - rx_synchronizer=self.rx_synchronizer, - ultrascale=False, - rtio_clk_freq=self.drtio_transceiver.rtio_clk_freq) - platform.add_false_path_constraints( - self.crg.cd_sys.clk, self.siphaser.mmcm_freerun_output) - self.csr_devices.append("siphaser") - self.submodules.si5324_rst_n = gpio.GPIOOut(platform.request("si5324").rst_n) - self.csr_devices.append("si5324_rst_n") - i2c = self.platform.request("i2c") - self.submodules.i2c = gpio.GPIOTristate([i2c.scl, i2c.sda]) - self.csr_devices.append("i2c") - self.config["I2C_BUS_COUNT"] = 1 - self.config["HAS_SI5324"] = None - - self.comb += [ - platform.request("user_sma_clock_p").eq(ClockSignal("rtio_rx0")), - platform.request("user_sma_clock_n").eq(ClockSignal("rtio")) - ] - - rtio_clk_period = 1e9/self.drtio_transceiver.rtio_clk_freq - # Constrain TX & RX timing for the first transceiver channel - # (First channel acts as master for phase alignment for all channels' TX) - gtx0 = self.drtio_transceiver.gtxs[0] - platform.add_period_constraint(gtx0.txoutclk, rtio_clk_period) - platform.add_period_constraint(gtx0.rxoutclk, rtio_clk_period) - platform.add_false_path_constraints( - self.crg.cd_sys.clk, - gtx0.txoutclk, gtx0.rxoutclk) - # Constrain RX timing for the each transceiver channel - # (Each channel performs single-lane phase alignment for RX) - for gtx in self.drtio_transceiver.gtxs[1:]: - platform.add_period_constraint(gtx.rxoutclk, rtio_clk_period) - platform.add_false_path_constraints( - self.crg.cd_sys.clk, gtx.rxoutclk) - - rtio_channels = [] - for i in range(8): - phy = ttl_simple.Output(platform.request("user_led", i)) - self.submodules += phy - rtio_channels.append(rtio.Channel.from_phy(phy)) - for sma in "user_sma_gpio_p", "user_sma_gpio_n": - phy = ttl_simple.InOut(platform.request(sma)) - self.submodules += phy - rtio_channels.append(rtio.Channel.from_phy(phy)) - - self.submodules.rtio_moninj = rtio.MonInj(rtio_channels) - self.csr_devices.append("rtio_moninj") - - self.submodules.local_io = SyncRTIO(self.rtio_tsc, rtio_channels) - self.comb += self.drtiosat.async_errors.eq(self.local_io.async_errors) - 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(): - parser = argparse.ArgumentParser( - description="ARTIQ device binary builder / KC705 DRTIO satellite") - builder_args(parser) - soc_kc705_args(parser) - parser.set_defaults(output_dir="artiq_kc705/satellite") - parser.add_argument("--sma", default=False, action="store_true", - help="use the SMA connectors (RX: J17, J18, TX: J19, J20) " - "as DRTIO satellite channel instead of the SFP") - args = parser.parse_args() - - argdict = dict() - argdict["sma_as_sat"] = args.sma - - soc = Satellite(**soc_kc705_argdict(args), **argdict) - build_artiq_soc(soc, builder_argdict(args)) - - -if __name__ == "__main__": - main()