See also
A Jupyter notebook version of this tutorial can be downloaded here.
Real sequencer mode#
In this tutorial we show how to use the real mode of baseband modules. We do this by generating an amplitude modulated signal with sine envelope summed with non-modulated component consisting also in a sine wave, with the same frequency but different amplitude. For more details, see the user guide.
Setup#
First, we are going to import the required packages.
[1]:
from __future__ import annotations
import numpy as np
from qcodes.instrument import find_or_create_instrument
from qblox_instruments import Cluster, ClusterType
Scan For Clusters#
We scan for the available devices connected via ethernet using the Plug & Play functionality of the Qblox Instruments package (see Plug & Play for more info).
!qblox-pnp list
[2]:
cluster_ip = "10.10.200.42"
cluster_name = "cluster0"
Connect to Cluster#
We now make a connection with the Cluster.
[3]:
cluster: Cluster = find_or_create_instrument(
Cluster,
recreate=True,
name=cluster_name,
identifier=cluster_ip,
dummy_cfg=(
{
2: ClusterType.CLUSTER_QCM,
4: ClusterType.CLUSTER_QRM,
6: ClusterType.CLUSTER_QCM_RF,
8: ClusterType.CLUSTER_QRM_RF,
10: ClusterType.CLUSTER_QTM,
12: ClusterType.CLUSTER_QRC,
16: ClusterType.CLUSTER_QSM,
}
if cluster_ip is None
else None
),
)
cluster.reset()
print(cluster.get_system_status())
Status: ERROR, Flags: FEEDBACK_NETWORK_CALIBRATION_FAILED, Slot flags: NONE
Get connected modules#
[4]:
# QCM baseband modules
modules = cluster.get_connected_modules(lambda mod: mod.is_qcm_type and not mod.is_rf_type)
# This uses the module of the correct type with the lowest slot index
module = list(modules.values())[0]
Parameterize the waveforms we want to generate on the two paths of the sequencer, as well as the NCO frequency:
[5]:
nco_frequency = 40e6 # NCO frequency of 40 MHz
sine_envelope_frequency = 1e6 # frequency of the sine waveform used for both path_0 and path_1
amplitude = 0.5 # amplitude of the sine wave on path_0 (modulated by the NCO)
amplitude_ratio = 0.5 # ratio of the amplitude of the sine wave on path_1 (unmodulated)
# with respect to the amplitude of the sine wave on path_0
number_of_pts = int(1e9 / sine_envelope_frequency) # the AWG sampling rate is 1 Gs/second
Generation of the sine wave, used for the path_0 (modulated by the NCO) and the path_1 (unmodulated). We also write a short sequence with the parameters defined above.
[6]:
wf0 = np.sin(2 * np.pi * sine_envelope_frequency * np.arange(number_of_pts) * 1e-9).tolist()
wfs = {
"wf0": {"data": wf0, "index": 0},
}
program0 = f"""
wait_sync 4
set_awg_gain {int(amplitude_ratio * amplitude * 32767)},{int(amplitude * 32767)}
play:
set_mrk 15
play 0,0,4
set_mrk 0
upd_param 4
wait {number_of_pts - 8}
jmp @play # loop indefinitely
"""
# assembling the program and the waveforms into a sequence dictionary object, as expected by the `qblox-instruments` API
sequence0 = {"waveforms": wfs, "weights": {}, "acquisitions": {}, "program": program0}
Finally, we load the program in the sequencer, activate the real mode and connect the sequencer output to an output port:
[7]:
module.sequencer0.sync_en(True)
module.sequencer0.mod_en_awg(True)
module.sequencer0.nco_freq(nco_frequency)
module.disconnect_outputs()
module.sequencer0.real_mode_en(True)
module.sequencer0.sequence(sequence0)
module.sequencer0.connect_out0("I")
module.arm_sequencer(0)
module.start_sequencer(0)
The sequence is interrupted with
[8]:
module.stop_sequencer(0)
module.sequencer0.real_mode_en(False)
One can then acquire the output signal on the output port with an oscilloscope, and verify that it corresponds to the expected output of the real sequencer mode, as shown below: