examples/kc705_nist_clock: port to NAC3

This commit is contained in:
Sebastien Bourdeauducq 2022-04-27 18:41:59 +08:00
parent 3160378614
commit 50767c0365
11 changed files with 175 additions and 69 deletions

View File

@ -1,21 +1,26 @@
from artiq.experiment import *
from artiq.coredevice.core import Core
from artiq.coredevice.ttl import TTLOut
@nac3
class IdleKernel(EnvExperiment):
core: KernelInvariant[Core]
led: KernelInvariant[TTLOut]
def build(self):
self.setattr_device("core")
self.setattr_device("led")
@kernel
def run(self):
start_time = now_mu() + self.core.seconds_to_mu(500*ms)
start_time = now_mu() + self.core.seconds_to_mu(500.*ms)
while self.core.get_rtio_counter_mu() < start_time:
pass
self.core.reset()
while True:
self.led.pulse(250*ms)
delay(125*ms)
self.led.pulse(125*ms)
delay(125*ms)
self.led.pulse(125*ms)
delay(250*ms)
self.led.pulse(250.*ms)
self.core.delay(125.*ms)
self.led.pulse(125.*ms)
self.core.delay(125.*ms)
self.led.pulse(125.*ms)
self.core.delay(250.*ms)

View File

@ -1,20 +1,30 @@
from time import sleep
from artiq.experiment import *
from artiq.coredevice.core import Core
# NAC3TODO https://git.m-labs.hk/M-Labs/nac3/issues/282
@rpc
def sleep_rpc():
sleep(1)
@nac3
class CorePause(EnvExperiment):
core: KernelInvariant[Core]
def build(self):
self.setattr_device("core")
self.setattr_device("scheduler")
@kernel
def k(self):
print("kernel starting")
print_rpc("kernel starting")
while not self.scheduler.check_pause():
print("main kernel loop running...")
sleep(1)
print("kernel exiting")
print_rpc("main kernel loop running...")
sleep_rpc()
print_rpc("kernel exiting")
def run(self):
while True:

View File

@ -1,10 +1,16 @@
from operator import itemgetter
from artiq.experiment import *
from artiq.coredevice.core import Core
from artiq.coredevice.ad9914 import AD9914
@nac3
class DDSSetter(EnvExperiment):
"""DDS Setter"""
core: KernelInvariant[Core]
def build(self):
self.setattr_device("core")
@ -24,10 +30,10 @@ class DDSSetter(EnvExperiment):
}
@kernel
def set_dds(self, dds, frequency):
def set_dds(self, dds: AD9914, frequency: float):
self.core.break_realtime()
dds.set(frequency)
delay(200*ms)
self.core.delay(200.*ms)
def run(self):
for k, v in self.dds.items():

View File

@ -1,9 +1,22 @@
from artiq.experiment import *
from artiq.coredevice.core import Core
from artiq.coredevice.ad9914 import AD9914
from artiq.coredevice.ttl import TTLOut
@nac3
class DDSTest(EnvExperiment):
"""DDS test"""
core: KernelInvariant[Core]
dds0: KernelInvariant[AD9914]
dds1: KernelInvariant[AD9914]
dds2: KernelInvariant[AD9914]
ttl0: KernelInvariant[TTLOut]
ttl1: KernelInvariant[TTLOut]
ttl2: KernelInvariant[TTLOut]
led: KernelInvariant[TTLOut]
def build(self):
self.setattr_device("core")
self.dds0 = self.get_device("ad9914dds0")
@ -17,21 +30,21 @@ class DDSTest(EnvExperiment):
@kernel
def run(self):
self.core.reset()
delay(200*us)
self.dds1.set(120*MHz)
delay(10*us)
self.dds2.set(200*MHz)
delay(1*us)
self.core.delay(200.*us)
self.dds1.set(120.*MHz)
self.core.delay(10.*us)
self.dds2.set(200.*MHz)
self.core.delay(1.*us)
for i in range(10000):
if i & 0x200:
if bool(i & 0x200):
self.led.on()
else:
self.led.off()
with parallel:
with sequential:
self.dds0.set(100*MHz + 4*i*kHz)
self.ttl0.pulse(500*us)
self.ttl1.pulse(500*us)
self.ttl2.pulse(100*us)
self.dds0.set(100.*MHz + 4.*float(i)*kHz)
self.ttl0.pulse(500.*us)
self.ttl1.pulse(500.*us)
self.ttl2.pulse(100.*us)
self.led.off()

View File

@ -1,6 +1,8 @@
from artiq.experiment import *
# NAC3TODO https://git.m-labs.hk/M-Labs/nac3/issues/75
class DMABlink(EnvExperiment):
def build(self):
self.setattr_device("core")

View File

