qick.qick

The lower-level driver for the QICK library. Contains classes for interfacing with the SoC.

Classes

AxisSwitch(*args, **kwargs)

AxisSwitch class to control Xilinx AXI-Stream switch IP

QickSoc(*args, **kwargs)

QickSoc class.

RFDC(*args, **kwargs)

Extends the xrfdc driver.

class qick.qick.AxisSwitch(*args: Any, **kwargs: Any)[source]

Bases: SocIp

AxisSwitch class to control Xilinx AXI-Stream switch IP

Parameters:
  • nslave (int) – Number of slave interfaces

  • nmaster (int) – Number of master interfaces

disable_ports()[source]

Disables ports

sel(mst=0, slv=0)[source]

Digitally connects a master interface with a slave interface

Parameters:
  • mst (int) – Master interface

  • slv (int) – Slave interface

class qick.qick.RFDC(*args: Any, **kwargs: Any)[source]

Bases: RFdc

Extends the xrfdc driver. Since operations on the RFdc tend to be slow (tens of ms), we cache the Nyquist zone and frequency.

set_mixer_freq(dacname, f, phase_reset=True, force=False)[source]

Set the NCO frequency that will be mixed with the generator output.

Note that the RFdc driver does its own math to round the frequency to the NCO’s frequency step. If you want predictable behavior, the frequency you use here should already be rounded. Rounding is normally done for you as part of AbsQickProgram.declare_gen().

Parameters:
  • dacname (int) – DAC channel (2-digit string)

  • f (float) – NCO frequency

  • force (bool) – force update, even if the setting is the same

  • phase_reset (bool) – if we change the frequency, also reset the NCO’s phase accumulator

set_nyquist(blockname, nqz, blocktype='dac', force=False)[source]

Sets channel to operate in Nyquist zone nqz. This setting doesn’t change the DAC output frequencies: you will always have some power at both the demanded frequency and its image(s). Setting the NQZ to 2 increases output power in the 2nd/3rd Nyquist zones. See “RF-DAC Nyquist Zone Operation” in PG269.

Parameters:
  • blockname (int) – channel ID (2-digit string)

  • nqz (int) – Nyquist zone (1 or 2)

  • blocktype (str) – ‘dac’ or ‘adc’

  • force (bool) – force update, even if the setting is the same

get_nyquist(blockname, blocktype='dac')[source]

Get the current Nyquist zone setting for a channel.

Parameters:
  • blockname (str) – Channel ID (2-digit string)

  • blocktype (str) – ‘dac’ or ‘adc’

Returns:

NQZ setting (1 or 2)

Return type:

int

class qick.qick.QickSoc(*args: Any, **kwargs: Any)[source]

Bases: Overlay, QickConfig

QickSoc class. This class will create all object to access system blocks

Parameters:
  • bitfile (str) – Path to the bitfile. This should end with .bit, and the corresponding .hwh file must be in the same directory.

  • force_init_clks (bool) – Re-initialize the board clocks regardless of whether they appear to be locked. Specifying (as True or False) the clk_output or external_clk options will also force clock initialization.

  • clk_output (bool or None) – If true, output a copy of the RF reference. This option is supported for the ZCU111 (get 122.88 MHz from J108) and ZCU216 (get 245.76 MHz from OUTPUT_REF J10).

  • external_clk (bool or None) – If true, lock the board clocks to an external reference. This option is supported for the ZCU111 (put 12.8 MHz on External_REF_CLK J109), ZCU216 (put 10 MHz on INPUT_REF_CLK J11), and RFSoC 4x2 (put 10 MHz on CLK_IN).

  • ignore_version (bool) – Whether version discrepancies between PYNQ build and firmware build are ignored

map_signal_paths()[source]

Make lists of signal generator, readout, and buffer blocks in the firmware. Also map the switches connecting the generators and buffers to DMA. Fill the config dictionary with parameters of the DAC and ADC channels.

config_clocks(force_init_clks)[source]

Configure PLLs if requested, or if any ADC/DAC is not locked.

clocks_locked()[source]

Checks whether the DAC and ADC PLLs are locked. This can only be run after the bitstream has been downloaded.

Returns:

clock status

Return type:

bool

list_rf_blocks(rf_config)[source]

Lists the enabled ADCs and DACs and get the sampling frequencies. XRFdc_CheckBlockEnabled in xrfdc_ap.c is not accessible from the Python interface to the XRFdc driver. This re-implements that functionality.

