Hardware loop frequency sweep ZCU216
Jalbanese02 opened this issue · 1 comments
I have been trying to implement a hardware level loop over varying frequencies in qick. However, I run into an issue when attempting to sweep over the frequency in the standard way by incrementing the 'freq' register. The following program demonstrates the problem I am facing:
from qick import *
from tqdm.notebook import tqdm
import matplotlib.pyplot as plt
import numpy as np
soc = QickSoc()
soccfg = soc
class SweepProgram(RAveragerProgram):
def initialize(self):
cfg=self.cfg
self.declare_gen(ch=cfg["res_ch"], nqz=1) # set the nyquist zone
self.r_rp=self.ch_page(self.cfg["res_ch"]) # get register page for res_ch
self.r_freq=self.sreg(cfg["res_ch"], "freq") #Get freq register for res_ch
self.step = self.freq2reg(self.cfg["step"])
#Note that freq=100
self.declare_readout(ch=cfg["ro_ch"], length=self.cfg["readout_length"],
freq=100, gen_ch=cfg["res_ch"])
#Begin frequency sweep from 80Mhz
freq=self.freq2reg(80, gen_ch=cfg["res_ch"], ro_ch=cfg["ro_ch"]) # convert frequency to dac frequency (ensuring it is an available adc frequency)
self.set_pulse_registers(ch=cfg["res_ch"], style="const", freq=freq, phase=0, gain=cfg["pulse_gain"],
length=cfg["length"])
self.synci(200) # give processor some time to configure pulses
def body(self):
self.measure(pulse_ch=self.cfg["res_ch"],
adcs=[self.cfg["ro_ch"]],
adc_trig_offset=self.cfg["adc_trig_offset"],
wait=True,
syncdelay=self.us2cycles(self.cfg["relax_delay"]))
def update(self):
self.mathi(self.r_rp, self.r_freq, self.r_freq, '+', self.step) # update freq of the pulse
config={"res_ch":6, # --Fixed
"ro_ch":0, # --Fixed
"relax_delay":0.01, # --Fixed
"res_phase":0, # --Fixed
"pulse_style": "const", # --Fixed
"length":100, # [Clock ticks]
"readout_length":100, # [Clock ticks]
"pulse_gain":1000, # [DAC units]
"pulse_freq": 100, # [MHz]
"adc_trig_offset": 10, # [Clock ticks]
"reps":1,
"expts": 400,
"start":80, # [MHz]
"step":0.1 # [MHz]
}
prog = SweepProgram(soccfg, config)
print(prog)
expt, avg_i, avg_q = prog.acquire(soc, load_pulses=True)
plt.xlabel("Frequency (MHz)")
plt.ylabel("Amplitude")
plt.plot(expt, abs(np.squeeze(avg_i) + 1j *np.squeeze(avg_q)))
I understand that this is an issue relating to the downconversion frequency, which we set in declare_readout (in the example we set it as 100MHz). My question is: can changing the downconversion frequency be implemented in the hardware, as part of the qick program loop? I have been unable to find a relevant register which could be accessed in a hardware loop to implement this, and I am uncertain whether such an implementation would be as simple as I imagine.
In every example that I have found, frequency sweeping has been implemented in software, and I would like to know the reason for this.
No, it's not possible in the standard firmware - this is mentioned in the 02_Sweeping_variables.ipynb demo (albeit briefly).