Pulsar QCM/QRM

Warning

Pulsar hardware is deprecated. Use cluster modules instead if possible!

Each device in the setup can be individually configured using the entry in the config. For instance:

 1mapping_config = {
 2    "backend": "quantify_scheduler.backends.qblox_backend.hardware_compile",
 3    "qcm0": {
 4        "instrument_type": "Pulsar_QCM",
 5        "ref": "internal",
 6        "complex_output_0": {
 7            "lo_name": "lo0",
 8            "portclock_configs": [
 9                {
10                    "port": "q0:mw",
11                    "clock": "q0.01",
12                    "interm_freq": 50e6
13                }
14            ]
15        },
16        "complex_output_1": {
17            "lo_name": "lo1",
18            "portclock_configs": [
19                {
20                    "port": "q1:mw",
21                    "clock": "q1.01",
22                    "interm_freq": None
23                }
24            ]
25        }
26    },
27    "lo0": {"instrument_type": "LocalOscillator", "frequency": None, "power": 20},
28    "lo1": {"instrument_type": "LocalOscillator", "frequency": 7.2e9, "power": 20}
29}

Here we specify a setup containing only a Pulsar QCM, with both outputs connected to local oscillator sources.

The first entry specifies the backend, the function that will compile a schedule using the information specified in this hardware config. All other entries at the highest level are instruments ("qcm0", "lo0", "lo1"). These names need to match the names of the corresponding QCoDeS instruments.

The first few entries of "qcm0" contain settings and information for the entire device: "type": "Pulsar_QCM" specifies that this device is a Pulsar QCM, and "ref": "internal" sets the reference source to internal (as opposed to "external"). Under the entries complex_output_0 (corresponding to O1/2) and complex_output_1 (corresponding to O3/4), we set all the parameters that are configurable per output.

The examples given below will be for a single Pulsar QCM, but the other devices can be configured similarly. In order to use a Pulsar QRM, QCM-RF or QRM-RF, change the "instrument_type" entry to "Pulsar_QRM", "Pulsar_QCM_RF" or "Pulsar_QRM_RF" respectively. Multiple devices can be added to the config, similar to how we added the local oscillators in the example given above.

Output settings

Most notably under the complex_output_0, we specify the port-clock combinations the output may target (see the User guide for more information on the role of ports and clocks within quantify-scheduler).

1"portclock_configs": [
2    {
3        "port": "q0:mw",
4        "clock": "q0.01",
5        "interm_freq": 50e6
6    }
7]

Additionally, the entry interm_freq specifies the intermediate frequency to use for I/Q modulation (in Hz) when targeting this port and clock.

I/Q modulation

To perform upconversion using an I/Q mixer and an external local oscillator, simply specify a local oscillator in the config using the lo_name entry. complex_output_0 is connected to a local oscillator instrument named lo0 and complex_output_1 to lo1. Since the aim of quantify-scheduler is to only specify the final RF frequency when the signal arrives at the chip, rather than any parameters related to I/Q modulation, we specify this information here.

The backend assumes that upconversion happens according to the relation

\[f_{RF} = f_{IF} + f_{LO}\]

This means that in order to generate a certain \(f_{RF}\), we need to specify either an IF or an LO frequency. In the dictionary, we therefore either set the lo_freq or the interm_freq and leave the other to be calculated by the backend by specifying it as None. Specifying both will raise an error if it violates \(f_{RF} = f_{IF} + f_{LO}\).

Downconverter

Some users may have a custom Qblox downconverter module operating at 4.4 GHz. In order to use it with this backend, we should specify a "downconverter": True entry in the outputs that are connected to this module, as exemplified below. The result is that the downconversion stage will be taken into account when calculating the IF or LO frequency (whichever was undefined) during compilation, such that the signal reaching the target port is at the desired clock frequency.

 1mapping_config_rf = {
 2    "backend": "quantify_scheduler.backends.qblox_backend.hardware_compile",
 3    "qcm0": {
 4        "instrument_type": "Pulsar_QCM_RF",
 5        "ref": "internal",
 6        "complex_output_0": {
 7            "downconverter": True,
 8            "portclock_configs": [
 9                {
10                    "port": "q0:mw",
11                    "clock": "q0.01",
12                    "interm_freq": 50000000.0
13                }
14            ]
15        }
16    }
17}
18hardware_compile(test_sched, mapping_config_rf)

Mixer corrections

The backend also supports setting the parameters that are used by the hardware to correct for mixer imperfections in real-time.

We configure this by adding the lines

1"dc_mixer_offset_I": -0.054,
2"dc_mixer_offset_Q": -0.034,

to complex_output_0 (or complex_output_1) in order to add a DC offset to the outputs to correct for feed-through of the local oscillator signal. And we add

1"mixer_amp_ratio": 0.9997,
2"mixer_phase_error_deg": -4.0,

to the port-clock configuration in order to set the amplitude and phase correction to correct for imperfect rejection of the unwanted sideband.

Usage without an LO

In order to use the backend without an LO, we simply remove the "lo_name" and all other related parameters. This includes the mixer correction parameters as well as the frequencies.

 1mapping_config = {
 2    "backend": "quantify_scheduler.backends.qblox_backend.hardware_compile",
 3    "qcm0": {
 4        "instrument_type": "Pulsar_QCM",
 5        "ref": "internal",
 6        "complex_output_0": {
 7            "portclock_configs": [
 8                {
 9                    "port": "q0:mw",
10                    "clock": "q0.01",
11                }
12            ]
13        },
14        "complex_output_1": {
15            "portclock_configs": [
16                {
17                    "port": "q1:mw",
18                    "clock": "q1.01",
19                }
20            ]
21        }
22    },
23}

