# AWG Module

The allows programmers to access the functionality available in the LabOne User Interface AWG tab. It allows users to compile and upload sequencer programs to the arbitrary waveform generator on UHF and HDAWG instruments from any of the LabOne APIs.

This chapter only explains the specifics for working with an AWG from an API; reference documentation of the LabOne AWG Sequencer Programming Language can be found in the UHF or HDAWG User Manual.

Figure 1. An AWG signal generated and measured using a UHFLI with the AWG Option. The waveform data was measured via a feedback cable using the UHF’s Scope. The plot was generated by the Python API example for the UHFLI, example_awg.py, which also generates the expected waveform and cross-correlates it with the measured waveform in order to overlay the expected signal on the measurement data.

## Getting Started with the AWG Module

The following API examples demonstrating AWG Module use are available:

• Matlab and Python, example_awg.{py,m}: Compiles and uploads an AWG sequencer program from a string. It demonstrates how to define waveforms using the four methods listed below in Methods to define Waveforms in Sequencer Programs. Separate versions of these examples are available for both UHF and HDAWG instruments.

• Matlab and Python, example_awg_sourcefile.{py,m}: Demonstrates how to compile and upload an AWG sequencer program from a .seqc file. Separate versions of these examples are available for both UHF and HDAWG instruments.

• LabVIEW, ziExample-UHFLI-Module-AWG.vi: Compiles and uploads an AWG sequencer program from a string and captures the generated waveform in the scope (UHF only).

• .NET, ExampleAwgModule() (in Examples.cs): Compiles and uploads an AWG sequencer program from a string. It demonstrates how to define waveforms using the four methods listed below in Methods to define Waveforms in Sequencer Programs.

• C API, ExampleAWGUpload.c: Demonstrates how to compile and upload an AWG sequencer program from a .seqc file.

## Sequencer Program Compilation and Upload

Programming an AWG with a sequencer program is a 2-step process. First, the source code must be compiled to a binary ELF file and secondly the ELF file must be uploaded from the PC to the AWG on the UHF or HDAWG instrument. Both steps are performed by an instance of the AWG Module regardless of whether the module is used in the API or the LabOne User Interface’s AWG Sequencer tab.

 Compilation An AWG sequencer program can be provided to the AWG module for compilation as either a: Source file: In this case the sequencer program file must reside in the "awg/src" sub-directory of the LabOne user directory. The filename (without full directory path) must be specified via the awgModule/compiler/sourcefile parameter and compilation is started when the in-out parameter awgModule/compiler/start is set to 1. String: A sequencer program may also be sent directly to the AWG Module as a string (comprising of a valid sequencer program) without the need to create a file on disk. The string is sent to the module by writing it to the awgModule/compiler/sourcestring using the module setString() function. In this case, compilation is started automatically after writing the source string.
 Upload If the awgModule/compiler/upload parameter is set to 1 the ELF file is automatically uploaded to the AWG after successful compilation. Otherwise, it must be uploaded by setting the in-out parameter awgModule/elf/upload to 1. A running AWG must be disabled first in order to upload a new sequencer program and it must be enabled again after upload.

## Methods to define Waveforms in Sequencer Programs

The waveforms played by an AWG sequencer program can be defined, or in the last case, modified, using the following four methods. These methods are demonstrated by the examples listed in Getting Started with the AWG Module.

1. By using one of the waveform generation functions such as sine(), sinc(), gauss(), etc. defined in the LabOne AWG Sequencer programming language. See the UHF, HDAWG or SHFSG User Manual for full reference documentation.

2. By defining a placeholder waveform and later loading the actual waveform from the API. This method is optimal, especially for long waveforms.[1]

3. By defining a waveform in a file, either with a floating point format in a CSV file, or a binary file.

### API vector transfer

The waveform must be first defined in the sequence, either as placeholder or as completely defined waveform with valid samples. In the first case, the compiler will only allocate the required memory and the waveform content is loaded later. The waveform definition must specify the length and eventual presence of markers. This should be respected later when the actual waveform is loaded.

