tk.HDAWG instrument drivers as in the previous example and setup and connect the device. Its device serial is
dev8030 and we connect via ethernet (
1gbe) to the host at
import numpy as np import matplotlib.pyplot as plt import qcodes as qc import zhinst.qcodes as ziqc hdawg = ziqc.HDAWG("hdawg1", "dev8138", interface="1gbe", host="10.42.0.226")
Successfully connected to data server at 10.42.0.2268004 api version: 6 Successfully connected to device DEV8138 on interface 1GBE Connected to: Zurich Instruments HDAWG (serial:dev8138, firmware:66245) in 1.25s
print([k for k in hdawg.submodules.keys()]) print([k for k in hdawg.parameters.keys()])
['awgs', 'stats', 'oscs', 'status', 'sines', 'dios', 'system', 'sigouts', 'triggers', 'features', 'cnts'] ['IDN', 'clockbase']
The HDAWG features eight AWG Channels grouped in four AWG Cores with two channels each. These four AWG Cores can be accessed through the
awgs submodule of the instrument driver.
awgs is a Channel List of four HDAWG-specific
AWGCore Instrument Channels. The
AWGCore handles the basic functionality to control the AWG Core and program its sequencer to play a specific series of waveforms and commands.
print([k for k in hdawg.awgs.parameters.keys()])
['outputs', 'output1', 'output2', 'gain1', 'gain2', 'modulation_phase_shift', 'modulation_freq']
An AWG Core features a list of
Parameters as well as methods that allow for a high-level control of the AWG Core. The Parameters control the channel outputs as well as their modulation settings.
For instance, the channel outputs can be turned on and off like this:
AWG output modulation¶
The output modulation for both channel outputs can be turned on with:
This method applies the corresponding settings for IQ Modulation using one of the internal oscillators and two sine generators. The sines are used to modulate the AWG output channels at a 90 degree phase difference. The parameters
gain2 correspond to the settings of the oscillator and the sine generators.
Node: oscs/0/freq Description: Sets the modulation frequency of the AWG output channels. Type: Double Properties: Read, Write Unit: Hz Parameter class: * `name` modulation_freq * `label` Modulation Frequency * `unit` Hz * `vals` <Numbers>
A simple sweep of the modulation frequency could look like this:
import time for f in np.linspace(10e6, 20e6, 21): hdawg.awgs.modulation_freq(f) # do something here time.sleep(0.1)
The AWG Core also holds a
SequenceProgram that defines the pulse sequence played by the AWG Sequencer. One of the next examples will describe how this sequence program is defined and how you can configure it to play the sequence of waveforms that you want to use.
Programming the AWG core¶
# turn the outputs on hdawg.awgs.output1("on") hdawg.awgs.output2("on")
All the parameters of the sequence program are set using
set_sequence_params(...) which lets the user pass keyword arguments. The most important ones are
sequence_type: the type of sequence to be programmed. The ‘Simple’ sequence type allows the user to upload their own sample-based waveforms which are played in a well defined sequence.
period: the period in seconds in which the single shots of the experiment should be repeated
repetitions: the number of repetitions of the sequence
hdawg.awgs.set_sequence_params( sequence_type="Simple", # let the user uplaod the sample-defined waveforms period=20e-6, # play the waveform every 20 us repetitions=1e3, # repeat 1000 times )
Because we are using the ‘Simple’ sequence type, we can define the waveforms as
numpy arrays. The waveform is defined by samples, which means that the timing calculation has to be taken care of by the user! For example the sampling rate of the HDAWG is 2.4 Gs, thus a waveform of 1000 samples correpsonds to a duration of
1000 / 2.4e9 = 416.6 ns.
We first reset the queue to ensure it is empty, then we add our waveform to the queue. The waveform is always defined for both channels of the AWG Core simultaneously.
wave1 = np.ones(1000) wave2 = -np.ones(1000) hdawg.awgs.reset_queue() # reset the queue hdawg.awgs.queue_waveform(wave1, wave2) # add the waveform to the queue # what is in the queue? hdawg.awgs.waveforms
Current length of queue: 1
[<zhinst.toolkit.helpers.waveform.Waveform at 0x2659aca3cf8>]
Next, we need to tell the AWG Core to compile the sequence program and to upload all the waveforms in the queue. The method
compile_and_upload_waveforms() takes care of both these jobs for the ‘Simple’ sequence (to ensure the correct sequence program is compiled before all the waveforms are uploaded).
hdawg.awgs.compile_and_upload_waveforms() # compile the sequence program and uplaod all waveforms in the queue
Compilation successful hdawg1-0: Sequencer status: ELF file uploaded Upload of 1 waveforms took 0.027058 s
Now we can run our seuqence program!
Compilation successful hdawg1-0: Sequencer status: ELF file uploaded
hdawg.awgs.run() # start the AWG Core! hdawg.awgs.wait_done() # wait until the AWG Core has finished playing the program
This program will output two rectangular pulses of length 1000 samples (416.6 ns) with amplitude 1 on channel 1 and amplitude -1 on channel 2. The waveforms are played every 20 us and are repeated 1000 times.