Frequency multiplexing

It is possible to do frequency multiplexing of the signals by adding multiple port-clock configurations to the same output.

 1mapping_config = {
 2    "backend": "quantify_scheduler.backends.qblox_backend.hardware_compile",
 3    "qcm0": {
 4        "instrument_type": "Pulsar_QCM",
 5        "ref": "internal",
 6        "complex_output_0": {
 7            "portclock_configs": [
 8                {
 9                    "port": "q0:mw",
10                    "clock": "q0.01",
11                },
12                {
13                    "port": "q0:mw",
14                    "clock": "some_other_clock",
15                }
16            ]
17        },
18        "complex_output_1": {
19            "portclock_configs": [
20                {
21                    "port": "q1:mw",
22                    "clock": "q1.01",
23                }
24            ]
25        }
26    },
27}

In the given example, we added a second port-clock configuration to output 0. Now any signal on port "q0:mw" with clock "some_other_clock" will be added digitally to the signal with the same port but clock "q0.01". The Qblox modules currently have six sequencers available, which sets the upper limit to our multiplexing capabilities.

Note

We note that it is a requirement of the backend that each combination of a port and a clock is unique, i.e. it is possible to use the same port or clock multiple times in the hardware config but the combination of a port with a certain clock can only occur once.

Gain and attenuation

For QRM, QRM-RF and QCM-RF modules you can set the gain and attenuation parameters in dB. See the example below for the possible gain and attenuation parameters for each module type.

  • The parameters input_gain_I and input_gain_Q for QRM correspond to the qcodes parameters in0_gain and in1_gain respectively.

  • The parameters output_att and input_att for QRM-RF correspond to the qcodes parameters out0_att and in0_att respectively.

  • The parameters output_atts for QCM-RF correspond to the qcodes parameters out0_att and out1_att.

 1mapping_config = {
 2    ...
 3    "qrm0": {
 4        "instrument_type": "Pulsar_QRM",
 5        "complex_output_0": {
 6            "input_gain_I": 2,
 7            "input_gain_Q": 3,
 8            ...
 9        },
10    },
11    "qrm_rf0": {
12        "instrument_type": "QRM_RF",
13        "complex_output_0": {
14            "output_att": 12,
15            "input_att": 10,
16            ...
17        },
18    },
19    "qcm_rf0": {
20        "instrument_type": "QCM_RF",
21        "complex_output_0": {
22            "output_att": 4,
23            ...
24        },
25        "complex_output_1": {
26            "output_att": 6,
27            ...
28        },
29    },
30}

See Qblox Instruments: QCM-QRM documentation for allowed values.

Real mode

For the baseband modules, it is also possible to use the backend to generate signals for the outputs individually rather than using IQ pairs.

In order to do this, instead of "complex_output_X", we use "real_output_X". In the case of a QCM, we have four of those outputs. The QRM has two available.

The resulting config looks like this:

 1mapping_config = {
 2    "backend": "quantify_scheduler.backends.qblox_backend.hardware_compile",
 3    "qcm0": {
 4        "instrument_type": "Pulsar_QCM",
 5        "ref": "internal",
 6        "real_output_0": {
 7            "portclock_configs": [
 8                {
 9                    "port": "q0:mw",
10                    "clock": "q0.01",
11                }
12            ]
13        },
14        "real_output_1": {
15            "portclock_configs": [
16                {
17                    "port": "q1:mw",
18                    "clock": "q1.01",
19                }
20            ]
21        },
22        "real_output_2": {
23            "portclock_configs": [
24                {
25                    "port": "q2:mw",
26                    "clock": "q2.01",
27                }
28            ]
29        }
30    },
31}

When using real outputs, the backend automatically maps the signals to the correct output paths. We note that for real outputs, it is not allowed to use any pulses that have an imaginary component i.e. only real-valued pulses are allowed. If you were to use a complex pulse, the backend will produce an error, e.g. square and ramp pulses are allowed but DRAG pulses are not.

Warning

When using real mode, we highly recommend using it in combination with the instrument coordinator as the outputs need to be configured correctly in order for this to function.

Instruction-generated pulses

Warning

The instruction_generated_pulses_enabled option is deprecated and will be removed in a future version. Long square pulses and staircase pulses can be generated with the newly introduced StitchedPulseBuilder. More information can be found in the relevant section of the Cluster user guide.

The Qblox backend contains some intelligence that allows it to generate certain specific waveforms from the pulse library using a more complicated series of sequencer instructions, which helps conserve waveform memory. Though in order to keep the backend fully transparent, all such advanced capabilities are disabled by default.

In order to enable the advanced capabilities we need to add line "instruction_generated_pulses_enabled": True to the port-clock configuration.

 1mapping_config = {
 2    "backend": "quantify_scheduler.backends.qblox_backend.hardware_compile",
 3    "qcm0": {
 4        "instrument_type": "Pulsar_QCM",
 5        "ref": "internal",
 6        "complex_output_0": {
 7            "portclock_configs": [
 8                {
 9                    "port": "q0:mw",
10                    "clock": "q0.01",
11                    "instruction_generated_pulses_enabled": True
12                }
13            ]
14        },
15    },
16}

Currently, this has the following effects:

  • Long square pulses get broken up into separate pulses with durations <= 1 us, which allows the modules to play square pulses longer than the waveform memory normally allows.

  • Staircase pulses are generated using offset instructions instead of using waveform memory