The waveform can be loaded from the API using the setVector command to write waveform data the following nodes:

 UHF /DEV…​/AWGS/0/WAVEFORM/WAVES/ HDAWG /DEV…​/AWGS/[0-3]/WAVEFORM/WAVES/ SHFSG /DEV…​/SGCHANNELS/[0-7]/AWG/WAVEFORM/WAVES/ [2]

These nodes are the same regardless of the channel grouping mode on the HDAWG, so for example even when using the 1x8 mode on HDAWG8, waveforms are addressed separately for all 4 AWG cores. The assignment of a waveform to an index is done directly in the sequence program using the assignWaveIndex instruction.

As example

wave w = placeholder(WFM_SIZE);
assignWaveIndex(1,w, INDEX);

will allocate a waveform of WFM_SIZE at the index INDEX.

 Dual-channel waveforms Dual-channel waveform are effectively a single waveform, so there is only one index associated: wave w1 = placeholder(WFM_SIZE); wave w2 = placeholder(WFM_SIZE); assignWaveIndex(1,w1, 2,w2, INDEX);
 HDAWG grouped mode When the HDAWG is configured to work in grouped mode (all modes except 4x2 mode), see section HDAWG Channel Grouping, the waveforms for each AWG core are treated separately, even when they are played together. As in the 4x2 mode, waveforms can be either single- or dual-channel per core. As an example, this sequence //AWG CORE 1 wave w1 = placeholder(WFM_SIZE); wave w2 = placeholder(WFM_SIZE); assignWaveIndex(1,w1, 2,w2, INDEX1); //AWG CORE 2 wave w3 = placeholder(WFM_SIZE); assignWaveIndex(3,w3, INDEX2); //Playback playWave(1,w1, 2,w2, 3,w3); defines one dual-channel waveform on core 1, and one single-channel waveform on core 2. They can be loaded by writing their content to the nodes /DEV…​/AWGS/0/WAVEFORM/WAVES/ /DEV…​/AWGS/1/WAVEFORM/WAVES/

The waveform nodes use the internal raw format of the instrument and map the hardware capabilities of an AWG core. Thus, each waveform node can hold up to two analog waveforms and four markers. The length, number of waves and the presence of markers must be the same as defined in the sequence. An analog waveform is represented as array of signed int16. The markers are represented as array of int16, with the marker values defined in the four LSB; the other 12 bits must be zeros (see Figure 2).

wave_int16 = int16((1 << 15 - 1) * wave_float);
markers = int16(mk1_out1 * 1 << 0 + mk2_out1 * 1 << 1 +
mk1_out2 * 1 << 2 + mk2_out2 * 1 << 3);

If there is more than one analog waveform and/or markers, the arrays representing them must be interleaved; the order should be the first wave, then the second and finally the markers (see Figure 2).

Figure 2. Interleaving of waves and markers in AWG raw format

It’s convenient to use the helper Python functions zhinst.utils.convert_awg_waveform and zhinst.utils.parse_awg_waveform to write and read these nodes.

 The waveform nodes have the property SILENTWRITE. This means that subscribing to such a node has no effect, i.e. changes to the node will not be returned in poll. To obtain the contents of such nodes, getAsEvent has to be called followed by poll. For short vectors get may be used.

### File on disk

A waveform stored on the disk can be loaded from the sequence by referring to the file name without extension in the sequence program. For example

//Definition inline with playWave
playWave("wave_file");

//Assign first to a wave data type, then use
wave w = "wave_file";
playWave(w)

Two formats are supported, an CSV ASCII based and a binary one. The binary format should be preferred as it offers faster compilation than the CSV format. The waveform files must be located in the "awg/waveforms" sub-directory of the LabOne user directory (see explanation of awgModule/directory).

#### Binary

The binary format support only single-channel definition. To use dual-channel waveforms, two files holding single-channel waveform can be loaded separately:

wave w1 = 'wave1';
wave w2 = 'wave2';

playWave(1,w1, 2,w2);

The file must use the extension ".wave". Each sample is a word of 16 bits little-endian. The bits are assigned as follow:

• Bit 15-2: Wave, as 14 bit signed integer

• Bit 1: Marker 2

• Bit 0: Marker 1

As example, the waveform [-1.0, 0.0, 1.0], without marker will be saved as 04 80 00 00 FC 7F. The same waveform with marker1 [1,0,0] and marker2 [1,1,0] would be FD 7F 01 00 02 00.

