Skip to content

Instantly share code, notes, and snippets.

@dnadlinger
Created January 28, 2019 15:29
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dnadlinger/fb54dc976e18373ed34d4f2fc55f0ffe to your computer and use it in GitHub Desktop.
Save dnadlinger/fb54dc976e18373ed34d4f2fc55f0ffe to your computer and use it in GitHub Desktop.
from artiq.experiment import *
from artiq.coredevice.urukul import urukul_sta_smp_err, urukul_cfg
from artiq.coredevice.ad9910 import (_AD9910_REG_SYNC, _AD9910_REG_CFR1,
_AD9910_REG_CFR2)
import numpy as np
_MULTICHIP_SYNC_RECV = (1 << 27) + (1 << 26) # + (4<<28)
@portable
def multichip_sync_cfg(validation_delay, sync_recv_en, sync_gen_en, input_sync_delay):
return (validation_delay << 28) | (sync_recv_en << 27) | (sync_gen_en << 26) | (
input_sync_delay << 3)
class MultichipSyncScan(EnvExperiment):
def build(self):
self.setattr_device("core")
self.setattr_device("ccb")
self.name = self.get_argument(
"Device", EnumerationValue(["urukul0", "urukul1", "rurukul0", "rurukul1"]))
self.syncsel = self.get_argument("Sync source",
EnumerationValue(["DDS", "FPGA"]))
def prepare(self):
self.cpld = self.get_device(self.name + "_cpld")
for i in range(4):
setattr(self, "ch{}".format(i),
self.get_device(self.name + "_ch{}".format(i)))
self.dds_sync = self.get_device("ttlclk_" + self.name + "_sync")
def issue_applets(self):
self.ccb.issue(
"create_applet",
"Sync error",
"${python} -m oxart.applets.plot_xy_fit "
"data.dds.errors --x data.dds.ts --ylabel \"Sync errors\" "
"--grids",
group="dds")
@kernel
def set_sync_recv_delay(self, ch, t):
delay(10 * us)
r = ch.read32(0xa)
r &= (~0xff)
r |= ((t & 0x1f) << 3)
delay(20 * us)
ch.write32(0xa, r)
delay(1 * us)
self.cpld.io_update.pulse(10 * ns)
@kernel
def resync(self, chobj):
delay(20 * us)
r = chobj.read32(_AD9910_REG_CFR2)
delay(50 * us)
r |= np.int32(1 << 5) # disable validation
chobj.write32(_AD9910_REG_CFR2, r)
self.cpld.io_update.pulse(10 * ns)
r &= np.int32(~(1 << 5)) # reenable validation
delay(50 * us)
chobj.write32(_AD9910_REG_CFR2, r)
delay(10 * us)
self.cpld.io_update.pulse(10 * ns)
@kernel
def sync_status(self, ch):
delay(15 * us)
s = urukul_sta_smp_err(self.cpld.sta_read())
return 0 != s & (1 << ch)
def run(self):
self.issue_applets()
self.ts = []
self.errors = []
self.N = 1000
sync_sel = 0 if self.syncsel == "FPGA" else 1
self.cpld.cfg_reg = urukul_cfg(
rf_sw=0,
led=0,
profile=0,
io_update=0,
mask_nu=0,
clk_sel=0,
sync_sel=sync_sel,
rst=0,
io_rst=0)
self.krun()
@kernel
def krun(self):
self.core.reset()
delay(1 * ms)
tn = now_mu()
tn &= ~0xf
at_mu(tn)
self.dds_sync.set(125e6 / 2)
self.cpld.init()
self.ch0.init()
self.ch1.init()
self.ch2.init()
self.ch3.init()
self.ch0.set(100 * MHz, amplitude=0.)
self.ch0.sw.on()
self.ch0.set_att(0.)
# delay(10 *us)
self.ch1.set(100 * MHz, amplitude=0.)
self.ch1.sw.on()
self.ch1.set_att(0.)
# delay(10*us)
self.ch2.set(100 * MHz, amplitude=0.)
self.ch2.sw.on()
self.ch2.set_att(0.)
# delay(10*us)
self.ch3.set(100 * MHz, amplitude=0.)
self.ch3.sw.on()
self.ch3.set_att(0.)
# delay(10*us)
self.ch0.write32(_AD9910_REG_SYNC, multichip_sync_cfg(0, 1, 1, 0))
delay(1 * us)
self.ch1.write32(_AD9910_REG_SYNC, multichip_sync_cfg(0, 1, 0, 0))
delay(1 * us)
self.ch2.write32(_AD9910_REG_SYNC, multichip_sync_cfg(0, 1, 0, 0))
delay(1 * us)
self.ch3.write32(_AD9910_REG_SYNC, multichip_sync_cfg(0, 1, 0, 0))
delay(1 * us)
self.cpld.io_update.pulse(10 * ns)
for t in range(32):
self.core.break_realtime()
self.set_sync_recv_delay(self.ch0, t)
self.set_sync_recv_delay(self.ch1, t)
self.set_sync_recv_delay(self.ch2, t)
self.set_sync_recv_delay(self.ch3, t)
errs = [0] * 4
for i in range(self.N):
self.resync(self.ch0)
self.resync(self.ch1)
self.resync(self.ch2)
self.resync(self.ch3)
for ch in range(4):
if self.sync_status(ch):
errs[ch] += 1
self.report(t, errs)
def report(self, delay, ns):
print("{}\t{}".format(delay, ns))
self.ts.append(delay)
self.errors.append(ns[0])
self.set_dataset("data.dds.ts", self.ts, broadcast=True)
self.set_dataset("data.dds.errors", self.errors, broadcast=True)
class AutotuneDelays(EnvExperiment):
def build(self):
self.setattr_device("core")
self.setattr_device("ccb")
self.name = self.get_argument(
"Device", EnumerationValue(["urukul0", "urukul1", "rurukul0", "rurukul1"]))
def prepare(self):
self.cpld = self.get_device(self.name + "_cpld")
self.channels = [
self.get_device(self.name + "_ch{}".format(i)) for i in range(4)
]
@kernel
def run(self):
self.core.reset()
self.core.break_realtime()
self.cpld.init()
for i in range(len(self.channels)):
ch = self.channels[i]
print()
print("Channel", i)
print("---")
self.core.break_realtime()
print("msync (delay, window):", ch.tune_sync_delay(15))
self.core.break_realtime()
print("io_update_delay:", ch.tune_io_update_delay())
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment