diff --git a/artiq/gateware/targets/sayma_amc_standalone.py b/artiq/gateware/targets/sayma_amc_standalone.py index ec0cc175d..b30e92853 100755 --- a/artiq/gateware/targets/sayma_amc_standalone.py +++ b/artiq/gateware/targets/sayma_amc_standalone.py @@ -7,9 +7,11 @@ from migen import * from misoc.cores import gpio from misoc.integration.soc_sdram import soc_sdram_args, soc_sdram_argdict from misoc.integration.builder import builder_args, builder_argdict +from misoc.interconnect import stream from misoc.targets.sayma_amc import MiniSoC from artiq.gateware.amp import AMPSoC, build_artiq_soc +from artiq.gateware import serwb from artiq.gateware import rtio from artiq.gateware.rtio.phy import ttl_simple from artiq import __version__ as artiq_version @@ -20,6 +22,7 @@ class SaymaAMCStandalone(MiniSoC, AMPSoC): "cri_con": 0x10000000, "rtio": 0x20000000, "rtio_dma": 0x30000000, + "serwb": 0x20000000, "mailbox": 0x70000000 } mem_map.update(MiniSoC.mem_map) @@ -51,6 +54,61 @@ class SaymaAMCStandalone(MiniSoC, AMPSoC): serial_rtm.tx.eq(serial_1.rx) ] + # AMC/RTM serwb + # TODO: cleanup (same comments as in sayma_rtm.py) + serwb_pll = serwb.kusphy.KUSSerdesPLL(self.clk_freq, 1.25e9, vco_div=2) + self.comb += serwb_pll.refclk.eq(self.crg.cd_sys.clk) + self.submodules += serwb_pll + + serwb_pads = platform.request("amc_rtm_serwb") + serwb_serdes = serwb.kusphy.KUSSerdes(serwb_pll, serwb_pads, mode="master") + self.submodules += serwb_serdes + serwb_init = serwb.phy.SerdesMasterInit(serwb_serdes, taps=512) + self.submodules += serwb_init + self.submodules.serwb_control = serwb.phy.SerdesControl(serwb_init, mode="master") + self.csr_devices.append("serwb_control") + + serwb_serdes.cd_serdes.clk.attr.add("keep") + serwb_serdes.cd_serdes_20x.clk.attr.add("keep") + serwb_serdes.cd_serdes_5x.clk.attr.add("keep") + platform.add_period_constraint(serwb_serdes.cd_serdes.clk, 32.0), + platform.add_period_constraint(serwb_serdes.cd_serdes_20x.clk, 1.6), + platform.add_period_constraint(serwb_serdes.cd_serdes_5x.clk, 6.4) + platform.add_false_path_constraints( + self.crg.cd_sys.clk, + serwb_serdes.cd_serdes.clk, + serwb_serdes.cd_serdes_5x.clk) + + serwb_depacketizer = serwb.packet.Depacketizer(self.clk_freq) + serwb_packetizer = serwb.packet.Packetizer() + self.submodules += serwb_depacketizer, serwb_packetizer + serwb_etherbone = serwb.etherbone.Etherbone(mode="slave") + self.submodules += serwb_etherbone + serwb_tx_cdc = ClockDomainsRenamer({"write": "sys", "read": "serdes"})( + stream.AsyncFIFO([("data", 32)], 8)) + self.submodules += serwb_tx_cdc + serwb_rx_cdc = ClockDomainsRenamer({"write": "serdes", "read": "sys"})( + stream.AsyncFIFO([("data", 32)], 8)) + self.submodules += serwb_rx_cdc + self.comb += [ + # core <--> etherbone + serwb_depacketizer.source.connect(serwb_etherbone.sink), + serwb_etherbone.source.connect(serwb_packetizer.sink), + + # core --> serdes + serwb_packetizer.source.connect(serwb_tx_cdc.sink), + If(serwb_tx_cdc.source.stb & serwb_init.ready, + serwb_serdes.tx_data.eq(serwb_tx_cdc.source.data) + ), + serwb_tx_cdc.source.ack.eq(serwb_init.ready), + + # serdes --> core + serwb_rx_cdc.sink.stb.eq(serwb_init.ready), + serwb_rx_cdc.sink.data.eq(serwb_serdes.rx_data), + serwb_rx_cdc.source.connect(serwb_depacketizer.sink), + ] + self.add_wb_slave(self.mem_map["serwb"], 8192, serwb_etherbone.wishbone.bus) + # RTIO rtio_channels = [] for i in (2, 3): diff --git a/artiq/gateware/targets/sayma_rtm.py b/artiq/gateware/targets/sayma_rtm.py index e8482d6a7..56ac0ac1e 100755 --- a/artiq/gateware/targets/sayma_rtm.py +++ b/artiq/gateware/targets/sayma_rtm.py @@ -67,6 +67,7 @@ class SaymaRTM(Module): # maybe keep only 3 user-visible modules: serwb PLL, serwb PHY, and serwb core # TODO: after this is done, stop exposing internal modules in serwb/__init__.py # TODO: avoid having a "serdes" clock domain at the top level, rename to "serwb_serdes" or similar. + # TODO: the above also applies to sayma_amc_standalone.py. # serwb SERDES serwb_pll = serwb.s7phy.S7SerdesPLL(125e6, 1.25e9, vco_div=1)