Figure 3. Binary format of samples
 By default the AWG compiler loads in memory all the binary waveforms present in the directory. To achieve faster compilation, it’s advised to keep there only the required waveforms or to use the compiler/waveform.

#### ASCII CSV

As alternative to binary waveform, the ASCII CSV format can be used. The CSV file should contain floating-point values in the range from –1.0 to +1.0 and contain one or two columns, corresponding to the single- and dual-channel waveforms. The file must use the extension ".csv". As an example, the following specify a dual-channel wave with a length of 16 samples:

-1.0   0.0
-0.8   0.0
-0.7   0.1
-0.5   0.2
-0.2   0.3
-0.1   0.2
0.1   0.0
0.2  -0.1
0.7  -0.3
1.0  -0.2
0.9  -0.3
0.8  -0.2
0.4  -0.1
0.0  -0.1
-0.5  -0.1
-0.8   0.0

In order to obtain digital marker data from a file, specify a second wave file with integer instead of floating-point values. The marker bits are encoded in the binary representation of the integer (i.e., integer 1 corresponds to the first marker high, 2 corresponds to the second marker high, and 3 corresponds to both bits high). Later in the program add up the analog and the marker waveforms. For instance, if the floating-point analog data are contained in wave_file_analog.csv and the integer marker data in wave_file_digital.csv, the following code can be used to combine and play them.

wave w_analog  = "wave_file_analog";
wave w_digital = "wave_file_digital";
wave w = w_analog + w_digital;
playWave(w);

As an alternative to specifying analog data as floating-point values in one file, and marker data as integer values in a second file, both may be combined into one file containing integer values. The integer values in that file should be 18-bit unsigned integers with the two least significant bits being the markers. The values are mapped to 0 ⇒ -FS, 262143 ⇒ +FS, with FS equal to the full scale. This integer version of the CSV format is not to be confused with the binary file format documented previously. To optimize compilation speed, the binary format should be preferred over both versions of the CSV format.

## HDAWG Channel Grouping

This section explains how to configure the awgModule/index parameter and which AWGS node branch must be used for different channel grouping configurations. The channel grouping is defined by the value of the the node /DEV…​./SYSTEM/AWG/CHANNELGROUPING as follows:

0:

Use the outputs in groups of 2; each sequencer program controls 2 outputs. Each group n=0,1,2,3 of AWGs (respectively n=0,1 on HDAWG4 instruments) is configured by the /DEV…​./AWGS/n branches. Each of these 4 groups requires its own instance of the AWG Module and awgModule/index should be set to n=0,1,2,3 for each group accordingly.

1:

Use the outputs in groups of 4; each sequencer program controls 4 outputs. Each group n=0,1 of AWGs (respectively n=0 on HDAWG4 instruments) is configured by the /DEV…​./AWGS/0 and /DEV…​./AWGS/2 branches. Each of these two groups requires its own instance of the AWG Module and awgModule/index should be set to n=0,1 for each group accordingly. For HDAWG4 instruments, there is only one group of 4 outputs which is configured by the /DEV…​./AWGS/0 branch.

2:

HDAWG8 devices only. Use the outputs in a single group of 8; the (single) sequencer program controls 8 outputs. There is only one group (n=0) of 8 AWGs which is configured by the /DEV…​./AWGS/0 branch. Only one instance of the AWG Module is required and its value of awgModule/index should be 0.

Table 1. Overview of the device nodes and the value of awgModule/index used indifferent channel grouping configurations on HDAWG8 instruments.
Value of CHANNELGROUPING Number of Cores AWG Core Corresponding device AWG branch index Value of awgModule/index

0

4

1

/DEV…​./AWGS/0

0

2

/DEV…​./AWGS/1

1

3

/DEV…​./AWGS/2

2

4

/DEV…​./AWGS/3

3

1

2

1

/DEV…​./AWGS/0

0

2

/DEV…​./AWGS/2

1

2

1

1

/DEV…​./AWGS/0

0

