mirror of https://github.com/m-labs/artiq.git
pdq2: wire up more of the pipeline
This commit is contained in:
parent
e42fd9ca31
commit
f0860beffd
|
@ -193,6 +193,8 @@ class Pdq2:
|
||||||
|
|
||||||
def program_frame(self, frame_data):
|
def program_frame(self, frame_data):
|
||||||
segments = [c.new_segment() for c in self.channels]
|
segments = [c.new_segment() for c in self.channels]
|
||||||
|
for segment in segments:
|
||||||
|
segment.line(typ=3, data=b"", trigger=True, duration=10, aux=1)
|
||||||
for i, line in enumerate(frame_data): # segments are concatenated
|
for i, line in enumerate(frame_data): # segments are concatenated
|
||||||
dac_divider = line.get("dac_divider", 1)
|
dac_divider = line.get("dac_divider", 1)
|
||||||
shift = int(log(dac_divider, 2))
|
shift = int(log(dac_divider, 2))
|
||||||
|
@ -209,9 +211,11 @@ class Pdq2:
|
||||||
shift=shift, duration=duration, trigger=trigger,
|
shift=shift, duration=duration, trigger=trigger,
|
||||||
**target_data)
|
**target_data)
|
||||||
# append an empty line to stall the memory reader before jumping
|
# append an empty line to stall the memory reader before jumping
|
||||||
# through the frame table
|
# through the frame table (`wait` does not prevent reading
|
||||||
|
# the next line)
|
||||||
for segment in segments:
|
for segment in segments:
|
||||||
segment.line(typ=3, data=b"", trigger=True, duration=10)
|
segment.line(typ=3, data=b"", trigger=True, duration=1,
|
||||||
|
jump=True, aux=1)
|
||||||
return segments
|
return segments
|
||||||
|
|
||||||
def program(self, program):
|
def program(self, program):
|
||||||
|
|
|
@ -111,6 +111,7 @@ class _Frame:
|
||||||
"dac_divider": dac_divider,
|
"dac_divider": dac_divider,
|
||||||
"duration": duration,
|
"duration": duration,
|
||||||
"channel_data": channel_data,
|
"channel_data": channel_data,
|
||||||
|
"trigger": False,
|
||||||
} for dac_divider, duration, channel_data in segment.lines]
|
} for dac_divider, duration, channel_data in segment.lines]
|
||||||
segment_program[0]["trigger"] = True
|
segment_program[0]["trigger"] = True
|
||||||
r += segment_program
|
r += segment_program
|
||||||
|
@ -156,7 +157,7 @@ class _Frame:
|
||||||
class CompoundPDQ2:
|
class CompoundPDQ2:
|
||||||
def __init__(self, dmgr, pdq2_devices, trigger_device, frame_devices):
|
def __init__(self, dmgr, pdq2_devices, trigger_device, frame_devices):
|
||||||
self.core = dmgr.get("core")
|
self.core = dmgr.get("core")
|
||||||
self.pdq2s = [dmgr.get(d) for d in self.pdq2_devices]
|
self.pdq2s = [dmgr.get(d) for d in pdq2_devices]
|
||||||
self.trigger = dmgr.get(trigger_device)
|
self.trigger = dmgr.get(trigger_device)
|
||||||
self.frame0 = dmgr.get(frame_devices[0])
|
self.frame0 = dmgr.get(frame_devices[0])
|
||||||
self.frame1 = dmgr.get(frame_devices[1])
|
self.frame1 = dmgr.get(frame_devices[1])
|
||||||
|
|
|
@ -143,14 +143,12 @@ class CoefficientSource:
|
||||||
return build_segment(durations, coefficients, target=target,
|
return build_segment(durations, coefficients, target=target,
|
||||||
variable=variable)
|
variable=variable)
|
||||||
|
|
||||||
def extend_segment(self, segment, trigger=True, *args, **kwargs):
|
def extend_segment(self, segment, *args, **kwargs):
|
||||||
"""Extend a wavesynth segment.
|
"""Extend a wavesynth segment.
|
||||||
|
|
||||||
See `get_segment()` for arguments.
|
See `get_segment()` for arguments.
|
||||||
"""
|
"""
|
||||||
for i, line in enumerate(self.get_segment_data(*args, **kwargs)):
|
for i, line in enumerate(self.get_segment_data(*args, **kwargs)):
|
||||||
if i == 0:
|
|
||||||
line["trigger"] = trigger
|
|
||||||
segment.add_line(**line)
|
segment.add_line(**line)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -4,11 +4,11 @@ import numpy as np
|
||||||
|
|
||||||
from artiq import *
|
from artiq import *
|
||||||
|
|
||||||
|
from artiq.wavesynth.coefficients import SplineSource
|
||||||
|
|
||||||
# data is usually precomputed offline
|
transport = SplineSource(
|
||||||
transport_data = dict(
|
x=np.linspace(0, 10, 101), # waveform time
|
||||||
t=np.linspace(0, 10, 101), # waveform time
|
y=np.random.rand(4*3*3, 101)*1e-6, # waveform data,
|
||||||
u=np.random.randn(101, 4*3*3), # waveform data,
|
|
||||||
# 4 devices, 3 board each, 3 dacs each
|
# 4 devices, 3 board each, 3 dacs each
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -16,37 +16,33 @@ class Transport(EnvExperiment):
|
||||||
"""Transport"""
|
"""Transport"""
|
||||||
|
|
||||||
def build(self):
|
def build(self):
|
||||||
self.setattr_device("core")
|
self.core = self.get_device("core")
|
||||||
self.setattr_device("bd")
|
self.bd_sw = self.get_device("bd_sw")
|
||||||
self.setattr_device("bdd")
|
self.pmt = self.get_device("pmt")
|
||||||
self.setattr_device("pmt")
|
self.electrodes = self.get_device("electrodes")
|
||||||
self.setattr_device("electrodes")
|
|
||||||
|
|
||||||
self.setattr_argument("wait_at_stop", NumberValue(100*us))
|
self.wait_at_stop = self.get_argument("wait_at_stop",
|
||||||
self.setattr_argument("speed", NumberValue(1.5))
|
NumberValue(100*us))
|
||||||
self.setattr_argument("repeats", NumberValue(100))
|
self.speed = self.get_argument("speed", NumberValue(1.5))
|
||||||
self.setattr_argument("nbins", NumberValue(100))
|
self.repeats = self.get_argument("repeats", NumberValue(100))
|
||||||
|
self.nbins = self.get_argument("nbins", NumberValue(100))
|
||||||
|
|
||||||
def calc_waveforms(self, stop):
|
def calc_waveforms(self, stop):
|
||||||
t = transport_data["t"][:stop]*self.speed
|
|
||||||
u = transport_data["u"][:stop]
|
|
||||||
|
|
||||||
self.electrodes.disarm()
|
self.electrodes.disarm()
|
||||||
self.tf = self.electrodes.create_frame()
|
self.tf = self.electrodes.create_frame()
|
||||||
self.tf.create_segment(t, u, name="to_stop")
|
to_stop = self.tf.create_segment("to_stop")
|
||||||
|
from_stop = self.tf.create_segment("from_stop")
|
||||||
|
transport.extend_segment(to_stop, 0, stop, scale=self.speed)
|
||||||
# append the reverse transport (from stop to 0)
|
# append the reverse transport (from stop to 0)
|
||||||
# both durations are the same in this case
|
# both durations are the same in this case
|
||||||
self.tf.create_segment(t[-1] - t[::-1], u[::-1], name="from_stop")
|
transport.extend_segment(from_stop, 0, stop, scale=self.speed)
|
||||||
# distributes frames to the sub-devices in CompoundPDQ2
|
# distributes frames to the sub-devices in CompoundPDQ2
|
||||||
# and uploads them
|
# and uploads them
|
||||||
self.electrodes.arm()
|
self.electrodes.arm()
|
||||||
|
|
||||||
@kernel
|
@kernel
|
||||||
def cool(self):
|
def cool(self):
|
||||||
with parallel:
|
self.bd_sw.pulse(1*ms)
|
||||||
self.bd.pulse(200*MHz, 1*ms)
|
|
||||||
self.bdd.pulse(300*MHz, 1*ms)
|
|
||||||
self.bd.pulse(210*MHz, 100*us)
|
|
||||||
|
|
||||||
@kernel
|
@kernel
|
||||||
def transport(self):
|
def transport(self):
|
||||||
|
@ -65,10 +61,9 @@ class Transport(EnvExperiment):
|
||||||
@kernel
|
@kernel
|
||||||
def detect(self):
|
def detect(self):
|
||||||
with parallel:
|
with parallel:
|
||||||
self.bd.pulse(220*MHz, 100*us)
|
self.bd_sw.pulse(100*us)
|
||||||
self.pmt.gate_rising(100*us)
|
self.pmt.gate_rising(100*us)
|
||||||
self.bd.on(200*MHz)
|
self.bd_sw.on()
|
||||||
self.bdd.on(300*MHz)
|
|
||||||
return self.pmt.count()
|
return self.pmt.count()
|
||||||
|
|
||||||
@kernel
|
@kernel
|
||||||
|
@ -79,7 +74,7 @@ class Transport(EnvExperiment):
|
||||||
|
|
||||||
@kernel
|
@kernel
|
||||||
def repeat(self):
|
def repeat(self):
|
||||||
self.histogram = [0 for _ in range(self.nbins)]
|
self.histogram[:] = [0 for _ in range(self.nbins)]
|
||||||
|
|
||||||
for i in range(self.repeats):
|
for i in range(self.repeats):
|
||||||
n = self.one()
|
n = self.one()
|
||||||
|
@ -100,5 +95,5 @@ class Transport(EnvExperiment):
|
||||||
|
|
||||||
def run(self):
|
def run(self):
|
||||||
# scan transport endpoint
|
# scan transport endpoint
|
||||||
stops = range(10, len(transport_data["t"]), 10)
|
stops = range(10, len(transport.x), 10)
|
||||||
self.scan(stops)
|
self.scan(stops)
|
||||||
|
|
Loading…
Reference in New Issue