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
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
andinput_gain_Q
for QRM correspond to the qcodes parameters in0_gain and in1_gain respectively.The parameters
output_att
andinput_att
for QRM-RF correspond to the qcodes parameters out0_att and in0_att respectively.The parameters
output_att
s 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