@ -1,15 +1,21 @@
from artiq.experiment import *
from artiq.coredevice.core import Core
from artiq.coredevice.ttl import TTLOut
@nac3
class Handover(EnvExperiment):
core: KernelInvariant[Core]
led: KernelInvariant[TTLOut]
def build(self):
self.setattr_device("core")
self.setattr_device("led")
@kernel
def blink_once(self):
delay(250*ms)
self.led.pulse(250*ms)
self.core.delay(250.*ms)
self.led.pulse(250.*ms)
def run(self):
self.core.reset()

View File

@ -1,17 +1,25 @@
import sys
from numpy import int32
from artiq.experiment import *
from artiq.coredevice.core import Core
@nac3
class Mandelbrot(EnvExperiment):
"""Mandelbrot set demo"""
core: KernelInvariant[Core]
def build(self):
self.setattr_device("core")
def col(self, i):
@rpc
def col(self, i: int32):
sys.stdout.write(" .,-:;i+hHM$*#@ "[i])
@rpc
def row(self):
print("")
@ -22,22 +30,22 @@ class Mandelbrot(EnvExperiment):
maxX = 1.0
width = 78
height = 36
aspectRatio = 2
aspectRatio = 2.0
yScale = (maxX-minX)*(height/width)*aspectRatio
yScale = (maxX-minX)*(float(height)/float(width))*aspectRatio
for y in range(height):
for x in range(width):
c_r = minX+x*(maxX-minX)/width
c_i = y*yScale/height-yScale/2
c_r = minX+float(x)*(maxX-minX)/float(width)
c_i = float(y)*yScale/float(height)-yScale/2.0
z_r = c_r
z_i = c_i
i = 0
for i in range(16):
if z_r*z_r + z_i*z_i > 4:
if z_r*z_r + z_i*z_i > 4.0:
break
new_z_r = (z_r*z_r)-(z_i*z_i) + c_r
z_i = 2*z_r*z_i + c_i
z_i = 2.0*z_r*z_i + c_i
z_r = new_z_r
self.col(i)
self.row()

View File

@ -1,9 +1,28 @@
from numpy import int32
from artiq.experiment import *
from artiq.coredevice.core import Core
from artiq.coredevice.ad9914 import AD9914
from artiq.coredevice.ttl import TTLOut, TTLInOut
@nac3
class PhotonHistogram(EnvExperiment):
"""Photon histogram"""
core: KernelInvariant[Core]
bd_dds: KernelInvariant[AD9914]
bd_sw: KernelInvariant[TTLOut]
bdd_dds: KernelInvariant[AD9914]
bdd_sw: KernelInvariant[TTLOut]
pmt: KernelInvariant[TTLInOut]
nbins: KernelInvariant[int32]
repeats: KernelInvariant[int32]
cool_f: KernelInvariant[float]
detect_f: KernelInvariant[float]
detect_t: KernelInvariant[float]
def build(self):
self.setattr_device("core")
self.setattr_device("bd_dds")
@ -22,20 +41,21 @@ class PhotonHistogram(EnvExperiment):
@kernel
def program_cooling(self):
delay_mu(-self.bd_dds.set_duration_mu)
self.bd_dds.set(200*MHz)
self.bd_dds.set(200.*MHz)
delay_mu(self.bd_dds.set_duration_mu)
self.bdd_dds.set(300*MHz)
self.bdd_dds.set(300.*MHz)
@kernel
def cool_detect(self):
def cool_detect(self) -> int32:
with parallel:
self.bd_sw.pulse(1*ms)
self.bdd_sw.pulse(1*ms)
self.bd_sw.pulse(1.*ms)
self.bdd_sw.pulse(1.*ms)
self.bd_dds.set(self.cool_f)
self.bd_sw.pulse(100*us)
self.bd_sw.pulse(100.*us)
self.bd_dds.set(self.detect_f)
gate_end_mu = int64(0)
with parallel:
self.bd_sw.pulse(self.detect_t)
gate_end_mu = self.pmt.gate_rising(self.detect_t)
@ -46,6 +66,11 @@ class PhotonHistogram(EnvExperiment):
return self.pmt.count(gate_end_mu)
@rpc
def report(self, hist: list[int32], ion_present: bool):
self.set_dataset("cooling_photon_histogram", hist)
self.set_dataset("ion_present", ion_present, broadcast=True)
@kernel
def run(self):
self.core.reset()
@ -55,18 +80,11 @@ class PhotonHistogram(EnvExperiment):
total = 0
for i in range(self.repeats):
delay(0.5*ms)
self.core.delay(0.5*ms)
n = self.cool_detect()
if n >= self.nbins:
n = self.nbins - 1
hist[n] += 1
total += n
self.set_dataset("cooling_photon_histogram", hist)
self.set_dataset("ion_present", total > 5*self.repeats,
broadcast=True)
if __name__ == "__main__":
from artiq.frontend.artiq_run import run
run()
self.report(hist, total > 5*self.repeats)

View File

@ -1,6 +1,8 @@
from artiq.experiment import *
# NAC3TODO
class Precompile(EnvExperiment):
def build(self):
self.setattr_device("core")