Table 2. Overview of the device nodes and the value of awgModule/index used indifferent channel grouping configurations on HDAWG4 instruments.
Value of CHANNELGROUPING Number of Cores AWG Core Corresponding device AWG branch index Value of awgModule/index`

0

2

1

/DEV…​./AWGS/0

0

2

/DEV…​./AWGS/1

1

1

1

1

/DEV…​./AWGS/0

0

## AWG Module Node Tree

The following section contains reference documentation for the settings and measurement data available on the AWG module.

Since these settings and data streams may be written and read using the LabOne APIs (Application Programming Interfaces) this section is of particular interest to users who would like to perform measurements programmatically via LabVIEW, Python, MATLAB, .NET or C.

### awg

/awg/enable

 Properties: Read, Write Type: Integer (64 bit) Unit: None

Start the AWG sequencers. In MDS mode, this will enable all devices in the correct order.

### compiler

/compiler/sourcefile

 Properties: Read, Write Type: String Unit: None

The filename of an AWG sequencer program file to compile and load. The file must be located in the "awg/src" sub-directory of the LabOne user directory. This directory path is provided by the value of the read-only directory parameter.

/compiler/sourcestring

 Properties: Read, Write Type: String Unit: None

A string containing an AWG sequencer program may directly loaded to this parameter using the module command setString. This allows compilation and upload of a sequencer program without saving it to a file first. Compilation starts automatically after compiler/sourcestring has been set.

/compiler/start

 Properties: Read, Write Type: Integer (64 bit) Unit: None

Set to 1 to start compiling the AWG sequencer program specified by compiler/ sourcefile. The module sets compiler/ start to 0 once compilation has successfully completed (or failed). If compiler/upload is enabled then the sequencer program will additionally be uploaded to the AWG upon after successful compilation.

/compiler/status

 Properties: Read Type: Integer (enumerated) Unit: None

Compilation status

 -1 Idle. 0 Compilation successful. 1 Compilation failed. 2 Compilation completed with warnings.

/compiler/statusstring

 Properties: Read Type: String Unit: None

Status message of the compiler.

 Properties: Read, Write Type: Integer (64 bit) Unit: None

Specify whether the sequencer program should be automatically uploaded to the AWG following successful compilation.

/compiler/waveforms

 Properties: Read, Write Type: String Unit: None

A comma-separated list of waveform CSV files to be used by the AWG sequencer program.

### device

/device

 Properties: Read, Write Type: String Unit: None

The target device for AWG sequencer programs upload, e.g. 'dev2006'.

### directory

/directory

 Properties: Read, Write Type: String Unit: None

The path of the LabOne user directory. The AWG Module uses the following subdirectories in the LabOne web server directory: "awg/src": Contains AWG sequencer program source files (user created); "awg/elf": Contains compiled AWG binary (ELF) files (created by the module); "awg/waves": Contains CSV waveform files (user created).

### elf

/elf/checksum

 Properties: Read Type: Integer (64 bit) Unit: None

The checksum of the generated ELF file.

/elf/file

 Properties: Read, Write Type: String Unit: None

The filename of the compiled binary ELF file. If not set, the name is automatically set based on the source filename. The ELF file will be saved by the AWG Module in the "awg/elf" sub-directory of the LabOne user directory. This directory path is provided by the value of the read-only directory parameter.

/elf/status

 Properties: Read Type: Integer (enumerated) Unit: None

Status of the ELF file upload.

 Properties: Read, Write Type: Integer (64 bit) Unit: None

Set to 1 to start uploading the AWG sequencer program to the device. The module sets elf/upload to 0 once the upload has finished.

### index

/index

 Properties: Read, Write Type: Integer (64 bit) Unit: None

The index of the current AWG Module to use when running with multiple AWG groups. See section on channel grouping in the manual for further explanation.

### mds

/mds/group

 Properties: Read, Write Type: Integer (64 bit) Unit: None

The MDS group (multiDeviceSyncModule/group) to use for synchronized AWG playback.

### progress

/progress

 Properties: Read Type: Double Unit: None

Reports the progress of the upload as a value between 0 and 1.

1. The UHF platform is an exception and this method is on the contrary slower. However, since the waveform memory is limited, that should not be relevant for most of the practical purposes.
2. Only dual-channel waveforms