set_all_clks()[source]

Resets all the board clocks

get_decimated(ch, address=0, length=None)[source]

Acquires data from the readout decimated buffer

Parameters:
  • ch (int) – ADC channel

  • address (int) – Address of data

  • length (int) – Buffer transfer length

Returns:

List of I and Q decimated arrays

Return type:

list

get_accumulated(ch, address=0, length=None)[source]

Acquires data from the readout accumulated buffer

Parameters:
  • ch (int) – ADC channel

  • address (int) – Address of data

  • length (int) – Buffer transfer length

Returns:

  • di[:length] (list) - list of accumulated I data

  • dq[:length] (list) - list of accumulated Q data

configure_readout(ch, ro_regs)[source]

Configure readout channel output style and frequency. This method is only for use with PYNQ-configured readouts.

Parameters:
  • ch (int) – readout channel number (index in ‘readouts’ list)

  • ro_regs (dict) – readout registers, from QickConfig.calc_ro_regs()

config_avg(ch, address=0, length=1, enable=True)[source]

Configure and optionally enable accumulation buffer :param ch: Channel to configure :type ch: int :param address: Starting address of buffer :type address: int :param length: length of buffer (how many samples to take) :type length: int :param enable: True to enable buffer :type enable: bool

config_buf(ch, address=0, length=1, enable=True)[source]

Configure and optionally enable decimation buffer :param ch: Channel to configure :type ch: int :param address: Starting address of buffer :type address: int :param length: length of buffer (how many samples to take) :type length: int :param enable: True to enable buffer :type enable: bool

get_avg_max_length(ch=0)[source]

Get accumulation buffer length for channel :param ch: Channel :type ch: int :return: Length of accumulation buffer for channel ‘ch’ :rtype: int

load_pulse_data(ch, data, addr)[source]

Load pulse data into signal generators :param ch: Channel :type ch: int :param data: array of (I, Q) values for pulse envelope :type data: int16 array :param addr: address to start data at :type addr: int

set_nyquist(ch, nqz, force=False)[source]

Sets DAC channel ch to operate in Nyquist zone nqz mode.

Parameters:
  • ch (int) – DAC channel (index in ‘gens’ list)

  • nqz (int) – Nyquist zone

set_mixer_freq(ch, f, ro_ch=None, phase_reset=True)[source]

Set mixer frequency for a signal generator. If the generator does not have a mixer, you will get an error.

Parameters:
  • ch (int) – DAC channel (index in ‘gens’ list)

  • f (float) – Mixer frequency (in MHz)

  • ro_ch (int) – readout channel (index in ‘readouts’ list) for frequency matching use None if you don’t want mixer freq to be rounded to a valid readout frequency

  • phase_reset (bool) – if this changes the frequency, also reset the phase (so if we go to freq=0, we end up on the real axis)

config_mux_gen(ch, tones)[source]

Set up a list of tones all at once, using raw (integer) units. If the supplied list of tones is shorter than the number supported, the extra tones will have their gains set to 0.

Parameters:
  • ch (int) – generator channel (index in ‘gens’ list)

  • tones (list of dict) – Tones to configure. This is generated by QickConfig.calc_muxgen_regs().

config_mux_readout(pfbpath, cfgs, sel=None)[source]

Set up a list of readout frequencies all at once, using raw (integer) units.

Parameters:
  • pfbpath (str) – Firmware path of the PFB readout being configured.

  • cfgs (list of dict) – Readout chains to configure. This is generated by QickConfig.calc_pfbro_regs().

  • sel (str) – Output selection (if supported), default to ‘product’

set_iq(ch, f, i, q, ro_ch=None, phase_reset=True)[source]

Set frequency, I, and Q for a constant-IQ output.

Parameters:
  • ch (int) – DAC channel (index in ‘gens’ list)

  • f (float) – frequency (in MHz)

  • i (float) – I value (in range -1 to 1)

  • q (float) – Q value (in range -1 to 1)

  • ro_ch (int) – readout channel (index in ‘readouts’ list) for frequency matching use None if you don’t want freq to be rounded to a valid readout frequency

  • phase_reset (bool) – if this changes the frequency, also reset the phase (so if we go to freq=0, we end up on the real axis)

load_bin_program(binprog)[source]

Write the program to the tProc program memory.

start_src(src)[source]

Sets the start source of tProc

