diff --git a/artiq/examples/kasli_suservo/device_db.py b/artiq/examples/kasli_suservo/device_db.py index 2da2df0cf..d33bfb280 100644 --- a/artiq/examples/kasli_suservo/device_db.py +++ b/artiq/examples/kasli_suservo/device_db.py @@ -1,4 +1,4 @@ -core_addr = "10.0.16.119" +core_addr = "10.0.16.121" device_db = { "core": { @@ -135,20 +135,6 @@ device_db = { "arguments": {"channel": 15}, }, - "suservo0": { - "type": "local", - "module": "artiq.coredevice.suservo", - "class": "SUServo", - "arguments": { - "channel": 24, - "pgia_device": "spi_sampler0_pgia", - "cpld0_device": "urukul0_cpld", - "cpld1_device": "urukul1_cpld", - "dds0_device": "urukul0_dds", - "dds1_device": "urukul1_dds" - } - }, - "suservo0_ch0": { "type": "local", "module": "artiq.coredevice.suservo", @@ -198,6 +184,20 @@ device_db = { "arguments": {"channel": 23, "servo_device": "suservo0"} }, + "suservo0": { + "type": "local", + "module": "artiq.coredevice.suservo", + "class": "SUServo", + "arguments": { + "channel": 24, + "pgia_device": "spi_sampler0_pgia", + "cpld0_device": "urukul0_cpld", + "cpld1_device": "urukul1_cpld", + "dds0_device": "urukul0_dds", + "dds1_device": "urukul1_dds" + } + }, + "spi_sampler0_pgia": { "type": "local", "module": "artiq.coredevice.spi2", diff --git a/artiq/gateware/eem.py b/artiq/gateware/eem.py index 007430338..31879f324 100644 --- a/artiq/gateware/eem.py +++ b/artiq/gateware/eem.py @@ -4,6 +4,8 @@ from migen.genlib.io import DifferentialOutput from artiq.gateware import rtio from artiq.gateware.rtio.phy import spi2, grabber +from artiq.gateware.suservo import servo, pads as servo_pads +from artiq.gateware.rtio.phy import servo as rtservo def _eem_signal(i): @@ -429,3 +431,79 @@ class Grabber(_EEM): phy = ttl_out_cls(pads.p, pads.n) target.submodules += phy target.rtio_channels.append(rtio.Channel.from_phy(phy)) + + +class SUServo(_EEM): + @staticmethod + def io(*eems): + assert len(eems) == 6 + return (Sampler.io(*eems[0:2]) + + Urukul.io_qspi(*eems[2:4]) + + Urukul.io_qspi(*eems[4:6])) + + @classmethod + def add_std(cls, target, eems_sampler, eems_urukul0, eems_urukul1, + t_rtt=4, clk=1, shift=11, profile=5): + cls.add_extension( + target, *(eems_sampler + eems_urukul0 + eems_urukul1)) + eem_sampler = "sampler{}".format(eems_sampler[0]) + eem_urukul0 = "urukul{}".format(eems_urukul0[0]) + eem_urukul1 = "urukul{}".format(eems_urukul1[0]) + + sampler_pads = servo_pads.SamplerPads(target.platform, eem_sampler) + urukul_pads = servo_pads.UrukulPads( + target.platform, eem_urukul0, eem_urukul1) + # timings in units of RTIO coarse period + adc_p = servo.ADCParams(width=16, channels=8, lanes=4, t_cnvh=4, + # account for SCK pipeline latency + t_conv=57 - 4, t_rtt=t_rtt + 4) + iir_p = servo.IIRWidths(state=25, coeff=18, adc=16, asf=14, word=16, + accu=48, shift=shift, channel=3, + profile=profile) + dds_p = servo.DDSParams(width=8 + 32 + 16 + 16, + channels=adc_p.channels, clk=clk) + su = servo.Servo(sampler_pads, urukul_pads, adc_p, iir_p, dds_p) + su = ClockDomainsRenamer("rio_phy")(su) + target.submodules += sampler_pads, urukul_pads, su + + ctrls = [rtservo.RTServoCtrl(ctrl) for ctrl in su.iir.ctrl] + target.submodules += ctrls + target.rtio_channels.extend( + rtio.Channel.from_phy(ctrl) for ctrl in ctrls) + mem = rtservo.RTServoMem(iir_p, su) + target.submodules += mem + target.rtio_channels.append(rtio.Channel.from_phy(mem, ififo_depth=4)) + + phy = spi2.SPIMaster( + target.platform.request("{}_pgia_spi_p".format(eem_sampler)), + target.platform.request("{}_pgia_spi_n".format(eem_sampler))) + target.submodules += phy + target.rtio_channels.append(rtio.Channel.from_phy(phy, ififo_depth=4)) + + phy = spi2.SPIMaster( + target.platform.request("{}_spi_p".format(eem_urukul0)), + target.platform.request("{}_spi_n".format(eem_urukul0))) + target.submodules += phy + target.rtio_channels.append(rtio.Channel.from_phy(phy, ififo_depth=4)) + + pads = target.platform.request("{}_dds_reset".format(eem_urukul0)) + target.specials += DifferentialOutput(0, pads.p, pads.n) + + for i, signal in enumerate("sw0 sw1 sw2 sw3".split()): + pads = target.platform.request("{}_{}".format(eem_urukul0, signal)) + target.specials += DifferentialOutput( + su.iir.ctrl[i].en_out, pads.p, pads.n) + + phy = spi2.SPIMaster( + target.platform.request("{}_spi_p".format(eem_urukul1)), + target.platform.request("{}_spi_n".format(eem_urukul1))) + target.submodules += phy + target.rtio_channels.append(rtio.Channel.from_phy(phy, ififo_depth=4)) + + pads = target.platform.request("{}_dds_reset".format(eem_urukul1)) + target.specials += DifferentialOutput(0, pads.p, pads.n) + + for i, signal in enumerate("sw0 sw1 sw2 sw3".split()): + pads = target.platform.request("{}_{}".format(eem_urukul1, signal)) + target.specials += DifferentialOutput( + su.iir.ctrl[i + 4].en_out, pads.p, pads.n) diff --git a/artiq/gateware/targets/kasli.py b/artiq/gateware/targets/kasli.py index c340df435..858c8fb59 100755 --- a/artiq/gateware/targets/kasli.py +++ b/artiq/gateware/targets/kasli.py @@ -16,9 +16,7 @@ from misoc.integration.builder import builder_args, builder_argdict from artiq.gateware.amp import AMPSoC from artiq.gateware import rtio -from artiq.gateware.rtio.phy import ( - ttl_simple, ttl_serdes_7series, spi2, servo as rtservo) -from artiq.gateware.suservo import servo, pads as servo_pads +from artiq.gateware.rtio.phy import ttl_simple, ttl_serdes_7series from artiq.gateware import eem from artiq.gateware.drtio.transceiver import gtp_7series from artiq.gateware.drtio.siphaser import SiPhaser7Series @@ -211,67 +209,10 @@ class SUServo(_StandaloneBase): eem.DIO.add_std(self, 1, ttl_serdes_7series.Output_8X, ttl_serdes_7series.Output_8X) - # EEM3, EEM2: Sampler - self.platform.add_extension(eem.Sampler.io(3, 2)) - sampler_pads = servo_pads.SamplerPads(self.platform, "sampler3") - # EEM5, EEM4 and EEM7, EEM6: Urukul - self.platform.add_extension(eem.Urukul.io_qspi(5, 4)) - self.platform.add_extension(eem.Urukul.io_qspi(7, 6)) - urukul_pads = servo_pads.UrukulPads(self.platform, - "urukul5", "urukul7") - adc_p = servo.ADCParams(width=16, channels=8, lanes=4, t_cnvh=4, - # account for SCK pipeline latency - t_conv=57 - 4, t_rtt=4 + 4) - iir_p = servo.IIRWidths(state=25, coeff=18, adc=16, asf=14, word=16, - accu=48, shift=11, channel=3, profile=5) - dds_p = servo.DDSParams(width=8 + 32 + 16 + 16, - channels=adc_p.channels, clk=1) - su = servo.Servo(sampler_pads, urukul_pads, adc_p, iir_p, dds_p) - su = ClockDomainsRenamer("rio_phy")(su) - self.submodules += sampler_pads, urukul_pads, su - - ctrls = [rtservo.RTServoCtrl(ctrl) for ctrl in su.iir.ctrl] - self.submodules += ctrls - self.rtio_channels.extend(rtio.Channel.from_phy(ctrl) for ctrl in ctrls) - mem = rtservo.RTServoMem(iir_p, su) - self.submodules += mem - self.rtio_channels.append(rtio.Channel.from_phy(mem, ififo_depth=4)) - - # EEM3: Sampler - phy = spi2.SPIMaster(self.platform.request("sampler3_pgia_spi_p"), - self.platform.request("sampler3_pgia_spi_n")) - self.submodules += phy - self.rtio_channels.append(rtio.Channel.from_phy(phy, ififo_depth=4)) - - # EEM5 + EEM4: Urukul - phy = spi2.SPIMaster(self.platform.request("urukul5_spi_p"), - self.platform.request("urukul5_spi_n")) - self.submodules += phy - self.rtio_channels.append(rtio.Channel.from_phy(phy, ififo_depth=4)) - - pads = self.platform.request("urukul5_dds_reset") - self.specials += DifferentialOutput(0, pads.p, pads.n) - - for i, signal in enumerate("sw0 sw1 sw2 sw3".split()): - pads = self.platform.request("urukul5_{}".format(signal)) - self.specials += DifferentialOutput( - su.iir.ctrl[i].en_out, - pads.p, pads.n) - - # EEM7 + EEM6: Urukul - phy = spi2.SPIMaster(self.platform.request("urukul7_spi_p"), - self.platform.request("urukul7_spi_n")) - self.submodules += phy - self.rtio_channels.append(rtio.Channel.from_phy(phy, ififo_depth=4)) - - pads = self.platform.request("urukul7_dds_reset") - self.specials += DifferentialOutput(0, pads.p, pads.n) - - for i, signal in enumerate("sw0 sw1 sw2 sw3".split()): - pads = self.platform.request("urukul7_{}".format(signal)) - self.specials += DifferentialOutput( - su.iir.ctrl[i + 4].en_out, - pads.p, pads.n) + # EEM3/2: Sampler, EEM5/4: Urukul, EEM7/6: Urukul + eem.SUServo.add_std( + self, eems_sampler=(3, 2), + eems_urukul0=(5, 4), eems_urukul1=(7, 6)) for i in (1, 2): sfp_ctl = self.platform.request("sfp_ctl", i) @@ -285,12 +226,11 @@ class SUServo(_StandaloneBase): self.add_rtio(self.rtio_channels) + pads = self.platform.lookup_request("sampler3_adc_data_p") self.platform.add_false_path_constraints( - sampler_pads.clkout_p, - self.rtio_crg.cd_rtio.clk) + pads.clkout, self.rtio_crg.cd_rtio.clk) self.platform.add_false_path_constraints( - sampler_pads.clkout_p, - self.crg.cd_sys.clk) + pads.clkout, self.crg.cd_sys.clk) class SYSU(_StandaloneBase):