qick.qick_asm
The interface for writing QICK programs. This contains tools for managing the board configuration and the base class for QICK programs. The assembly language for QICK programs is defined separately for the v1 and v2 tProcessors.
Classes
|
Generic QICK program, including support for generator and readout configuration but excluding tProc-specific code. |
|
Adds acquire() and acquire_decimated() methods for acquiring readout data, and run_rounds() for running repeatedly without acquisition. |
|
Stores the configuration constants for a firmware IP block. |
|
Uses the QICK configuration to convert frequencies and clock delays. |
- class qick.qick_asm.QickConfig(cfg=None)[source]
Bases:
object
Uses the QICK configuration to convert frequencies and clock delays. If running on the QICK, you don’t need to use this class - the QickSoc class has all of the same methods. If running remotely, you may want to initialize a QickConfig from a JSON file.
- description()[source]
Generate a printable description of the QICK configuration.
- Returns:
description
- Return type:
- get_cfg()[source]
Return the QICK configuration dictionary. This contains everything you need to recreate the QickConfig.
- Returns:
configuration dictionary
- Return type:
- dump_cfg()[source]
Generate a JSON description of the QICK configuration. You can save this string to a file and load it to recreate the QickConfig.
- Returns:
configuration in JSON format
- Return type:
- calc_fstep_int(dict1, other_dicts)[source]
Finds the multiplier that needs to be applied to a channel’s frequency step size to allow this channel to be frequency-matched with another channel.
- calc_fstep(dicts)[source]
Finds the least common multiple of the frequency steps of one or more channels (typically two, a generator and a readout) For proper frequency matching, you should only use frequencies that are evenly divisible by this value. The order of the parameters does not matter.
- roundfreq(f, dicts)[source]
Round a frequency to the LCM of the frequency steps of one or more channels (typically two, a generator and a readout).
- freq2int(f, thisch, otherch=None)[source]
Converts frequency in MHz to integer value suitable for writing to a register. This method works for both generators and readouts. If a gen will be connected to an RO, the two channels must have exactly the same frequency, and you must supply the config for the other channel.
- int2freq(r, thisch)[source]
Converts register value to MHz. This method works for both generators and readouts.
- freq2reg(f, gen_ch=0, ro_ch=None)[source]
Converts frequency in MHz to tProc generator register value.
- adcfreq(f, gen_ch=0, ro_ch=0)[source]
Takes a frequency and trims it to the closest DDS frequency valid for both channels.
- deg2int(deg, thisch)[source]
Converts phase in degrees to integer value suitable for writing to a register. This method works for both generators and readouts.
- int2deg(r, thisch)[source]
Converts register value to degrees. This method works for both generators and readouts.
- deg2reg(deg, gen_ch=0, ro_ch=None)[source]
Converts degrees into phase register values; numbers greater than 360 will effectively be wrapped.
- cycles2us(cycles, gen_ch=None, ro_ch=None)[source]
Converts clock cycles to microseconds. Uses tProc clock frequency by default. If gen_ch or ro_ch is specified, uses that generator/readout channel’s fabric clock.
- us2cycles(us, gen_ch=None, ro_ch=None)[source]
Converts microseconds to integer number of clock cycles. Uses tProc clock frequency by default. If gen_ch or ro_ch is specified, uses that generator/readout channel’s fabric clock.
- calc_mixer_freq(gen_ch, mixer_freq, nqz, ro_ch)[source]
Set the NCO frequency that will be mixed with the generator output.
The RFdc driver does its own math to convert a frequency to a register value. (see XRFdc_SetMixerSettings in xrfdc_mixer.c, and “NCO Frequency Conversion” in PG269) This is what it does: 1. Add/subtract fs to get the frequency in the range of [-fs/2, fs/2]. 2. If the original frequency was not in [-fs/2, fs/2] and the DAC is configured for 2nd Nyquist zone, multiply by -1. 3. Convert to a 48-bit register value, rounding using C integer casting (i.e. round towards 0).
Step 2 is not desirable for us, so we must undo it.
The rounding gives unexpected results sometimes: it’s hard to tell if a freq will get rounded up or down. This is important if the demanded frequency was rounded to a valid frequency for frequency matching. The safest way to get consistent behavior is to always round to a valid NCO frequency. We are trusting that the floating-point math is exact and a number we rounded here is still a round number in the RFdc driver.
- calc_muxgen_regs(gen_ch, freqs, gains, phases, ro_ch)[source]
Calculate the register values to program into a multiplexed generator.
- calc_ro_regs(rocfg, phase, sel)[source]
Calculate the settings to configure a readout.
- Returns:
settings for QickSoc.config_readout()
- Return type:
- calc_ro_freq(rocfg, ro_pars, ro_regs, mixer_freq)[source]
Calculate the readout frequency and registers.
- class qick.qick_asm.DummyIp(iptype, fullpath)[source]
Bases:
object
Stores the configuration constants for a firmware IP block.
- class qick.qick_asm.AbsQickProgram(soccfg)[source]
Bases:
object
Generic QICK program, including support for generator and readout configuration but excluding tProc-specific code. QickProgram/QickProgramV2 are the concrete subclasses for tProc v1/v2.
The tProc executes binary machine code; you write declarations and ASM code (or macros that get expanded to ASM). So before a program gets run, you need to fill it with declarations and ASM, and they need to get compiled (converted to machine code). There are three ways to prepare a QickProgram for running:
1. External initialization: Create an empty program object. Write the program by calling declaration and ASM methods of the program object. The program will be compiled when you try to run, dump, or print it.
2. Internal initialization: Create a subclass which calls declaration and ASM methods as part of __init__(). When you create an instance of the subclass, it will automatically fill itself. Typically you won’t subclass QickProgram directly, you will subclass something like AveragerProgram which does a lot of the work for you. The program will be compiled when you try to run, dump, or print.
3. Loading a dump: Create an empty program object. Call QickProgram.load_prog() to load the program definition from a dump. The program will be compiled as part of load_prog().
- dump_prog()[source]
Dump the program to a dictionary. This output contains all the information necessary to run the program. In other words, it will have the low-level ASM and pulse+envelope data, but not higher-level structures. Caution: don’t modify the sub-dictionaries of this dict! You will be modifying the original program (this is not a deep copy).
- config_all(soc, load_pulses=True, reset=False)[source]
Load the waveform memory, gens, ROs, and program memory as specified for this program. The decimated+accumulated buffers are not configured, since those should be re-configured for each acquisition. The tProc is set to internal start before any other configuration is done, to prevent spurious external starts.
- Parameters:
reset (bool) – Force-stop the tProc before loading the program. This option only affects tProc v1, where the reset takes several ms. For tProc v2, where reset is easy, we always do the reset.
- run(soc, load_prog=True, load_pulses=True, start_src='internal')[source]
Load the program into the tProcessor and start it. Because there is in general no way to tell when a program is done running, there is no guarantee that the program will be done before this method returns. If you want that guarantee, use run_rounds().
- Parameters:
soc (QickSoc) – The QickSoc that will execute this program.
load_prog (bool) – Load the program before starting the tProc.
load_pulses (bool) – Load the generator envelopes before starting the tProc. If load_prog is False, load_pulses is ignored.
start_src (str) – “internal” (tProc starts immediately) or “external” (each round waits for an external trigger).
- declare_readout(ch, length, freq=None, phase=0, sel='product', gen_ch=None)[source]
Add a channel to the program’s list of readouts. Duration units depend on the program type: tProc v1 programs use integer number of samples, tProc v2 programs use float us.
- Parameters:
ch (int) – readout channel number (index in ‘readouts’ list)
freq (float) – downconverting frequency (MHz)
phase (float) – phase (degrees)
length (int or float) – readout length (number of decimated samples for tProc v1, us for tProc v2)
sel (str) – output select (‘product’, ‘dds’, ‘input’)
gen_ch (int) – generator channel (use None if you don’t want the downconversion frequency to be rounded to a valid DAC frequency or be offset by the DAC mixer frequency)
- config_readouts(soc)[source]
Configure the readout channels specified in this program. This is usually called as part of an acquire() method.
- Parameters:
soc (QickSoc) – the QickSoc that will execute this program
- config_bufs(soc, enable_avg=True, enable_buf=True)[source]
Configure the readout buffers specified in this program. This is usually called as part of an acquire() method.
- declare_gen(ch, nqz=1, mixer_freq=None, mux_freqs=None, mux_gains=None, mux_phases=None, ro_ch=None)[source]
Add a channel to the program’s list of signal generators.
If this is a generator with a mixer (interpolated or muxed generator), you may define a mixer frequency.
If this is a muxed generator, the mux_freqs list must be long enough to define all the tones you will play. (in other words, if your mask list ever enables tone 2 you must define at least 3 freqs+gains) If your mux gen supports gains and/or phases and you define them, those lists must be the same length. If you don’t define gains or phases, they will be set to defaults (max positive gain, zero phase).
- Parameters:
ch (int) – generator channel (index in ‘gens’ list)
nqz (int, optional) – Nyquist zone (must be 1 or 2). Setting the NQZ to 2 increases output power in the 2nd/3rd Nyquist zones.
mixer_freq (float, optional) – Mixer frequency (in MHz)
mux_freqs (list of float, optional) – Tone frequencies for the muxed generator (in MHz). Positive and negative values are allowed.
mux_gains (list of float, optional) – Tone amplitudes for the muxed generator (in range -1 to 1).
mux_phases (list of float, optional) – Phases for the muxed generator (in degrees).
ro_ch (int, optional) – readout channel for frequency-matching mixer and mux freqs
- config_gens(soc)[source]
Configure the signal generators specified in this program. This is usually called as part of an acquire() method.
- Parameters:
soc (QickSoc) – the QickSoc that will execute this program
- add_envelope(ch, name, idata=None, qdata=None)[source]
Adds a waveform to the list of envelope waveforms available for this channel. The I and Q arrays must be of equal length, and the length must be divisible by the samples-per-clock of this generator.
- add_cosine(ch, name, length, maxv=None, even_length=False)[source]
Adds a cosine to the envelope library. The envelope will peak at length/2. Duration units depend on the program type: tProc v1 programs use integer number of fabric clocks, tProc v2 programs use float us.
- Parameters:
ch (int) – generator channel (index in ‘gens’ list)
name (str) – Name of the envelope
length (int) – Total envelope length (in fabric clocks or us)
maxv (float) – Value at the peak (if None, the max value for this generator will be used)
even_length (bool) – If length is in us, round the envelope length to an even number of fabric clock cycles. This is useful for flat_top pulses, where the envelope gets split into two halves.
- add_gauss(ch, name, sigma, length, maxv=None, even_length=False)[source]
Adds a Gaussian to the envelope library. The envelope will peak at length/2. Duration units depend on the program type: tProc v1 programs use integer number of fabric clocks, tProc v2 programs use float us.
- Parameters:
ch (int) – generator channel (index in ‘gens’ list)
name (str) – Name of the envelope
sigma (float) – Standard deviation of the Gaussian (in fabric clocks or us)
length (int or float) – Total envelope length (in fabric clocks or us)
maxv (float) – Value at the peak (if None, the max value for this generator will be used)
even_length (bool) – If length is in us, round the envelope length to an even number of fabric clock cycles. This is useful for flat_top pulses, where the envelope gets split into two halves.
- add_DRAG(ch, name, sigma, length, delta, alpha=0.5, maxv=None, even_length=False)[source]
Adds a DRAG to the envelope library. The envelope will peak at length/2.
- Parameters:
ch (int) – generator channel (index in ‘gens’ list)
name (str) – Name of the envelope
sigma (float or float) – Standard deviation of the Gaussian (in fabric clocks or us)
length (int or float) – Total envelope length (in fabric clocks or us)
maxv (float) – Value at the peak (if None, the max value for this generator will be used)
delta (float) – anharmonicity of the qubit (units of MHz)
alpha (float) – alpha parameter of DRAG (order-1 scale factor)
even_length (bool) – If length is in us, round the envelope length to an even number of fabric clock cycles. This is useful for flat_top pulses, where the envelope gets split into two halves.
- add_triangle(ch, name, length, maxv=None, even_length=False)[source]
Adds a triangle to the envelope library. The envelope will peak at length/2. Duration units depend on the program type: tProc v1 programs use integer number of fabric clocks, tProc v2 programs use float us.
- Parameters:
ch (int) – generator channel (index in ‘gens’ list)
name (str) – Name of the envelope
length (int or float) – Total envelope length (in fabric clocks or us)
maxv (float) – Value at the peak (if None, the max value for this generator will be used)
even_length (bool) – If length is in us, round the envelope length to an even number of fabric clock cycles. This is useful for flat_top pulses, where the envelope gets split into two halves.
- class qick.qick_asm.AcquireMixin(*args, **kwargs)[source]
Bases:
object
Adds acquire() and acquire_decimated() methods for acquiring readout data, and run_rounds() for running repeatedly without acquisition. Program classes that use this mixin must call setup_acquire() after _init_prog() and before acquire()/acquire_decimated().
- setup_counter(counter_addr, loop_dims)[source]
Set the parameters needed to track the progress of the program. This is a subset of setup_acquire(), appropriate for programs where you have no readouts. You should use this if you’re updating a tProc counter and want to use it to track program progress.
- setup_acquire(counter_addr, loop_dims, avg_level)[source]
Set the parameters needed to define the data acquisition. Since the number of readouts per shot is set based on calls to trigger(), this should be called after the program has been fully defined.
- set_reads_per_shot(reads_per_shot)[source]
Override the default count of readout triggers per shot. This should be called after setup_acquire(). You probably shouldn’t be using this method; the default value is usually correct.
- get_raw()[source]
Get the raw integer I/Q values (before normalizing to the readout window, averaging across reps, removing the readout offset, or thresholding).
- Returns:
Array of I/Q values for each readout channel.
- Return type:
list of ndarray
- get_shots()[source]
Get the shot-by-shot threshold decisions.
- Returns:
Array of shots for each readout channel.
- Return type:
list of ndarray
- acquire(soc, soft_avgs=1, load_pulses=True, start_src='internal', threshold=None, angle=None, progress=True, remove_offset=True)[source]
Acquire data using the accumulated readout.
- Parameters:
soc (QickSoc) – Qick object
soft_avgs (int) – number of times to rerun the program, averaging results in software (aka “rounds”)
load_pulses (bool) – if True, load pulse envelopes
start_src (str) – “internal” (tProc starts immediately) or “external” (each round waits for an external trigger)
threshold (float or list of float) – The threshold(s) to apply to the I values after rotation. Length-normalized units (same units as the output of acquire()). If scalar, the same threshold will be applied to all readout channels. A list must have length equal to the number of declared readout channels.
angle (float or list of float) – The angle to rotate the I/Q values by before applying the threshold. Units of radians. If scalar, the same angle will be applied to all readout channels. A list must have length equal to the number of declared readout channels.
progress (bool) – if true, displays progress bar
remove_offset (bool) – Some readouts (muxed and tProc-configured) introduce a small fixed offset to the I and Q values of every decimated sample. This subtracts that offset, if any, before returning the averaged IQ values or rotating to apply software thresholding.
- Returns:
averaged IQ values (float) divided by the length of the RO window, and averaged over reps and rounds if threshold is defined, the I values will be the fraction of points over threshold dimensions for a simple averaging program: (n_ch, n_reads, 2) dimensions for a program with multiple expts/steps: (n_ch, n_reads, n_expts, 2)
- Return type:
ndarray
- get_time_axis_ddr4(ro_ch, data)[source]
Get an array usable as the time axis for plotting DDR4 data.
- run_rounds(soc, rounds=1, load_pulses=True, start_src='internal', progress=True)[source]
Run the program and wait until it completes, once or multiple times. No data will be saved.
- Parameters:
- acquire_decimated(soc, soft_avgs, load_pulses=True, start_src='internal', progress=True, remove_offset=True)[source]
Acquire data using the decimating readout.
- Parameters:
soc (QickSoc) – Qick object
soft_avgs (int) – number of times to rerun the program, averaging results in software (aka “rounds”)
load_pulses (bool) – if True, load pulse envelopes
start_src (str) – “internal” (tProc starts immediately) or “external” (each round waits for an external trigger)
progress (bool) – if true, displays progress bar
remove_offset (bool) – Subtract the readout’s IQ offset, if any.
- Returns:
decimated values, averaged over rounds (float) dimensions for a single-rep, single-read program : (length, 2) multi-rep or multi-read: (n_reps*n_reads, length, 2) multi-rep and multi-read: (n_reps, n_reads, length, 2)
- Return type:
list of ndarray