From a20087848d4e90080670cf1a46611ad1baa492f4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20J=C3=B6rdens?= Date: Fri, 2 Sep 2022 11:03:23 +0000 Subject: [PATCH] differentiate phaser modes --- artiq/coredevice/phaser.py | 65 ++++++++++++++++------------ artiq/frontend/artiq_ddb_template.py | 6 ++- artiq/gateware/eem.py | 6 +-- artiq/gateware/rtio/phy/phaser.py | 2 +- 4 files changed, 47 insertions(+), 32 deletions(-) diff --git a/artiq/coredevice/phaser.py b/artiq/coredevice/phaser.py index 9fad1d964..5c8f64668 100644 --- a/artiq/coredevice/phaser.py +++ b/artiq/coredevice/phaser.py @@ -190,7 +190,7 @@ class Phaser: def __init__(self, dmgr, channel_base, miso_delay=1, tune_fifo_offset=True, clk_sel=0, sync_dly=0, dac=None, trf0=None, trf1=None, - core_device="core"): + mode="base", core_device="core"): self.channel_base = channel_base self.core = dmgr.get(core_device) # TODO: auto-align miso-delay in phy @@ -230,6 +230,8 @@ class Phaser: if debug: print("gw_rev:", gw_rev) self.core.break_realtime() + is_base = gw_rev == 1 + is_miqro = gw_rev == 2 delay(.1*ms) # slack # allow a few errors during startup and alignment since boot @@ -350,32 +352,33 @@ class Phaser: channel.set_servo(profile=0, enable=0, hold=1) - # test oscillators and DUC - for i in range(len(channel.oscillator)): - oscillator = channel.oscillator[i] - asf = 0 - if i == 0: - asf = 0x7fff - # 6pi/4 phase - oscillator.set_amplitude_phase_mu(asf=asf, pow=0xc000, clr=1) + if is_base: + # test oscillators and DUC + for i in range(len(channel.oscillator)): + oscillator = channel.oscillator[i] + asf = 0 + if i == 0: + asf = 0x7fff + # 6pi/4 phase + oscillator.set_amplitude_phase_mu(asf=asf, pow=0xc000, clr=1) + delay(1*us) + # 3pi/4 + channel.set_duc_phase_mu(0x6000) + channel.set_duc_cfg(select=0, clr=1) + self.duc_stb() + delay(.1*ms) # settle link, pipeline and impulse response + data = channel.get_dac_data() delay(1*us) - # 3pi/4 - channel.set_duc_phase_mu(0x6000) - channel.set_duc_cfg(select=0, clr=1) - self.duc_stb() - delay(.1*ms) # settle link, pipeline and impulse response - data = channel.get_dac_data() - delay(1*us) - channel.oscillator[0].set_amplitude_phase_mu(asf=0, pow=0xc000, - clr=1) - delay(.1*ms) - sqrt2 = 0x5a81 # 0x7fff/sqrt(2) - data_i = data & 0xffff - data_q = (data >> 16) & 0xffff - # allow ripple - if (data_i < sqrt2 - 30 or data_i > sqrt2 or - abs(data_i - data_q) > 2): - raise ValueError("DUC+oscillator phase/amplitude test failed") + channel.oscillator[0].set_amplitude_phase_mu(asf=0, pow=0xc000, + clr=1) + delay(.1*ms) + sqrt2 = 0x5a81 # 0x7fff/sqrt(2) + data_i = data & 0xffff + data_q = (data >> 16) & 0xffff + # allow ripple + if (data_i < sqrt2 - 30 or data_i > sqrt2 or + abs(data_i - data_q) > 2): + raise ValueError("DUC+oscillator phase/amplitude test failed") if is_baseband: continue @@ -826,6 +829,7 @@ class PhaserChannel: self.trf_mmap = TRF372017(trf).get_mmap() self.oscillator = [PhaserOscillator(self, osc) for osc in range(5)] + self.miqro = Miqro(self) @kernel def get_dac_data(self) -> TInt32: @@ -1139,7 +1143,7 @@ class PhaserChannel: for data in [b0, b1, a1, offset]: self.phaser.write16(addr, data) addr += 2 - + @kernel def set_iir(self, profile, kp, ki=0., g=0., x_offset=0., y_offset=0.): """Set servo profile IIR coefficients. @@ -1269,3 +1273,10 @@ class PhaserOscillator: raise ValueError("amplitude out of bounds") pow = int32(round(phase*(1 << 16))) self.set_amplitude_phase_mu(asf, pow, clr) + + +class Miqro: + def __init__(self, channel): + self.channel = channel + self.base_addr = (self.channel.phaser.channel_base + 1 + + self.channel.index) << 8 diff --git a/artiq/frontend/artiq_ddb_template.py b/artiq/frontend/artiq_ddb_template.py index b6d9294a3..503f4862e 100755 --- a/artiq/frontend/artiq_ddb_template.py +++ b/artiq/frontend/artiq_ddb_template.py @@ -559,6 +559,7 @@ class PeripheralManager: return 1 def process_phaser(self, rtio_offset, peripheral): + mode = peripheral.get("mode", "base") self.gen(""" device_db["{name}"] = {{ "type": "local", @@ -567,11 +568,14 @@ class PeripheralManager: "arguments": {{ "channel_base": 0x{channel:06x}, "miso_delay": 1, + "mode": "{mode}" }} }}""", name=self.get_name("phaser"), + mode=mode, channel=rtio_offset) - return 5 + rtio_channels = {"base": 5, "miqro": 3}[mode] + return rtio_channels def process_hvamp(self, rtio_offset, peripheral): hvamp_name = self.get_name("hvamp") diff --git a/artiq/gateware/eem.py b/artiq/gateware/eem.py index eaa2f4fb2..3cc55e3f0 100644 --- a/artiq/gateware/eem.py +++ b/artiq/gateware/eem.py @@ -709,11 +709,11 @@ class Phaser(_EEM): ) for pol in "pn"] @classmethod - def add_std(cls, target, eem, mode, iostandard=default_iostandard): + def add_std(cls, target, eem, mode="base", iostandard=default_iostandard): cls.add_extension(target, eem, iostandard=iostandard) - if mode == "phaser": - phy = phaser.Phaser( + if mode == "base": + phy = phaser.Base( target.platform.request("phaser{}_ser_p".format(eem)), target.platform.request("phaser{}_ser_n".format(eem))) target.submodules += phy diff --git a/artiq/gateware/rtio/phy/phaser.py b/artiq/gateware/rtio/phy/phaser.py index 038f8b2c5..483e0945c 100644 --- a/artiq/gateware/rtio/phy/phaser.py +++ b/artiq/gateware/rtio/phy/phaser.py @@ -28,7 +28,7 @@ class DDSChannel(Module): [Cat(i.a, i.clr, i.p) for i in self.dds.i]) -class Phaser(Module): +class Base(Module): def __init__(self, pins, pins_n): self.rtlink = rtlink.Interface( rtlink.OInterface(data_width=8, address_width=8,