View File

@ -1,6 +1,9 @@
import time
from numpy import int32
from artiq.experiment import *
from artiq.coredevice.core import Core
class _PayloadNOP(EnvExperiment):
@ -11,7 +14,10 @@ class _PayloadNOP(EnvExperiment):
pass
@nac3
class _PayloadCoreNOP(EnvExperiment):
core: KernelInvariant[Core]
def build(self):
self.setattr_device("core")
@ -20,11 +26,15 @@ class _PayloadCoreNOP(EnvExperiment):
pass
@nac3
class _PayloadCoreSend100Ints(EnvExperiment):
core: KernelInvariant[Core]
def build(self):
self.setattr_device("core")
def devnull(self, d):
@rpc
def devnull(self, d: int32):
pass
@kernel
@ -33,11 +43,15 @@ class _PayloadCoreSend100Ints(EnvExperiment):
self.devnull(42)
@nac3
class _PayloadCoreSend1MB(EnvExperiment):
core: KernelInvariant[Core]
def build(self):
self.setattr_device("core")
def devnull(self, d):
@rpc
def devnull(self, d: list[int32]):
pass
@kernel
@ -46,11 +60,15 @@ class _PayloadCoreSend1MB(EnvExperiment):
self.devnull(data)
@nac3
class _PayloadCorePrimes(EnvExperiment):
core: KernelInvariant[Core]
def build(self):
self.setattr_device("core")
def devnull(self, d):
@rpc
def devnull(self, d: int32):
pass
@kernel
@ -104,9 +122,14 @@ class SpeedBenchmark(EnvExperiment):
def run_without_scheduler(self, pause):
payload = globals()["_Payload" + self.payload](self)
start_time = time.monotonic()
for i in range(int(self.nruns)):
try:
payload.run()
except:
import traceback
print(traceback.format_exc())
if pause:
self.core.comm.close()
self.scheduler.pause()

View File

@ -1,24 +1,30 @@
# Copyright (C) 2014, 2015 Robert Jordens <jordens@gmail.com>
from numpy import int32, int64
from artiq.experiment import *
from artiq.coredevice.core import Core
from artiq.coredevice.ttl import TTLOut, TTLInOut
@nac3
class PulseNotReceivedError(Exception):
pass
@nac3
class TDR(EnvExperiment):
"""Time domain reflectometer.
From ttl2 an impedance matched pulse is send onto a coax
cable with an open end. pmt0 (very short stub, high impedance) also
listens on the transmission line near ttl2.
From ttl0 an impedance matched pulse is send onto a coax
cable with an open end. ttl3 (very short stub, high impedance) also
listens on the transmission line near ttl0.
When the forward propagating pulse passes pmt0, the voltage is half of the
When the forward propagating pulse passes ttl3, the voltage is half of the
logic voltage and does not register as a rising edge. Once the
rising edge is reflected at an open end (same sign) and passes by pmt0 on
its way back to ttl2, it is detected. Analogously, hysteresis leads to
detection of the falling edge once the reflection reaches pmt0 after
rising edge is reflected at an open end (same sign) and passes by ttl3 on
its way back to ttl0, it is detected. Analogously, hysteresis leads to
detection of the falling edge once the reflection reaches ttl3 after
one round trip time.
This works marginally and is just a proof of principle: it relies on
@ -30,10 +36,17 @@ class TDR(EnvExperiment):
This is also equivalent to a loopback tester or a delay measurement.
"""
core: KernelInvariant[Core]
ttl3: KernelInvariant[TTLInOut]
ttl0: KernelInvariant[TTLOut]
t: Kernel[list[int32]]
def build(self):
self.setattr_device("core")
self.setattr_device("pmt0")
self.setattr_device("ttl2")
self.setattr_device("ttl3")
self.setattr_device("ttl0")
def run(self):
self.core.reset()
@ -54,20 +67,20 @@ class TDR(EnvExperiment):
t_rise/1e-9, t_fall/1e-9))
@kernel
def many(self, n, p):
def many(self, n: int32, p: int64):
self.core.break_realtime()
for i in range(n):
self.one(p)
@kernel
def one(self, p):
def one(self, p: int64):
t0 = now_mu()
with parallel:
self.pmt0.gate_both_mu(2*p)
self.ttl2.pulse_mu(p)
self.ttl3.gate_both_mu(int64(2)*p)
self.ttl0.pulse_mu(p)
for i in range(len(self.t)):
ti = self.pmt0.timestamp_mu(now_mu())
if ti <= 0:
ti = self.ttl3.timestamp_mu(now_mu())
if ti <= int64(0):
raise PulseNotReceivedError()
self.t[i] = int(self.t[i] + ti - t0)
self.pmt0.count(now_mu()) # flush
self.t[i] = int32(int64(self.t[i]) + ti - t0)
self.ttl3.count(now_mu()) # flush