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.experiment import *
from artiq.coredevice.core import Core
from artiq.coredevice.ttl import TTLOut
@nac3
class IdleKernel(EnvExperiment): class IdleKernel(EnvExperiment):
core: KernelInvariant[Core]
led: KernelInvariant[TTLOut]
def build(self): def build(self):
self.setattr_device("core") self.setattr_device("core")
self.setattr_device("led") self.setattr_device("led")
@kernel @kernel
def run(self): 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: while self.core.get_rtio_counter_mu() < start_time:
pass pass
self.core.reset() self.core.reset()
while True: while True:
self.led.pulse(250*ms) self.led.pulse(250.*ms)
delay(125*ms) self.core.delay(125.*ms)
self.led.pulse(125*ms) self.led.pulse(125.*ms)
delay(125*ms) self.core.delay(125.*ms)
self.led.pulse(125*ms) self.led.pulse(125.*ms)
delay(250*ms) self.core.delay(250.*ms)

View File

@ -1,20 +1,30 @@
from time import sleep from time import sleep
from artiq.experiment import * 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): class CorePause(EnvExperiment):
core: KernelInvariant[Core]
def build(self): def build(self):
self.setattr_device("core") self.setattr_device("core")
self.setattr_device("scheduler") self.setattr_device("scheduler")
@kernel @kernel
def k(self): def k(self):
print("kernel starting") print_rpc("kernel starting")
while not self.scheduler.check_pause(): while not self.scheduler.check_pause():
print("main kernel loop running...") print_rpc("main kernel loop running...")
sleep(1) sleep_rpc()
print("kernel exiting") print_rpc("kernel exiting")
def run(self): def run(self):
while True: while True:

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -1,9 +1,28 @@
from numpy import int32
from artiq.experiment import * 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): class PhotonHistogram(EnvExperiment):
"""Photon histogram""" """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): def build(self):
self.setattr_device("core") self.setattr_device("core")
self.setattr_device("bd_dds") self.setattr_device("bd_dds")
@ -22,20 +41,21 @@ class PhotonHistogram(EnvExperiment):
@kernel @kernel
def program_cooling(self): def program_cooling(self):
delay_mu(-self.bd_dds.set_duration_mu) 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) delay_mu(self.bd_dds.set_duration_mu)
self.bdd_dds.set(300*MHz) self.bdd_dds.set(300.*MHz)
@kernel @kernel
def cool_detect(self): def cool_detect(self) -> int32:
with parallel: with parallel:
self.bd_sw.pulse(1*ms) self.bd_sw.pulse(1.*ms)
self.bdd_sw.pulse(1*ms) self.bdd_sw.pulse(1.*ms)
self.bd_dds.set(self.cool_f) 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) self.bd_dds.set(self.detect_f)
gate_end_mu = int64(0)
with parallel: with parallel:
self.bd_sw.pulse(self.detect_t) self.bd_sw.pulse(self.detect_t)
gate_end_mu = self.pmt.gate_rising(self.detect_t) gate_end_mu = self.pmt.gate_rising(self.detect_t)
@ -45,6 +65,11 @@ class PhotonHistogram(EnvExperiment):
self.bdd_sw.on() self.bdd_sw.on()
return self.pmt.count(gate_end_mu) 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 @kernel
def run(self): def run(self):
@ -55,18 +80,11 @@ class PhotonHistogram(EnvExperiment):
total = 0 total = 0
for i in range(self.repeats): for i in range(self.repeats):
delay(0.5*ms) self.core.delay(0.5*ms)
n = self.cool_detect() n = self.cool_detect()
if n >= self.nbins: if n >= self.nbins:
n = self.nbins - 1 n = self.nbins - 1
hist[n] += 1 hist[n] += 1
total += n total += n
self.set_dataset("cooling_photon_histogram", hist) self.report(hist, total > 5*self.repeats)
self.set_dataset("ion_present", total > 5*self.repeats,
broadcast=True)
if __name__ == "__main__":
from artiq.frontend.artiq_run import run
run()

View File

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

View File

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

View File

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