AWG Tab
The AWG tab is available on all SHFSG Signal Generator instruments.
Features
-
4- or 8-channel arbitrary waveform generator
-
98 kSa waveform memory per channel
-
Sequence branching
-
Digital modulation
-
Cross-domain trigger engine
-
Sequence Editor with code highlighting and auto completion
-
High-level programming language with waveform generation and editing toolset
-
Waveform viewer
Description
The AWG tab gives access to the arbitrary waveform generator functionality. Whenever the tab is closed or an additional one of the same type is needed, clicking the following icon will open a new instance of the tab.
Control/Tool | Option/Range | Description |
---|---|---|
AWG |
Generate arbitrary signals using sequencing and sample-by-sample definition of waveforms. |
The AWG tab (see Figure 1) consists of a settings section on the right side and the Sequence and Waveform Viewer sub-tabs on the left side. The settings section is further divided into Control, Waveform, Trigger, and Advanced sub-tabs. The Sequence sub-tab is used for displaying, editing and compiling a LabOne sequence program. The sequence program defines which waveforms are played and in which order. The Sequence Editor is the main tool for operating the AWG.

A number of sequence programming examples are available through a drop-down menu at the top of the Sequence Editor, and additional ones can be found in Tutorials . The LabOne sequence programming language is specified in detail in LabOne Sequence Programming. The language comes with a number of predefined waveforms, such as Gaussian, Blackman, sine, or square functions. By combining those predefined waveforms using the waveform editing tools (add, multiply, cut, concatenate, etc), signals with a high level of complexity can be generated directly from the Sequence Editor window. Sample-by-sample definition of the output signal is possible by using comma-separated value (CSV) files specified by the user .
The AWG features a compiler which translates the high-level sequence program into machine instructions and waveform data to be stored in the instrument memory as shown in Figure 2. The sequence program is written using high-level control structures and syntax that are inspired by human language, whereas machine instructions reflect exactly what happens on the hardware level. Writing the sequence program using a high-level language represents a more natural and efficient way of working in comparison to writing lists of machine instructions, which is the traditional way of programming AWGs. Concretely, the improvements rely on features such as:
-
combination of waveform generation, editing, and playback sequence in a single script
-
easily readable syntax and naming for run-time variables and constants
-
optimized waveform memory management, reduced transfers upon waveform changes
-
definition of user functions and procedures for advanced structuring
-
syntax validation
By design, there is no one-to-one link between the list of statements in the high-level language and the list of instructions executed by the Sequencer. In order to understand the execution timing, it’s helpful to consider the internal architecture of the AWG, consisting of the Sequencer itself, the Waveform Player, and the Waveform Memory.
The Sequence Editor provides the editing, compilation, and transfer functionality for sequence programs. A program typed into the Editor is compiled upon clicking . If the compilation is successful and Automatic Upload is enabled, the program including all necessary waveform data is transferred to the device. If the compilation fails, the Status field will display debug messages. Clicking on
allows you to choose a new name for the program. The name of the program that is currently edited is displayed at the top of the editor. External program files as well as waveform data files can be transferred to the right location easily using the file drag-and-drop zone in the Config Tab so they become accessible from the user interface. The files can be managed in the File Manager Tab and their location in the directory structure is shown in Table 2. The program name is displayed in a drop-down box. The box allows quick access to all programs in the standard sequence program location. It is possible to quickly switch between programs using the box. Changes made in one program will be preserved when switching to a different program. The file name of a program will be postfixed by an asterisk in case there are unsaved changes in the source file. Note that switching programs in the editor is not sufficient to also update the program in the instrument. In order to send a newly selected program to the instrument, the
button must be clicked.
File type | Location |
---|---|
Waveform files (Windows) |
|
Sequence programs (Windows) |
|
Waveform files (Linux) |
|
Sequence programs (Linux) |
|
In the Control sub-tab the user configures signal parameters and controls the execution of the AWG. The AWG can be started in by clicking on . When enabling the Rerun button, the Sequencer will be restarted automatically when its program completes. The continuous mode is a simple way to create an infinite loop, but it results in a considerable timing jitter. To avoid this jitter, it is recommended to specify infinite loops directly in the sequence program.
The Sampling Rate field is used to control the default playback sampling rate of the AWG. The sampling rate is dynamic, i.e., can be specified for each waveform by using an optional argument in the waveform playback instructions in the sequence program. This allows for considerably reducing waveform upload time for signals that contain both fast and slow components.
The Waveform sub-tab displays information about the waveforms that are used by the current sequence program, such as their length and channel number. Together with the Waveform viewer sub-tab, it is a useful tool to visualize the waveforms used in the sequence program.
On the Trigger sub-tab you can configure the trigger inputs of the AWG. Each AWG core has two internal trigger input channels which can be configured to probe any of the Trig inputs on the instrument front panel. The Advanced sub-tab displays the compiled list of sequencer instructions and the current state of the sequencer on the instrument. This can help an advanced user in debugging a sequence program and understanding its execution.
Sequence Editor Keyboard Shortcuts
The tables below list a number of helpful keyboard shortcuts that are applicable in the LabOne Sequence Editor.
Shortcut | Action |
---|---|
Ctrl-D |
Remove line |
Alt-Shift-Down |
Copy lines down |
Alt-Shift-Up |
Copy lines up |
Alt-Down |
Move lines down |
Alt-Up |
Move lines up |
Alt-Delete |
Remove to line end |
Alt-Backspace |
Remove to line start |
Ctrl-Backspace |
Remove word left |
Ctrl-Delete |
Remove word right |
Shortcut | Action |
---|---|
Ctrl-A |
Select all |
Shift-Left |
Select left |
Shift-Right |
Select right |
Ctrl-Shift-Left |
Select word left |
Ctrl-Shift-Right |
Select word right |
Shift-Home |
Select line start |
Shift-End |
Select line end |
Alt-Shift-Right |
Select to line end |
Alt-Shift-Left |
Select to line start |
Shift-Up |
Select up |
Shift-Down |
Select down |
Shift-PageUp |
Select page up |
Shift-PageDown |
Select page down |
Ctrl-Shift-Home |
Select to start |
Ctrl-Shift-End |
Select to end |
Ctrl-Shift-D |
Duplicate selection |
Ctrl-Shift-P |
Select to matching bracket |
Shortcut | Action |
---|---|
Left |
Go to left |
Right |
Go to right |
Ctrl-Left |
Go to word left |
Ctrl-Right |
Go to word right |
Up |
Go line up |
Down |
Go line down |
Alt-Left, Home |
Go to line start |
Alt-Right, End |
Go to line end |
PageUp |
Go to page up |
PageDown |
Go to page down |
Ctrl-Home |
Go to start |
Ctrl-End |
Go to end |
Ctrl-L |
Go to line |
Ctrl-Down |
Scroll line down |
Ctrl-Up |
Scroll line up |
Ctrl-P |
Go to matching bracket |
Shortcut | Action |
---|---|
Ctrl-F |
Find |
Ctrl-H |
Replace |
Ctrl-K |
Find next |
Ctrl-Shift-K |
Find previous |
Shortcut | Action |
---|---|
Alt-L |
Fold selection |
Alt-Shift-L |
Unfold |
Shortcut | Action |
---|---|
Tab |
Indent |
Shift-Tab |
Outdent |
Ctrl-Z |
Undo |
Ctrl-Shift-Z,Ctrl-Y |
Redo |
Ctrl-/ |
Toggle comment |
Ctrl-Shift-U |
Change to lower case |
Ctrl-U |
Change to upper case |
Insert |
Overwrite |
Ctrl-Shift-E |
Macros replay |
Ctrl-Alt-E |
Macros recording |
Delete |
Delete |
LabOne Sequence Programming
A Simple Example
The syntax of the LabOne AWG Sequencer programming language is based on C, but with a few simplifications. Each statement is concluded with a semicolon, several statements can be grouped with curly brackets, and comment lines are identified with a double slash. The following example shows some of the fundamental functionalities: waveform generation, repeated playback, triggering, and single/dual-channel waveform playback. See Tutorials for a step-by-step introduction with more examples.
// Define an integer constant const N = 4096; // Create two Gaussian pulses with length N points, // amplitude +1.0 (-1.0), center at N/2, and a width of N/8 wave gauss_pos = 1.0*gauss(N, N/2, N/8); wave gauss_neg = -1.0*gauss(N, N/2, N/8); // execute playback sequence 100 times repeat (100) { // Play pulse on AWG channel 1 playWave(gauss_pos); // Play pulses simultaneously on both AWG channels playWave(gauss_pos, gauss_neg); }
Keywords and Comments
The following table lists the keywords used in the LabOne AWG Sequencer language.
Keyword | Description |
---|---|
|
Constant declaration |
|
Integer variable declaration |
|
Compile-time variable declaration |
|
Constant string declaration |
|
Boolean true constant |
|
Boolean false constant |
|
For-loop declaration |
|
While-loop declaration |
|
Repeat-loop declaration |
|
If-statement |
|
Else-part of an if-statement |
|
Switch-statement |
|
Case-statement within a switch |
|
Default-statement within a switch |
|
Return from function or procedure, optionally with a return value |
The following code example shows how to use comments.
const a = 10; // This is a line comment. Everything between the double // slash and the end of the line will be ignored. /* This is a block comment. Everything between the start-of-block-comment and end-of-block-comment markers is ignored. For example, the following statement will be ignored by the compiler. const b = 100; */
Constants and Variables
Constants may be used to make the program more readable. They may be of integer or floating-point type. It must be possible for the compiler to compute the value of a constant at compile time, i.e., on the host computer. Constants are declared using the const
keyword.
Compile-time variables may be used in computations and loop iterations during compile time, e.g. to create large numbers of waveforms in a loop. They may be of integer or floating-point type. They are used in a similar way as constants, except that they can change their value during compile time operations. Compile-time variables are declared using the cvar
keyword.
Variables may be used for making simple computations during run time, i.e., on the instrument. The Sequencer supports integer variables, addition, and subtraction. Not supported are floating-point variables, multiplication, and division. Typical uses of variables are to step waiting times
or to tag digital measurement data with a numerical identifier. Variables are declared using the var
keyword.
The following code example shows how to use variables.
var b = 100; // Create and initialize a variable // Repeat the following block of statements 100 times repeat (100) { b = b + 1; // Increment b wait(b); // Wait 'b' cycles }
The following table shows the predefined constants. These constants are intended to be used as arguments in certain run-time evaluated functions that encode device parameters with integer numbers. For example, the AWG Sampling Rate is specified as an integer exponent n in the expression (baseSamplingClock)/2n. The AWG rates constants are specified for the sampling clock of 2.0 GHz of the SHFSG.
Name | Value | Description |
---|---|---|
commandTableEntries |
{4096} |
|
AWG_RATE_2000MHZ |
0 |
Constant to set Sampling Rate to 2.0 GHz. |
AWG_RATE_1000MHZ |
1 |
Constant to set Sampling Rate to 1.0 GHz. |
AWG_RATE_500MHZ |
2 |
Constant to set Sampling Rate to 500 MHz. |
AWG_RATE_250MHZ |
3 |
Constant to set Sampling Rate to 250 MHz. |
AWG_RATE_125MHZ |
4 |
Constant to set Sampling Rate to 125 MHz. |
AWG_RATE_62P5MHZ |
5 |
Constant to set Sampling Rate to 62.5 MHz. |
AWG_RATE_31P25MHZ |
6 |
Constant to set Sampling Rate to 31.25 MHz. |
AWG_RATE_15P63MHZ |
7 |
Constant to set Sampling Rate to 15.63 MHz. |
AWG_RATE_7P81MHZ |
8 |
Constant to set Sampling Rate to 7.81 MHz. |
AWG_RATE_3P9MHZ |
9 |
Constant to set Sampling Rate to 3.9 MHz. |
AWG_RATE_1P95MHZ |
10 |
Constant to set Sampling Rate to 1.95 MHz. |
AWG_RATE_976KHZ |
11 |
Constant to set Sampling Rate to 976 kHz. |
AWG_RATE_488KHZ |
12 |
Constant to set Sampling Rate to 488 kHz. |
AWG_RATE_244KHZ |
13 |
Constant to set Sampling Rate to 244 kHz. |
DEVICE_SAMPLE_RATE |
<actual device sample rate> |
|
ZSYNC_DATA_RAW |
commandTableEntries + 0 |
Constant to use as argument to getZSyncData/getFeedback. Return the data received on the ZSync as-is without parsing. |
ZSYNC_DATA_PQSC_REGISTER |
commandTableEntries + 1 |
Constant to use as argument to getZSyncData/getFeedback. Get last readout register forwarded by the PQSC. |
ZSYNC_DATA_PQSC_DECODER |
commandTableEntries + 2 |
Constant to use as argument to getZSyncData/getFeedback. Get last output of the decoder received from the PQSC. |
AWG_CHAN1 |
1 |
Constant to select channel 1. |
AWG_CHAN2 |
2 |
Constant to select channel 2. |
AWG_MARKER1 |
1 |
Constant to select marker 1. |
AWG_MARKER2 |
2 |
Constant to select marker 2. |
AWG_OSC_PHASE_START |
1 |
Constant to trigger the oscillator phase on the positive edge. |
AWG_OSC_PHASE_MIDDLE |
0 |
Constant to trigger the oscillator phase on the negative edge. |
AWG_USERREG_SWEEP_COUNT0 |
35 |
Constant for the sweep count register 0. |
AWG_USERREG_SWEEP_COUNT1 |
36 |
Constant for the sweep count register 1. |
Numbers can be expressed using either of the following formatting.
const a = 10; // Integer notation const b = -10; // Negative number const h = 0xdeadbeef; // Hexadecimal integer const bin = 0b10101; // Binary integer const f = 0.1e-3; // Floating point number. const not_float = 10e3; // Not a floating point number
Booleans are specified with the keywords true
and false
. Furthermore, all numbers that evaluate to a nonzero value are considered true. All numbers that evaluate to zero are considered false.
Strings are delimited using "" and are interpreted as constants. Strings may be concatenated using the + operator.
string AWG_PATH = "awgs/0/"; string AWG_GAIN_PATH = AWG_PATH + "gains/0";
Waveform Generation and Editing
The following table contains the definition of functions for waveform generation.
resulting waveform
wave zeros(const samples)
samples:
Number of samples in the waveform
resulting waveform
wave ones(const samples)
samples:
Number of samples in the waveform
resulting waveform
wave sine(const samples, const amplitude=1.0, const phaseOffset, const nrOfPeriods)
amplitude:
Amplitude of the signal (optional)nrOfPeriods:
Number of Periods within the defined number of samplesphaseOffset:
Phase offset of the signal in radianssamples:
Number of samples in the waveform
resulting waveform
wave cosine(const samples, const amplitude=1.0, const phaseOffset, const nrOfPeriods)
amplitude:
Amplitude of the signal (optional)nrOfPeriods:
Number of Periods within the defined number of samplesphaseOffset:
Phase offset of the signal in radianssamples:
Number of samples in the waveform
resulting waveform
wave sinc(const samples, const amplitude=1.0, const position, const beta)
amplitude:
Amplitude of the signal (optional)beta:
Width of the functionposition:
Peak position of the functionsamples:
Number of samples in the waveform
resulting waveform
wave ramp(const samples, const startLevel, const endLevel)
endLevel:
level at the last sample of the waveformsamples:
Number of samples in the waveformstartLevel:
level at the first sample of the waveform
resulting waveform
wave sawtooth(const samples, const amplitude=1.0, const phaseOffset, const nrOfPeriods)
amplitude:
Amplitude of the signalnrOfPeriods:
Number of Periods within the defined number of samplesphaseOffset:
Phase offset of the signal in radianssamples:
Number of samples in the waveform
resulting waveform
wave triangle(const samples, const amplitude=1.0, const phaseOffset, const nrOfPeriods)
amplitude:
Amplitude of the signalnrOfPeriods:
Number of Periods within the defined number of samplesphaseOffset:
Phase offset of the signal in radianssamples:
Number of samples in the waveform
resulting waveform
wave gauss(const samples, const amplitude=1.0, const position, const width)
amplitude:
Amplitude of the signal (optional)position:
Peak position of the pulsesamples:
Number of samples in the waveformwidth:
Width of the pulse
resulting waveform
wave drag(const samples, const amplitude=1.0, const position, const width)
amplitude:
Amplitude of the signal (optional)position:
Center point position of the pulsesamples:
Number of samples in the waveformwidth:
Width of the pulse
resulting waveform
wave blackman(const samples, const amplitude=1.0, const alpha)
alpha:
Width of the functionamplitude:
Amplitude of the signal (optional)samples:
Number of samples in the waveform
resulting waveform
wave hamming(const samples, const amplitude=1.0)
amplitude:
Amplitude of the signal (optional)samples:
Number of samples in the waveform
resulting waveform
wave hann(const samples, const amplitude=1.0)
amplitude:
Amplitude of the signalsamples:
Number of samples in the waveform
resulting waveform
wave rect(const samples, const amplitude)
amplitude:
Amplitude of the signalsamples:
Number of samples in the waveform
resulting waveform
wave marker(const samples, const markerValue)
markerValue:
Value of the marker bitssamples:
Number of samples in the waveform
resulting waveform
wave rand(const samples, const amplitude=1.0, const mean, const stdDev)
amplitude:
Amplitude of the signalmean:
Average signal levelsamples:
Number of samples in the waveformstdDev:
Standard deviation of the noise signal
resulting waveform
wave randomGauss(const samples, const amplitude=1.0, const mean, const stdDev)
amplitude:
Amplitude of the signalmean:
Average signal levelsamples:
Number of samples in the waveformstdDev:
Standard deviation of the noise signal
resulting waveform
wave randomUniform(const samples, const amplitude=1.0)
amplitude:
Amplitude of the signalsamples:
Number of samples in the waveform
resulting waveform
wave lfsrGaloisMarker(const samples, const markerBit, const polynomial, const initial)
initial:
LFSR initial state, any nonzero value will work, usually 0x1markerBit:
Marker bit to set (1 or 2)polynomial:
LFSR characteristic polynomial in binary representation (max shift length 32), use 0x90000 for QRSS / PRBS-20samples:
Number of samples in the waveform
resulting waveform
wave chirp(const samples, const amplitude=1.0, const startFreq, const stopFreq, const phase=0)
amplitude:
Amplitude of the signal (optional)phase:
Initial phase of the signal (optional)samples:
Number of samples in the waveformstartFreq:
Start frequency of the signalstopFreq:
Stop Frequency of the signal
Resulting waveform
wave rrc(const samples, const amplitude=1.0, const position, const beta, const width)
amplitude:
Amplitude of the signalbeta:
Roll-off factorposition:
Center point position of the pulsesamples:
Number of samples in the waveformwidth:
Width of the pulse
resulting waveform
wave vect(const value,…)
value:
Waveform amplitude at the respective sample
waveform object
wave placeholder(const samples, const marker0=false, const marker1=false)
marker0:
true if marker bit 0 must be used (default false)marker1:
true if marker bit 1 must be used (default false)samples:
Number of samples in the waveform
The following table contains the definition of functions for waveform editing.
joined waveform
wave join(wave wave1, wave wave2, const interpolLength=0)
interpolLength:
Number of samples to interpolate between waveforms (optional, default 0)wave1:
Input waveformwave2:
Input waveform
joined waveform
wave join(wave wave1, wave wave2,…)
wave1:
Input waveformwave2:
Input waveform
interleaved waveform
wave interleave(wave wave1, wave wave2,…)
wave1:
Input waveformwave2:
Input waveform
sum waveform
wave add(wave wave1, wave wave2,…)
wave1:
Input waveformwave2:
Input waveform
product waveform
wave multiply(wave wave1, wave wave2,…)
wave1:
Input waveformwave2:
Input waveform
scaled waveform
wave scale(wave waveform, const factor)
factor:
Scaling factorwaveform:
Input waveform
flipped waveform
wave flip(wave waveform)
waveform:
Input waveform
cut waveform
wave cut(wave waveform, const from, const to)
from:
First sample of the cut waveformto:
Last sample of the cut waveformwaveform:
Input waveform
filtered waveform
wave filter(wave b, wave a, wave x)
a:
Denominator coefficientsb:
Numerator coefficientsx:
Input waveform
circularly shifted waveform
wave circshift(wave a, const n)
n:
Number of elements to shiftwaveform:
Input waveform
Waveform Playback and Predefined Functions
The following table contains the definition of functions for waveform playback and other purposes.
The value can be either a const or a var value. Configure the Mode setting in the DIO tab when using this command. The DIO interface speed of 50 MHz limits the rate at which the DIO output value is updated.
void setDIO(var value)
value:
The value to write to the DIO (const or var)
var containing the read value
var getDIO()
var containing the read value
var getDIOTriggered()
The state of all four AWG Trigger output signals is represented by the bits in the binary representation of the integer value. Binary notation of the form 0b0000 is recommended for readability.
void setTrigger(var value)
value:
to be written to the trigger output lines
Note: the minimum waiting time amounts to 3 cycles, which means that wait(0) and wait(1) will both result in a waiting time of 3 * 4 ns = 12 ns.
void wait(var cycles)
cycles:
number of cycles to wait
void waitTrigger(const mask, const value)
mask:
mask to be applied to the input signalvalue:
value to be compared with the trigger input
void waitDIOTrigger()
The physical signal connected to the AWG Digital Trigger input is to be configured in the Trigger sub-tab of the AWG tab. trigger state, either 0 or 1
var getDigTrigger(const index)
index:
index of the Digital Trigger input to be read; can be either 1 or 2
void error(string msg,…)
msg:
Message to be displayed
void info(string msg,…)
msg:
Message to be displayed
void waitWave()
void setRate(const rate)
rate:
New default sampling rate
void randomSeed()
void assignWaveIndex(const output, wave waveform, const index)
index:
index to assignoutput:
defines on which output the following waveform to be playedwaveform:
waveform to be played
void assignWaveIndex(wave waveform, const index)
index:
index to assignwaveform:
waveform to be played
void playWave(const output, wave waveform, const rate=AWG_RATE_DEFAULT)
output:
defines on which output the following waveform is playedrate:
sample rate with which the AWG plays the waveforms (default set in the user interface).waveform:
waveform to be played
void playWave(const output, wave waveform,…)
output:
defines on which output the following waveform is playedwaveform:
waveform to be played
void playWave(wave waveform, const rate=AWG_RATE_DEFAULT)
rate:
sample rate with which the AWG plays the waveforms (default set in the user interface).waveform:
waveform to be played
void playWave(wave waveform,…)
waveform:
waveform to be played
The User Registers may be used for communicating information to the LabOne User Interface or a running API program.
void setUserReg(const register, var value)
register:
The register index (0 to 15) to be written tovalue:
The integer value to be written
current register value
var getUserReg(const register)
register:
The register to be read (0 to 15)
void playZero(var samples)
samples:
Number of samples to be played. The same min length and granularity applies as for regular waveforms.
void playZero(var samples, const rate)
rate:
Sample rate with which the AWG plays zeros (default set in the user interface).samples:
Number of samples to be played. The same min length and granularity applies as for regular waveforms.
void waitDigTrigger(const index)
index:
Index of the digital trigger input; can be either 1 or 2.
void executeTableEntry(var index)
data_type:
ZSYNC_DATA_RAW: The raw ZSYNC data is the table entry to execute ZSYNC_DATA_PQSC_REGISTER: The last readout register forwarded by the PQSC is the table entry to execute ZSYNC_DATA_PQSC_DECODER: The last output of the decoder received from the PQSC is the table entry to executeindex:
table entry that shall be executedwait_cycles:
Wait for the specified number of cycles after the most recent waitZSyncTrigger() or waitDigTrigger() instruction
The seed is a 16 bit unsigned int value. Zero is invalid as seed.
void setPRNGSeed(var value)
value:
seed value to be configured
Random value rand
var getPRNGValue()
void setPRNGRange(var lower, var upper)
lower:
lower bound of range, 0 … 2**16-1upper:
upper bound of range, 0 … 2**16-1
void setSinePhase(const phase)
phase:
Phase value [degree]
void incrementSinePhase(const phase)
phase:
Phase value [degree]
void resetOscPhase(const mask, const reset_digital_mixer)
mask:
one-hot encoding to reset phase of individual oscillatorsreset_digital_mixer:
reset the digital mixer phase if true
void resetOscPhase(const mask)
void resetOscPhase()
void playHold(var samples)
samples:
Number of samples to be played. The same min length and granularity applies as for regular waveforms.
void playHold(var samples, const rate)
rate:
Sample rate with which the AWG plays zeros (default set in the user interface).samples:
Number of samples to be played. The same min length and granularity applies as for regular waveforms.
void playWaveDIO()
void waitSineOscPhase()
void configFreqSweep(const oscillator_index, const freq_start, const freq_increment)
freq_increment:
Specify how much to increment the frequency for each step of the sweep [Hz]freq_start:
Specify the start frequency value for the sweep [Hz]oscillator_index:
Index of the oscillator that will be used for the sweep
void setSweepStep(const oscillator_index, var sweep_index)
oscillator_index:
Index of the oscillator that will be used for the sweepsweep_index:
Sets the step index, from which the frequency is set
void setOscFreq(const oscillator_index, const freq)
freq:
Frequency to be set [Hz]oscillator_index:
Index of oscillator
var containing the read value
var getZSyncData(const data_type)
data_type:
Specifies which data the function should return: ZSYNC_DATA_RAW: Return the data received on the ZSync as-is without parsing. The structure of the message can change across different LabOne releases. ZSYNC_DATA_PQSC_REGISTER: Get last readout register forwarded by the PQSC ZSYNC_DATA_PQSC_DECODER: Get last output of the decoder received from the PQSC.wait_cycles:
Wait for the specified number of cycles after the most recent waitZSyncTrigger() instruction
var getZSyncData(const data_type, var wait_cycles)
var containing the read value
var getFeedback(const data_type)
data_type:
Specifies which data the function should return: ZSYNC_DATA_RAW: Return the data received on the ZSync as-is without parsing. The structure of the message can change across different LabOne releases. ZSYNC_DATA_PQSC_REGISTER: Get last readout register forwarded by the PQSC ZSYNC_DATA_PQSC_DECODER: Get last output of the decoder received from the PQSC.wait_cycles:
Wait for the specified number of cycles after the most recent waitZSyncTrigger() instruction
var getFeedback(const data_type, var wait_cycles)
void playWaveZSync(const data_type)
void playWaveZSync(const data_type, var wait_cycles)
void waitZSyncTrigger()
void resetRTLoggerTimestamp()
Expressions
Expressions may be used for making computations based on mathematical functions and operators. There are two kinds of expressions: those evaluated at compile time (the moment of clicking "Save" or "Save as…" in the user interface), and those evaluated at run time (after clicking "Run/Stop" or "Start"). Compile-time evaluated expressions only involve constants (const
) or compile-time variables (cvar
) and can be computed at compile time by the host computer. Such expressions can make use of standard mathematical functions and floating point arithmetic. Run-time evaluated expressions involve variables (var
) and are evaluated by the Sequencer on the instrument. Due to the limited computational capabilities of the Sequencer, these expressions may only operate on integer numbers and there are less operators available than at compile time.
The following table contains the list of mathematical functions supported at compile time.
Function | Description |
---|---|
const abs(const c) |
absolute value |
const acos(const c) |
inverse cosine |
const acosh(const c) |
hyperbolic inverse cosine |
const asin(const c) |
inverse sine |
const asinh(const c) |
hyperbolic inverse sine |
const atan(const c) |
inverse tangent |
const atanh(const c) |
hyperbolic inverse tangent |
const cos(const c) |
cosine |
const cosh(const c) |
hyperbolic cosine |
const exp(const c) |
exponential function |
const ln(const c) |
logarithm to base e (2.71828…) |
const log(const c) |
logarithm to the base 10 |
const log2(const c) |
logarithm to the base 2 |
const log10(const c) |
logarithm to the base 10 |
const sign(const c) |
sign function -1 if x<0; 1 if x>0 |
const sin(const c) |
sine |
const sinh(const c) |
hyperbolic sine |
const sqrt(const c) |
square root |
const tan(const c) |
tangent |
const tanh(const c) |
hyperbolic tangent |
const ceil(const c) |
smallest integer value not less than the argument |
const round(const c) |
round to nearest integer |
const floor(const c) |
largest integer value not greater than the argument |
const avg(const c1, const c2,…) |
mean value of all arguments |
const max(const c1, const c2,…) |
maximum of all arguments |
const min(const c1, const c2,…) |
minimum of all arguments |
const pow(const base, const exp) |
first argument raised to the power of second argument |
const sum(const c1, const c2,…) |
sum of all arguments |
The following table contains the list of predefined mathematical constants. These can be used for convenience in compile-time evaluated expressions.
Name | Value | Description |
---|---|---|
M_E |
2.71828182845904523536028747135266250 |
e |
M_LOG2E |
1.44269504088896340735992468100189214 |
log2(e) |
M_LOG10E |
0.434294481903251827651128918916605082 |
log10(e) |
M_LN2 |
0.693147180559945309417232121458176568 |
loge(2) |
M_LN10 |
2.30258509299404568401799145468436421 |
loge(10) |
M_PI |
3.14159265358979323846264338327950288 |
pi |
M_PI_2 |
1.57079632679489661923132169163975144 |
pi/2 |
M_PI_4 |
0.785398163397448309615660845819875721 |
pi/4 |
M_1_PI |
0.318309886183790671537767526745028724 |
1/pi |
M_2_PI |
0.636619772367581343075535053490057448 |
2/pi |
M_2_SQRTPI |
1.12837916709551257389615890312154517 |
2/sqrt(pi) |
M_SQRT2 |
1.41421356237309504880168872420969808 |
sqrt(2) |
M_SQRT1_2 |
0.707106781186547524400844362104849039 |
1/sqrt(2) |
Operator | Description | Priority |
---|---|---|
|
assignment |
-1 |
|
assignment by sum, difference, product, quotient, remainder, AND, OR, left shift, and right shift |
-1 |
|
logical OR |
1 |
|
logical AND |
2 |
|
bit-wise logical OR |
3 |
|
bit-wise logical AND |
4 |
|
not equal |
5 |
|
equal |
5 |
|
less or equal |
6 |
|
greater or equal |
6 |
|
greater than |
6 |
|
less than |
6 |
|
arithmetic left bit shift |
7 |
|
arithmetic right bit shift |
7 |
|
addition |
8 |
|
subtraction |
8 |
|
multiplication |
9 |
|
division |
9 |
|
bit-wise logical negation |
10 |
Operator | Description | Priority |
---|---|---|
|
assignment |
-1 |
|
assignment by sum, difference, product, quotient, remainder, AND, OR, left shift, and right shift |
-1 |
|
logical OR |
1 |
|
logical AND |
2 |
|
bit-wise logical OR |
3 |
|
bit-wise logical AND |
4 |
|
equal |
5 |
|
not equal |
5 |
|
less or equal |
6 |
|
greater or equal |
6 |
|
greater than |
6 |
|
less than |
6 |
|
left bit shift |
7 |
|
right bit shift |
7 |
|
addition |
8 |
|
subtraction |
8 |
|
bit-wise logical negation |
9 |
Control Structures
Functions may be declared using the var
keyword. Procedures may be declared using the void
keyword. Functions must return a value, which should be specified using the return
keyword. Procedures can not return values. Functions and procedures may be declared with an arbitrary number of arguments. The return
keyword may also be used without arguments to return from an arbitrary point within the function or procedure. Functions and procedures may contain variable and constant declarations. These declarations are local to the scope of the function or procedure.
var function_name(argument1, argument2, ...) { // Statements to be executed as part of the function. return constant-or-variable; } void procedure_name(argument1, argument2, ...) { // Statements to be executed as part of the procedure. // Optional return statement return; }
An if-then-else structure is used to create a conditional branching point in a sequencer program.
// If-then-else statement syntax if (expression) { // Statements to execute if 'expression' evaluates to 'true'. } else { // Statements to execute if 'expression' evaluates to 'false'. } // If-then-else statement short syntax (expression)?(statement if true):(statement if false)
// If-then-else statement example const REQUEST_BIT = 0x0001; const ACKNOWLEDGE_BIT = 0x0002; const IDLE_BIT = 0x8000; var dio = getDIO(); if (dio & REQUEST_BIT) { dio = dio | ACKNOWLEDGE_BIT; setDIO(dio); } else { dio = dio | IDLE_BIT; setDIO(dio); }
A switch-case structure serves to define a conditional branching point similarly to the if-then-else
statement, but is used to split the sequencer thread into more than two branches. Unlike the if-then-else
structure, the switch statement is synchronous, which means that the execution time is the same for all branches and determined by the execution time of the longest branch. If no default case is provided and no case matches the condition, all cases will be skipped. The case arguments need to be of type const
.
// Switch-case statement syntax switch (expression) { case const-expression: expression; ... default: expression; }
// Switch-case statement example switch (getDIO()) { case 0: playWave(gauss(1024,1.0,512,64)); case 1: playWave(gauss(1024,1.0,512,128)); case 2: playWave(drag(1024,1.0,512,64)); default: playWave(drag(1024,1.0,512,128)); }
The for loop is used to iterate through a code block several times. The initialization
statement is executed before the loop starts. The end-expression
is evaluated at the start of each iteration and determines when the loop should stop. The loop is executed as long as this expression is true. The iteration-expression
is executed at the end of each loop iteration.
Depending on how the for
loop is set up, it can be either evaluated at compile time or at run time. Run-time evaluation is typically used to play series of waveforms. Compile-time evaluation is typically used for advanced waveform generation, e.g. to generate a series of waveforms with varying amplitude. For a run-time evaluated for
loop, use the var
data type as a loop index. To ensure that a loop is evaluated at compile time, use the cvar
data type as a loop index. Furthermore, the compile-time for
loop should only contain waveform generation/editing operations and it can’t contain any variables of type var
. The following code example shows both versions of the loop.
// For loop syntax for (initialization; end-expression; iteration-expression) { // Statements to execute while end-expression evaluates to true }
// FOR loop example to assemble a train of pulses into // a single waveform (compile-time execution) cvar gain_factor; // CVAR: integer or float values allowed wave w_pulse_series; for (gain_factor = 0; gain_factor < 1.0; gain_factor = gain_factor + 0.1) { w_pulse_series = join(w_pulse_series, gain_factor*gauss(1008, 504, 100)); } // Playback of waveform defined using compile-time FOR loop playWave(w_pulse_series); // FOR loop example to vary waiting time between // waveform playbacks (run-time execution) var i; // VAR: integer values allowed for (i = 0; i < 1000; i = i + 100) { playWave(gauss(1008, 504, 100)); waitWave(); wait(i); }
The while loop is a simplified version of the for
loop. The end-expression
is evaluated at the start of each loop iteration. The contents of the loop are executed as long as this expression is true. Like the for
loop, this loop comes in a compile-time version (if the end-expression involves only cvar
and const
) and in a run-time version (if the end-expression involves also var
data types).
// While loop syntax while (end-expression) { // Statements to execute while end-expression evaluates to true }
// While loop example const STOP_BIT = 0x8000; var run = 1; var i = 0; var dio = 0; while (run) { dio = getDIO(); run = dio & STOP_BIT; dio = dio | (i & 0xff); setDIO(dio); i = i + 1; }
The repeat loop is a simplified version of the for
loop. It repeats the contents of the loop a fixed number of times. In contrast to the for
loop, the repetition number of the repeat
loop must be known at compile time, i.e., const-expression
can only depend on constants and not on variables. Unlike the for
and the while
loop, this loop comes only in a run-time version. Thus, no cvar
data types may be modified in the loop body.
// Repeat loop syntax repeat (constant-expression) { // Statements to execute }
// Repeat loop example repeat (100) { setDIO(0x1); wait(10); setDIO(0x0); wait(10); }
Usage of playZero and playHold commands
The functionalities of playHold
and playZero
are both available either through sequencer commands or through the command table. To use within a sequence, only the length in samples must be specified, as in playHold(32)
or playZero(128)
. The sequencer commands also accept a sampling rate as a second optional argument, which reduces the sampling rate only for the duration of the command. For example,
To use playZero
or playHold
within the command table, a command table entry must be made. See
Pulse-level Sequencing with the Command Table
for more information on using playZero
within the command table. Similar syntax applies for using playHold
within the command table. The table entries can be used within a sequence by adding the appropriate executeTableEntry
command to the sequencer code.
Depending on the experiment being performed, it can make sense to use the playZero
sequencer command in some cases and the command table version in other cases (and similarly for playHold
). Generally speaking, the sequencer commands should be used when the length is variable, when the length is 2^20 - 1 or fewer samples, or when the optional sampling rate argument is used. When using a variable argument, such as when performing a sweep of the evolution time between two pulses with playZero
or of the length of a pulse with playHold
(see Characterizing a Two-Qubit System)
, the sequencer command must be used, as the playZero
and playHold
functionality within the command table cannot support variable arguments. A similar restriction applies to the optional sampling rate argument.
When the length is 2^20 - 1 or fewer samples, the sequencer commands map to a single assembly instruction. Once the length is more than or equal to 2^20 samples, however, the sequencer commands map to at least two assembly instructions instead. Additionally, when using the optional sampling rate divider argument of the sequencer commands, playZero
and playHold
always map to at least three assembly instructions, regardless of the length in samples. When using the command table to perform playZero or `playHold
functionality, the corresponding executeTableEntry
command always maps to a single assembly instruction, regardless of the length of the playZero
or playHold
, at the cost of using a command table entry.
Using Qubit Feedback Data in a Sequence
The AWG can make decisions depending on the feedback data received over ZSync
. There are two primary ways to use the feedback data received: by using the command getFeedback
and storing the result in a variable, or by using the feedback data directly as the argument of executeTableEntry
. To directly make decisions about which pulse to play, it is recommended to use the feedback arguments of the executeTableEntry
. For example, active reset in which the qubit data is passed to an SG Channel over a ZSync connection to a PQSC could involve a snippet of code like the following:
waitZSyncTrigger();
executeTableEntry(ZSYNC_DATA_PQSC_REGISTER, feedback_time);
The first argument determines which command table entry should be played, and the second argument accounts for the time between when the ZSync trigger is received and when the updated qubit readout data is available for use. The exact value of feedback_time
(specified in number of sequencer clock cycles) depends on the combination of equipment being used as well as the experiment being performed and must be characterized by the user. For this example, the command table has been defined to play no pulse if the appropriate bit of ZSYNC_DATA_PQSC_REGISTER
is 0 or to play a pi-pulse if the appropriate bit of ZSYNC_DATA_RAW
is 1:
# Qubit was in state 0
table[0].waveform.playZero = True
table[0].waveform.length = PI_PULSE_LENGTH
# Qubit was in state 1
table[1].waveform.index = 0
table[1].amplitude00.value = PI_AMPLITUDE
table[1].amplitude01.value = -PI_AMPLITUDE
table[1].amplitude10.value = PI_AMPLITUDE
table[1].amplitude11.value = PI_AMPLITUDE
To use ZSYNC_DATA_PQSC_REGISTER
, it is additionally necessary to configure the appropriate shift, mask, and offset values of the corresponding SG Channel sequencer.
In other cases, storing the results of getFeedback
in a variable is the recommended route. For example, repeat until success requires repeated checking of the qubit readout data, but does not require a pulse to be played until the success criterion is met. Such an experiment might include sequencer code snippet like the following:
waitZSyncTrigger();
do {
// preceding code
failure = getFeedback(ZSYNC_DATA_PQSC_DECODER, feedback_time); // check for failure
// following code
} while (failure)
// Success pulse
playWave(1, 2, w_success);
The success pulse is played only once the success condition has been met, and the type of pulse played does not directly depend on the feedback data received.
When testing a new sequence, it can also be useful to store the , as the value of the variable can be monitored by writing to a user register:
waitZSyncTrigger();
feedback_data = getFeedback(ZSYNC_DATA_PQSC_REGISTER, feedback_time);
setUserReg(0, feedback_data);
The above code will write the feedback data available at feedback_time
sequencer clock cycles after the ZSync trigger is received. The data is written to user register 0.
Functional Elements
Control/Tool | Option/Range | Description |
---|---|---|
Start |
Runs the AWG. |
|
Sampling Rate |
AWG sampling rate. This value is used by default and can be overridden in the Sequence program. The numeric values are rounded for display purposes. The exact values are equal to the base sampling rate divided by 2^n, where n is an integer between 0 and 13. |
|
Round oscillator frequencies. |
![]() |
Round oscillator frequencies to nearest commensurable with 225 MHz. |
Status |
Display compiler errors and warnings. |
|
Compile Status |
grey/green/yellow/red |
Sequence program compilation status. Grey: No compilation started yet. Green: Compilation successful. Yellow: Compiler warnings (see status field). Red: Compilation failed (see status field). |
Upload Progress |
0% to 100% |
The percentage of the sequencer program already uploaded to the device. |
Upload Status |
grey/yellow/green |
Indicates the upload status of the compiled AWG sequence. Grey: Nothing has been uploaded. Yellow: Upload in progress. Green: Compiled sequence has been uploaded. |
Register selector |
Select the number of the user register value to be edited. |
|
Register |
0 to 2^32 |
Integer user register value. The sequencer has reading and writing access to the user register values during run time. |
Input File |
External source code file to be compiled. |
|
Example File |
Load pre-installed example sequence program. |
|
New |
![]() |
Create a new sequence program. |
Revert |
![]() |
Undo the changes made to the current program and go back to the contents of the original file. |
Save (Ctrl+S) |
![]() |
Compile and save the current program displayed in the Sequence Editor. Overwrites the original file. |
Save as… (Ctrl+Shift+S) |
![]() |
Compile and save the current program displayed in the Sequence Editor under a new name. |
Automatic upload |
ON / OFF |
If enabled, the sequence program is automatically uploaded to the device after clicking Save and if the compilation was successful. |
To Device |
![]() |
Sequence program will be compiled and, if the compilation was successful, uploaded to the device. |
Multi-Device |
ON / OFF |
Compile the program for use with multiple devices. If enabled, the program will be compiled for and uploaded to the devices currently synchronized in the Multi-Device Sync tab. |
Sync Status |
grey/green/yellow |
Sequence program synchronization status. Grey: No program loaded on device. Green: Program in sync with device. Yellow: Sequence program in editor differs from the one running on the device. |
Control/Tool | Option/Range | Description |
---|---|---|
Mem Usage (%) |
0 to 100 |
Amount of the used waveform data relative to the device cache memory. The cache memory provides space for 64 kSa of waveform data per AWG core. |
Wave Selection |
Select wave for display in the waveform viewer. If greyed out, the corresponding wave is too long for display. |
|
Waveforms |
Lists all waveforms used by the current sequence program. |
Control/Tool | Option/Range | Description |
---|---|---|
Signal |
Selects the digital trigger source signal. |
|
DIO/Zsync Trigger state |
grey/green |
Indicates that triggers are generated from the DIO or ZSync interface to the AWG. |
Read DIO/ZSync |
Each AWG can be configured to either receive DIO data or ZSync data. |
|
Valid Index |
16 to 31 |
Selects the index n of the DIO interface bit (notation DIO[n] in the Specification chapter of the User Manual) to be used as a VALID signal input, i.e. a qualifier indicating that a valid codeword is available on the DIO interface. |
Valid Polarity |
Polarity of the VALID bit that indicates that a codeword is available on the DIO interface. |
|
None |
VALID bit is ignored. |
|
Low |
VALID bit must be logical low. |
|
High |
VALID bit must be logical high. |
|
Both |
VALID bit may be logical high or logical low. |
|
Codeword Mask |
0 to 1023 |
10-bit value to select the bits of the DIO interface input state (notation DIO[n] in the Specification chapter of the User Manual) to be used as a codeword in connection with the playWaveDIO sequencer instruction. The Codeword Mask is combined with the DIO interface input state by a bitwise AND operation after applying the Codeword Shift. |
Codeword Shift |
0 to 31 |
Defines the integer bit shift to be applied to the input state of the DIO interface (notation DIO[n] in the Specification chapter of the User Manual) to be used as a codeword for waveform selection in connection with the playWaveDIO sequencer instruction. |
High bits |
32-bit value indicating which bits on the DIO interface are detected as logic high. |
|
Low bits |
32-bit value indicating which bits on the DIO interface are detected as logic low. |
|
Timing Error |
grey/red |
Indicates a timing error. A timing error is defined as an event where either the VALID or any of the data bits on the DIO interface change value at the same time as the STROBE bit. |
Display Format |
Select PQSC Register and Decoder view format. |
|
Hexadecimal |
ZSync parameters view format is hexadecimal. |
|
Decimal |
ZSync parameters view format is decimal. |
|
Binary |
ZSync parameters view format is binary. |
|
PQSC Register Shift |
The bit shift applied to the message received on ZSync interface coming from the PQSC readout registers. |
|
PQSC Register Mask |
4-bit value to select the bits of the message received on ZSync interface coming from the PQSC readout registers. |
|
PQSC Register Offset |
The additive offset applied to the message received on ZSync interface coming from the PQSC readout registers. |
|
PQSC Decoder Shift |
The bit shift applied to the message received on ZSync interface coming from the PQSC error decoder. |
|
PQSC Decoder Mask |
8-bit value to select the bits of the message received on ZSync interface coming from the PQSC error decoder. |
|
PQSC Decoder Offset |
The additive offset applied to the message received on ZSync interface coming from the PQSC error decoder. |
|
Display Format |
Select view format. |
|
Hexadecimal |
Internal feedback parameters view format is hexadecimal. |
|
Decimal |
Internal feedback parameters view format is decimal. |
|
Binary |
Internal feedback parameters view format is binary. |
|
Internal Feedback Shift |
The bit shift applied to the readout data received from the QA channel. |
|
Internal Feedback Mask |
16-bit value to select the bits of the shifted readout data received from the QA channel. |
|
Internal Feedback Offset |
The additive offset applied to the shifted and masked readout data received from the QA channel. |
|
Trigger State |
grey/green |
State of the Trigger. Grey: No trigger detected. Green: Trigger detected. |
Slope |
Select the signal edge that should activate the trigger. The trigger will be level sensitive when the Level option is selected. |
|
Level (V) |
numeric value |
Defines the analog trigger level. |
Auxiliary Trigger State |
grey/green |
State of the Auxiliary Trigger. Grey: No trigger detected. Green: Trigger detected. |
Control/Tool | Option/Range | Description |
---|---|---|
Assembly |
Text display |
Displays the current sequence program in compiled form. Every line corresponds to one hardware instruction. |
Mem Usage (%) |
0 to 100 |
Size of the current sequence program relative to the device cache memory. The cache memory provides space for a maximum of 16384 instructions. |
Clear |
Clears the command table description for the selected AWG Core. |
|
Sequence Editor |
Display and edit the sequence program. |
|
Counter |
Current position in the list of sequence instructions during execution. |
|
Status |
Running, Idle, Waiting |
Displays the status of the sequencer on the instrument. Off: Ready, not running. Green: Running, not waiting for any trigger event. Yellow: Running, waiting for a trigger event. Red: Not ready (e.g., pending elf download, no elf downloaded) |
Rerun |
ON / OFF |
Reruns the Sequencer program continuously. This way of looping a program results in timing jitter. For a jitter free signal implement a loop directly in the sequence program. |
Status |
grey/green/red |
Displays the status of the command table of the selected AWG Core. Grey: no table description uploaded, Green: table description successfully uploaded, Red: Error occurred during uploading of the table description. |