From 6353f6d5909ec4d04450798d88c6cbe70de6ddfc Mon Sep 17 00:00:00 2001 From: Sebastien Bourdeauducq Date: Fri, 2 Dec 2016 17:22:22 +0800 Subject: [PATCH] drtio: support different configurations and speeds --- .../gateware/drtio/transceiver/gtx_7series.py | 17 ++++-- artiq/gateware/targets/kc705_drtio_master.py | 56 ++++++++++++++++--- .../gateware/targets/kc705_drtio_satellite.py | 56 ++++++++++++++++--- 3 files changed, 107 insertions(+), 22 deletions(-) diff --git a/artiq/gateware/drtio/transceiver/gtx_7series.py b/artiq/gateware/drtio/transceiver/gtx_7series.py index 74ee4f1af..6c0a3e789 100644 --- a/artiq/gateware/drtio/transceiver/gtx_7series.py +++ b/artiq/gateware/drtio/transceiver/gtx_7series.py @@ -7,11 +7,10 @@ from misoc.interconnect.csr import * from artiq.gateware.drtio.transceiver.gtx_7series_init import * -class GTX_1000BASE_BX10(Module): - rtio_clk_freq = 62.5e6 - - # The transceiver clock on clock_pads must be 62.5MHz - # when clock_div2=False, and 125MHz when clock_div2=True. +class GTX_20X(Module): + # The transceiver clock on clock_pads must be at the RTIO clock + # frequency when clock_div2=False, and 2x that frequency when + # clock_div2=True. def __init__(self, clock_pads, tx_pads, rx_pads, sys_clk_freq, clock_div2=False): self.submodules.encoder = ClockDomainsRenamer("rtio")( @@ -192,6 +191,14 @@ class GTX_1000BASE_BX10(Module): ] +class GTX_1000BASE_BX10(GTX_20X): + rtio_clk_freq = 62.5e6 + + +class GTX_3G(GTX_20X): + rtio_clk_freq = 150e6 + + class RXSynchronizer(Module, AutoCSR): """Delays the data received in the rtio_rx by a configurable amount so that it meets s/h in the rtio domain, and recapture it in the rtio diff --git a/artiq/gateware/targets/kc705_drtio_master.py b/artiq/gateware/targets/kc705_drtio_master.py index 342ef62bf..8fb5cd1a4 100755 --- a/artiq/gateware/targets/kc705_drtio_master.py +++ b/artiq/gateware/targets/kc705_drtio_master.py @@ -3,6 +3,7 @@ import argparse from migen import * +from migen.build.generic_platform import * from misoc.targets.kc705 import MiniSoC, soc_kc705_args, soc_kc705_argdict from misoc.integration.builder import builder_args, builder_argdict @@ -15,6 +16,14 @@ from artiq.gateware.drtio import DRTIOMaster from artiq import __version__ as artiq_version +fmc_clock_io = [ + ("ad9154_refclk", 0, + Subsignal("p", Pins("HPC:GBTCLK0_M2C_P")), + Subsignal("n", Pins("HPC:GBTCLK0_M2C_N")), + ) +] + + class Master(MiniSoC, AMPSoC): mem_map = { "timer_kernel": 0x10000000, @@ -24,7 +33,7 @@ class Master(MiniSoC, AMPSoC): } mem_map.update(MiniSoC.mem_map) - def __init__(self, **kwargs): + def __init__(self, cfg, medium, **kwargs): MiniSoC.__init__(self, cpu_type="or1k", sdram_controller_type="minicon", @@ -36,13 +45,36 @@ class Master(MiniSoC, AMPSoC): platform = self.platform - self.comb += platform.request("sfp_tx_disable_n").eq(1) - self.submodules.transceiver = gtx_7series.GTX_1000BASE_BX10( - clock_pads=platform.request("sgmii_clock"), - tx_pads=platform.request("sfp_tx"), - rx_pads=platform.request("sfp_rx"), - sys_clk_freq=self.clk_freq, - clock_div2=True) + if medium == "sfp": + self.comb += platform.request("sfp_tx_disable_n").eq(1) + tx_pads = platform.request("sfp_tx") + rx_pads = platform.request("sfp_rx") + elif medium == "sma": + tx_pads = platform.request("user_sma_mgt_tx") + rx_pads = platform.request("user_sma_mgt_rx") + else: + raise ValueError + + if cfg == "simple_gbe": + # GTX_1000BASE_BX10 Ethernet compatible, 62.5MHz RTIO clock + # simple TTLs + self.submodules.transceiver = gtx_7series.GTX_1000BASE_BX10( + clock_pads=platform.request("sgmii_clock"), + tx_pads=tx_pads, + rx_pads=rx_pads, + sys_clk_freq=self.clk_freq, + clock_div2=True) + elif cfg == "sawg_3g": + # 3Gb link, 150MHz RTIO clock + # with SAWG on local RTIO and AD9154-FMC-EBZ + platform.register_extension(fmc_clock_io) + self.submodules.transceiver = gtx_7series.GTX_3G( + clock_pads=platform.request("ad9154_refclk"), + tx_pads=tx_pads, + rx_pads=rx_pads, + sys_clk_freq=self.clk_freq) + else: + raise ValueError self.submodules.drtio = DRTIOMaster(self.transceiver) self.csr_devices.append("drtio") @@ -71,9 +103,15 @@ def main(): description="ARTIQ with DRTIO on KC705 - Master") builder_args(parser) soc_kc705_args(parser) + parser.add_argument("-c", "--config", default="simple_gbe", + help="configuration: simple_gbe/sawg_3g " + "(default: %(default)s)") + parser.add_argument("--medium", default="sfp", + help="medium to use for transceiver link: sfp/sma " + "(default: %(default)s)") args = parser.parse_args() - soc = Master(**soc_kc705_argdict(args)) + soc = Master(args.config, args.medium, **soc_kc705_argdict(args)) build_artiq_soc(soc, builder_argdict(args)) diff --git a/artiq/gateware/targets/kc705_drtio_satellite.py b/artiq/gateware/targets/kc705_drtio_satellite.py index 32795634f..7a882ab94 100755 --- a/artiq/gateware/targets/kc705_drtio_satellite.py +++ b/artiq/gateware/targets/kc705_drtio_satellite.py @@ -1,6 +1,7 @@ import argparse from migen import * +from migen.build.generic_platform import * from migen.build.platforms import kc705 from misoc.cores.i2c import * @@ -12,6 +13,7 @@ from artiq.gateware.drtio.transceiver import gtx_7series from artiq.gateware.drtio import DRTIOSatellite +# TODO: parameters for sawg_3g def get_i2c_program(sys_clk_freq): # NOTE: the logical parameters DO NOT MAP to physical values written # into registers. They have to be mapped; see the datasheet. @@ -111,8 +113,16 @@ class Si5324ResetClock(Module): ) +fmc_clock_io = [ + ("ad9154_refclk", 0, + Subsignal("p", Pins("HPC:GBTCLK0_M2C_P")), + Subsignal("n", Pins("HPC:GBTCLK0_M2C_N")), + ) +] + + class Satellite(Module): - def __init__(self, toolchain="vivado"): + def __init__(self, cfg, medium, toolchain): self.platform = platform = kc705.Platform(toolchain=toolchain) rtio_channels = [] @@ -141,12 +151,36 @@ class Satellite(Module): sequencer.reset.eq(si5324_reset_clock.si5324_not_ready) ] - self.comb += platform.request("sfp_tx_disable_n").eq(1) - self.submodules.transceiver = gtx_7series.GTX_1000BASE_BX10( - clock_pads=platform.request("si5324_clkout"), - tx_pads=platform.request("sfp_tx"), - rx_pads=platform.request("sfp_rx"), - sys_clk_freq=sys_clk_freq) + if medium == "sfp": + self.comb += platform.request("sfp_tx_disable_n").eq(1) + tx_pads = platform.request("sfp_tx") + rx_pads = platform.request("sfp_rx") + elif medium == "sma": + tx_pads = platform.request("user_sma_mgt_tx") + rx_pads = platform.request("user_sma_mgt_rx") + else: + raise ValueError + + if cfg == "simple_gbe": + # GTX_1000BASE_BX10 Ethernet compatible, 62.5MHz RTIO clock + # simple TTLs + self.submodules.transceiver = gtx_7series.GTX_1000BASE_BX10( + clock_pads=platform.request("sgmii_clock"), + tx_pads=tx_pads, + rx_pads=rx_pads, + sys_clk_freq=sys_clk_freq, + clock_div2=True) + elif cfg == "sawg_3g": + # 3Gb link, 150MHz RTIO clock + # with SAWG on local RTIO and AD9154-FMC-EBZ + platform.register_extension(fmc_clock_io) + self.submodules.transceiver = gtx_7series.GTX_3G( + clock_pads=platform.request("ad9154_refclk"), + tx_pads=tx_pads, + rx_pads=rx_pads, + sys_clk_freq=sys_clk_freq) + else: + raise ValueError self.submodules.rx_synchronizer = gtx_7series.RXSynchronizer( self.transceiver.rtio_clk_freq) self.submodules.drtio = DRTIOSatellite( @@ -163,9 +197,15 @@ def main(): parser.add_argument("--output-dir", default="drtiosat_kc705", help="output directory for generated " "source files and binaries") + parser.add_argument("-c", "--config", default="simple_gbe", + help="configuration: simple_gbe/sawg_3g " + "(default: %(default)s)") + parser.add_argument("--medium", default="sfp", + help="medium to use for transceiver link: sfp/sma " + "(default: %(default)s)") args = parser.parse_args() - top = Satellite(args.toolchain) + top = Satellite(args.config, args.medium, args.toolchain) top.build(build_dir=args.output_dir) if __name__ == "__main__":