Parameters:

src (string) – start source “internal” or “external”

start_tproc()[source]

Start the tProc.

stop_tproc(lazy=False)[source]

Stop the tProc. This is somewhat slow (tens of ms) for tProc v1.

Parameters:

lazy (bool) – Only stop the tProc if it’s easy (i.e. do nothing for v1)

set_tproc_counter(addr, val)[source]

Initialize the tProc shot counter. :param addr: Counter address :type addr: int

Returns:

Counter value

Return type:

int

get_tproc_counter(addr)[source]

Read the tProc shot counter. For tProc V1, this accesses the data memory at the given address. For tProc V2, this accesses one of the two special AXI-readable registers.

Parameters:

addr (int) – Counter address

Returns:

Counter value

Return type:

int

reset_gens()[source]

Reset the tProc and run a minimal tProc program that drives all signal generators with 0’s. Useful for stopping any periodic or stdysel=”last” outputs that may have been driven by a previous program.

start_readout(total_shots, counter_addr=1, ch_list=None, reads_per_shot=1, stride=None)[source]

Start a streaming readout of the accumulated buffers.

Parameters:
  • total_shots (int) – Final value expected for the shot counter

  • counter_addr (int) – Data memory address for the shot counter

  • ch_list (list of int) – List of readout channels

  • reads_per_shot (list of int) – Number of data points to expect per counter increment

  • stride (int) – Default number of measurements to transfer at a time.

poll_data(totaltime=0.1, timeout=None)[source]

Get as much data as possible from the streamer data queue. Stop when any of the following conditions are met: * all the data has been transferred (based on the total_count) * we got data, and it has been totaltime seconds since poll_data was called * timeout is defined, and the timeout expired without getting new data in the queue If there are errors in the error queue, raise the first one.

Parameters:
  • totaltime (float) – How long to acquire data (negative value = ignore total time and total count, just read until timeout)

  • timeout (float) – How long to wait for the next data packet (None = wait forever)

Returns:

list of (data, stats) pairs, oldest first

Return type:

list

clear_ddr4(length=None)[source]

Clear the DDR4 buffer, filling it with 0’s. This is not necessary (the buffer will overwrite old data), but may be useful for debugging. Clearing the full buffer (4 GB) typically takes 4-5 seconds.

Parameters:

length (int) – Number of samples to clear (starting at the beginning of the buffer). If None, clear the entire buffer.

get_ddr4(nt, start=None)[source]

Get data from the DDR4 buffer. The first samples (typically 401 or 801) of the buffer are always stale data from the previous acquisition.

Parameters:
  • nt (int) – Number of data transfers (each transfer is 128 or 256 decimated samples) to retrieve. If start=None, the amount of data will be reduced (see below).

  • start (int) – Number of samples to skip at the beginning of the buffer. If a value is specified, the end address of the transfer window will also be incremented. If None, the junk at the start of the buffer will be skipped but the end address will not be incremented. This reduces the amount of data, giving you exactly the block of valid data from a DDR4 trigger with the same value of nt.

arm_ddr4(ch, nt, force_overwrite=False)[source]

Prepare the DDR4 buffer to take data. This must be called before starting a program that triggers the buffer. Once the buffer is armed, the first trigger it receives will cause the buffer to record the specified amount of data. Later triggers will have no effect.

Parameters:
  • ch (int) – The readout channel to record (index in ‘readouts’ list).

  • nt (int) – Number of data transfers to record; the number of IQ samples/transfer (128 or 256) is printed in the QickSoc config. Note that the amount of useful data is less (see get_ddr4)

  • force_overwrite (bool) – Allow a DDR4 acqusition that exceeds the DDR4 memory capacity. The memory will be used as a circular buffer: later transfers will wrap around to the beginning of the memory and overwrite older data.

arm_mr(ch)[source]

Prepare the Multi-Rate buffer to take data. This must be called before starting a program that triggers the buffer. Once the buffer is armed, the first trigger it receives will cause the buffer to record until the buffer is filled. Later triggers will have no effect.

Parameters:

ch (int) – The readout channel to record (index in ‘readouts’ list).

get_mr(start=None)[source]

Get data from the multi-rate buffer. The first 8 samples are always stale data from the previous acquisition. The transfer window always extends to the end of the buffer.

Parameters:

start (int) – Number of samples to skip at the beginning of the buffer. If None, the junk at the start of the buffer is skipped.