Q1 Sequence Processor
Description
The Q1 sequencer is the heart of the Quantum Control/Readout Modules (QRM/QCM) at Qblox. The sequencers are split into the sequence processor, arbitrary waveform generation (AWG), and acquisition paths as shown in the figures below. Each sequence processor controls two AWG paths and, in the case of QRM modules, two acquisition paths. The processor itself provides a ubiquitous interface across all modules for the end user. Each sequencer processor is, in turn, split into a classical and real-time pipeline. The classical pipeline is responsible for any classical instructions related to program flow or arithmetic and the real-time pipeline is responsible for real-time instructions that are used to create the experiment timeline.
The simplified architecture of the Q1 sequencers is presented below:
Applications
The Q1 sequence processor provides a ubiquitous platform across qblox’s instruments for developing low-level control and measurement sequences. The Python interface allows for fast development of experimental setups while the underlying Q1ASM programs grant access to precise and flexible control over the instruments.
Programming control sequences
For QCM/QCM-RF modules the Q1 sequence processor is used to develop control sequences to program the modules for qubit control. For more information on the applications of Quantum Control Modules that utilize the Q1 Sequence Processor, please refer to QCM applications and QCM-RF applications.
Programming readout sequences
For QRM/QRM-RF modules the Q1 sequence processor is used to develop readout (AWG and acquisition) sequences to program the modules for qubit measurement. For more information on the applications of Quantum Readout Modules that utilize the Q1 Sequence Processor, please refer to QRM applications and QRM-RF applications.
Features
Sequencer Layout
1. Instruction Memory
Memory storing the instructions of the Q1ASM program to be executed. Commands are either classical or real-time in nature, defining whether they are executed by the classical core or passed to the buffer to be executed by the real-time core. For QCM modules the maximum number of instructions per program is 16384 and for QRM modules the maximum number of instructions per program is 12288.
2. Data Memory
Data memory is a set of registers that are used to store data during the execution of a Q1ASM program. These registers are referenced as R# from 0 to 63.
3. Classical Core
The classical core is the computing block that executes all classical instructions in the Q1ASM program. For a list of all classical commands available in Q1ASM refer to Instructions.
4. Latches
Updates to playback parameters including NCO frequency, phase, amplitude, and offset are latched and await any of the play, acquire or update parameter commands, before the update to the parameter is physically set. For a break down on all Q1ASM commands that are latched, refer to Instructions
5. Buffer
The buffer stores the real-time commands ready for execution by the real-time core. This buffer holds up to 32 real-time commands at a time.
6. Real-time core
The real-time core is the processing unit that executes all real-time commands. The real-time core is connected to both the external trigger and SYNQ protocols, which allow real-time cores to be synchronized across modules and clusters using the wait_sync Q1ASM command. For a breakdown of all real-time commands please refer to Instructions
AWG Path
The AWG path has the following features across two pathways:
1. Waveform Memory
The AWG path has access to all waveforms supplied in the sequence.
These waveforms are referenced in the Q1ASM program
for playback with the play
command. The waveform memory for each sequencer
is 16384 samples (total duration of all waveforms on this sequencers),
and the maximum number of waveforms that can be stored on a sequencer is 1024.
2. Digital Gain
Each sequencer has a dedicated gain step for both paths 0 and 1, which can be
statically configured using the sequencer#.gain_awg_path#()
parameters.
However, the gain can also be dynamically controlled using the set_awg_gain
instruction of the sequence processor which enables pulse parametrization
(see section Instructions). The static and dynamic gain
controls are complementary.
Note
If modulated IQ signals are used for an output pair, the gain
sequencer#.gain_awg_path#()
has to be the same for both paths.
3. Digital Offset
Following the gain stage an offset is applied to the waveform before
modulation with the NCO. The offset of each path in a sequencer is set using
the sequencer#.offset#()
parameters.
4. NCO
Each Q1 sequencer has a dedicated numerically controlled oscillator (NCO). This NCO can be used to track the qubit or resonator phase (at a fixed frequency) in real-time. This NCO can be swept from -500MHz to 500MHz.
The frequency of the NCO and phase can be statically controlled using the
sequencer#.nco_freq()
and sequencer#.nco_phase_offs()
parameters. However, the frequency and phase of the NCO can also be dynamically controlled
using the set_freq, reset_ph, set_ph, and set_ph_delta instructions
of the sequence processor, which enables pulse parametrization and execution
of virtual Z-gates (see section Instructions). The
static and dynamic phase control is complementary. The modulation is enabled
using the sequencer#.mod_en_awg parameter()
. The demodulation is
enabled using the sequencer#.demod_en_acq parameter()
.
For further in depth details and a tutorial on how to utilize the Q1 sequencer NCO capabilities, please refer to the NCO tutorial.
5. Mixer Correction
The phase of the NCO can be offset between paths to allow for IQ mixer correction.
6. Mixing Stage
The Sequencer has an onboard mixing stage for modulating a set waveform envelope at a set frequency between -500MHz and 500MHz.
Acquisition Path
1. Demodulation
Each sequencer with an acquisition path has a digital demodulation unit onboard that can demodulate signals from -500MHz to 500MHz.
2. Time of Flight Compensation
To enable reliable demodulation a time of flight compensation can be programmed into the NCO used for demodulation, allowing for accurate phase matching between IF and acquired signal.
3. Weight Memory
The weight memory stores the integration weights set by the user in the provided sequence. This is an optional capability, and acquisition is performed an unitary integration by default. The maximum number of weights that can be stored is 64.
4. Integrator
The integrator block performs a square integration, or applies the provided integration weights to the incoming data. When using the square integration, the length of the integration is restricted to 16 777 212 ns. For the weighted integration, this is limited to the length of the weight memory of 16380 ns.
5. Rotation
The acquisition path performs a rotation of the data before thresholding. This acts to allow for thresholding to be set at an arbitrary gradient through the IQ plane. Setting the rotation is the equivalent of setting the angle of the separator used for thresholding in the IQ plane. Details on how to set and use this rotation are provided below in 6. Thresholding.
6. Thresholding
The thresholding unit evaluates all data above the set threshold, returning a 1 if it is above and a 0 otherwise. This result is shared across the cluster for applications in feedback.
One way of identifying the qubit state from a measurement (e.g. via an integrated acquisition)
is by defining a threshold for measured I-Q points. The threshold can be imagined as a
line through the I-Q-plane, where every point on one side is defined as a 0, and all
the others as a 1. The threshold line is controlled by two sequencer settings:
thresholded_acq_rotation
and thresholded_acq_threshold
, as illustrated in the figure
below
By default (left figure) we have thresholded_acq_rotation = 0
and
thresholded_acq_threshold = 0
, where every measured data point with I<0
is
assigned the state 0, and the remaining data points are assigned the state 1. The
first setting, thresholded_acq_rotation
rotates the threshold line by an angle in degrees
(0-360), clockwise. The second setting, thresholded_acq_threshold
, sets the
threshold that is compared to the rotated integrated acquisition result.
These settings can be set for each sequencer individually, e.g.
qrm.sequencer0.thresholded_acq_rotation(30)
qrm.sequencer0.thresholded_acq_threshold(0.15)
then, after arming and starting the sequence, the thresholded acquisitions can be retrieved from
qrm.get_acquisitions(0)['0']['acquisition']['bins']['threshold']
7. Binning and Averaging
The acquired integrated values can be stored in different memory entries or bins. Every sequencer has 132072 bins available. On top of that, saving multiple acquisition to the same bins allows one to average the value. The number of averages is saved to the acquisition data as well. The bins and averaging used are set in the sequence Sequence Protocol supplied to the sequencer before operation. An example is presented in the binning tutorial.
8. Scope
The Scope acquisition can be configured to be triggered by the input level or by the sequencer through commands
qrm.scope_acq_trigger_mode_path0/1()
, followed by sequencer#.scope_acq_trigger_level_path0/1()
or qrm.module.scope_acq_sequencer_select()
, respectively.
When the sequencer is selected to trigger the scope acquisition,
every acquisition will trigger the capture of 16k input samples on both
inputs and will store the raw input samples in a temporary buffer.
Every time an acquisition is started, this
temporary memory is overwritten, so it is vital to move the samples from the
temporary buffer to a more lasting location before the start of the next acquisition.
Learn how to use this mode by following the relevant scope tutorial.
TTL Trigger Acquisition Path
1. Input Select
In the TTL trigger path, one of the inputs is selected using the qblox_instruments
input_select_acq_ttl()
parameter tied to each sequencer.
2. Threshold
The thresholding unit evaluates all data above the set threshold, returning a 1 if it is above and a 0 otherwise. This result can be shared across the cluster for feedback applications.
The threshold for this acquisition can be set for each sequencer individually, e.g.
qrm.sequencer0.ttl_acq_threshold(0.5)
3. Edge Detect
When a TTL trigger is detected at the threshold comparator, the resulting one-bit signal is pushed through an edge detection to transform the TTL trigger of undetermined duration into a single clock cycle trigger pulse.
4. Enable
The TTL trigger path is always active, but its output results are gated based
on the enable()
parameter in the acquire_ttl()
Q1ASM instruction.
5. Bin Counter
The bin index is given as an argument of the instruction and is automatically
incremented by each detected trigger through the bin counter. auto_bin_incr_en_acq_ttl()
selects if the bin index is automatically incremented when acquiring multiple triggers.
6. Averaging/Binning
The resulting trigger pulse and the associated ADC values that caused the trigger detection can be stored through the binning and averaging module. When doing this, the retrigger rate is restricted to roughly 1MHz.
The TTL acquisition will be saved in ‘averages’ and can be retrieved by:
qrm.get_acquisitions(0)['0']['acquisition']['bins']['averages']
Continuous Waveform Mode
The sequencer also supports a continuous waveform mode of operation, where the
waveform playback control of the sequence processor is completely bypassed and a single
waveform is just played back on a loop. This mode can be enabled using the
sequencer#.cont_mode_en_awg_path#()
parameter and the waveform can be selected
using the sequencer#.cont_mode_waveform_idx_awg_path#()
parameter.
The waveforms used in this mode must have a minimum length of 4 ns.
When in continuous mode, simply program, arm, start, and stop the sequencer using
the regular control functions and parameters (i.e. sequencer#.sequence()
,
arm_sequencer()
, start_sequencer()
and stop_sequencer()
).
However, be aware that the sequencer processor can still
control parts of the AWG path, like phase, gain, and offset, while the sequencer
operates in this mode. Therefore, we advise programming the sequence processor
with a single stop instruction.
Multiplexing
All Q1 sequence processors are allowed to be connected to different outputs at the same time. This enables easy and flexible targeting of multiple qubits on a single channel.
The output multiplexer can be statically configured through the
sequencer#.channel_map_path#_out#_en()
parameters.
The graph below shows the different routing possibilities.
The routing possibilities are uniform for all outputs on the different modules. To simplify complex signal generation path0 (or the I component) can only be connected to out0 or out2, and path1 (Q component) to out1 or out3. In the QCM-RF and QRM-RF modules, the complex signal is upconverted to the GHz regime, resulting in half the number of outputs. For more details, see Block Diagram and Block Diagram.
In the QRM and QRM-RF modules, all inputs are permanently routed to all sequencers.
Operation
Q1 Sequencer processors have an arbitrary wave generation (AWG) path, and in the case of QRM modules, also have an acquisition path. Each sequencer shares the following features:
1. Sequences
Q1 Sequence Processors are programmed using sequence constructs which consist of 4 key parts: waveforms, weights, acquisitions, and a program. This section will break down the high-level structure of a sequence before going into detail on each of these 4 parts that can make up a sequence.
The sequencers are programmed with a sequence using the
sequencer#.sequence()
function parameter. The sequence is expected to adhere
to the following format:
waveforms: Indicates that the following waveforms are intended for the AWG path.
waveform name: Replace by string containing the waveform name.
data: List of floating point values to express the waveform.
index: Integer index used by the Q1ASM program to refer to the waveform.
For more details please go to section 2. Waveforms below
- weights: Indicates that the following weight functions are intended for the
integration units of the acquisition path (only used by the QRM or QRM-RF).
weight name: Replace by string containing the weight name.
data: List of floating point values to express the weight.
index: Integer index used by the Q1ASM program to refer to the weight.
For more details please go to section 4. Weights below
- acquisitions: Indicates that the following acquisitions are available for
the acquisition path to refer to (only used by the QRM or QRM-RF).
acquisition name: Replace by string containing the acquisition name.
num_bins: Number of bins in acquisition.
index: Integer index used by the Q1ASM program to refer to the acquisition.
For more details please go to section 3. Acquisitions below
program: Single string containing the entire sequence processor Q1ASM program.
For more details please go to section 5. Program below
For details of the instructions used in Q1ASM programs please go to Instructions
2. Waveforms
The waveforms are expressed as a list of floating point values in the range of 1.0 to -1.0 with a resolution of one nanosecond per sample. The AWG path uses these waveforms to parametrically generate pulses on its outputs.
Waveform playback is started by the play Q1ASM instruction. Each waveform is paired with an index, which is used by this instruction to refer to the associated waveform. The waveform is then completely played irrespective of further sequence processor instructions, except when the sequence processor issues the playback of another waveform, in which case the waveform will be stopped and the new waveform will start. In case the time between waveforms is longer than the waveform length, the intermediate time will be filled by samples with a value of zero. The maximum number of waveforms that can be stored is 1024.
The programmed waveforms can be retrieved using get_waveforms()
.
3. Acquisitions
Scope Acquisitions:
Acquisitions are started by the acquire, acquire_weighed, or acquire_ttl
Q1ASM instructions, and will trigger the capture of 16k input samples on both
inputs. This mode of operation is called scope mode and will store the raw
input samples in a temporary buffer. Every time an acquisition is started, this
temporary memory is overwritten, so it is vital to move the samples from the
temporary buffer to a more lasting location before the start of the next acquisition.
This is done by calling store_scope_acquisition()
,
which moves the samples into the specified acquisition in the acquisition list
of the sequencer, located in the RAM of the instrument. Multiple acquisitions
can be stored in
this list before being retrieved from the instrument by simply calling
get_acquisitions()
. Acquisitions are returned as a dictionary of acquisitions. Scope mode data is
located under the scope key as lists of floating point values in a range of
1.0 to -1.0 with a resolution of one nanosecond per sample, as well as an indication if the ADC was
out-of-range during the measurement. The maximum duration of the scope is
16380ns.
Note
Before calling store_scope_acquisition()
, be sure to call get_sequencer_state()
and get_acquisition_state()
in that order.
This ensures that both the sequencer has finished and that there is an acquisition ready.
The acquisition path also has an averaging function set through the
scope_acq_avg_mode_en_path#()
parameters. This enables the automatic
accumulation of acquisitions, where sample N of acquisition M is automatically
accumulated to sample N of acquisition M+1. This happens while the acquisition is
still in the temporary buffer, so after the desired number of averaging acquisitions
is completed, call store_scope_acquisition()
to store the
accumulated result in the acquisition list. Once retrieved from the instrument,
the accumulated samples will automatically be divided by the number of averages to get the actual
averaged acquisition result.
Tip
For debug purposes, the acquisition path can also be triggered using a
trigger level, where if the input exceeds this level, an acquisition is started. See the
sequencer#.trigger_mode_acq_path#()
and sequencer#.trigger_level_acq_path#()
parameters for more information.
Square Weight Acquisitions:
The acquire Q1ASM command performs a square weight acquisition over a certain
period and stores
the result in a bin of the provided acquisition in the sequence. The integration
is executed using square weights with a preset
length set through the associated QCoDeS parameter integration_length_acq()
(must be a multiple of 4, with a maximum of 16 777 212). The maximum number of
acquisitions that can be stored is 32.
acquire 0,0,16384 # Start acquisition using acquisition at index 0 and place in the bin at index 0, then wait for 16484ns
stop #Stop sequencer
Weighed Acquisitions:
The acquire_weighed Q1ASM command performs an acquisition that utilizes the weights provided in the sequence for integration of the acquired signal.
acquire_weighted 0,0,0,1,1000 #Acquire for 1000ns using acquisition at index 0 and place in bin at index 0, using weights at index 0 for path 0 and index 1 for path 1
stop #Stop sequencer
TTL Trigger Acquisitions:
The acquire_ttl instruction is used to detect TTL triggers on one of the instrument’s
inputs when it exceeds a configurable threshold.
The input is selected using sequencer#.ttl_acq_input_select()
, while the threshold
is set using sequencer#.ttl_acq_threshold()
.
The instruction enables the TTL trigger acquisition path by setting the enable
argument to 1 and needs to actively disable the path again by using the same
instruction with its enable argument set to 0. While the TTL trigger acquisition
path is enabled, real-time integration and discretization is disabled.
acquire_ttl 0,0,1,1000 #Acquire triggers and wait for 1000ns
acquire_ttl 0,0,0,4 #Stop acquiring triggers and wait for 4ns
stop #Stop sequencer
When a rising edge is detected on the input that exceeds the threshold while the path is enabled, a TTL trigger is detected and its ADC value at which it was detected is stored in the bin specified by the instruction’s bin index argument. No new TTL triggers will be detected until a new rising edge exceeds the configured threshold.
When multiple triggers are detected while the path is enabled, the storage strategy
is determined by the sequencer#.ttl_acq_auto_bin_incr_en()
parameter.
When sequencer#.ttl_acq_auto_bin_incr_en()
is enabled, the bin index is
automatically incremented every time a TTL trigger is detected. This gives the ability
to store every ADC value individually and allows you to count the number of TTL
triggers by counting the number of valid bins stored at the end of the sequence.
Alternatively, when sequencer#.ttl_acq_auto_bin_incr_en()
is disabled the
same bin is reused for every detected TTL trigger. This allows averaging the
ADC values in hardware and allows you to count the number of TTL triggers by
looking at the average count of that bin at the end of the sequence.
The resulting acquisition data can be retrieved using get_acquisitions()
.
The ADC values at which TTL triggers were detected are stored in the integration
key as lists of floating point values in a range of 1.0 to -1.0. They replace
the integration results of regular acquisitions.
4. Weights
The weights are expressed as a list of floating point values in the range of 1.0 to -1.0 with a resolution of one nanosecond per sample. The integration units in the acquisition path apply (i.e. multiply) these weights during the integration process when the acquisition path is triggered for weighted integration.
Weighed integration is triggered by the acquire_weighed instruction. Each weight is paired with an index, which is used by this instruction to refer to the associated weight. The weight is then played, like the waveforms discussed in the previous section, and determines the length of the integration. The weighted integration process continues irrespective of further sequence processor instructions, except when the sequence processor issues another acquisition using the acquire or acquire_weighed instructions, in which case the integration will be stopped, the result will be stored and a new integration will start. For non-weighted integrations the max length of integration is 16777212ns, for weighted integrations it is the same as the maximum scope length, 16380ns.
The programmed weights can be retrieved using get_weights()
.
5. Program
The sequence programs are written in the custom Q1ASM assembly language described in q1asm. All sequence processor instructions are executed by the classical pipeline and the real-time instructions are also executed by the real-time pipeline. These latter instructions are intended to control the AWG and acquisition paths in a real-time fashion. Once processed by the classical pipeline they are queued in the real-time pipeline awaiting further execution. A total of 32 instructions can be queued and once the queue is full, the classical part will stall on any further real-time instructions.
Once execution of the real-time instructions by the real-time pipeline is started, care must be taken to not cause an underrun of the queue. An underrun will potentially cause undetermined real-time behavior and desynchronize any synchronized sequencers. Therefore, when this is detected, the sequencer is completely stopped. A likely cause of underruns is a loop with a very short (i.e. < 24ns) real-time run-time, since the jump of a loop takes some cycles to be executed by the classical pipeline. See the column Execution time of Instructions for execution times in the classical pipeline for each instruction.
Finally, be aware that moving data into a register using an instruction takes a cycle to complete. This means that when an instruction reads from a register that the previous instruction has written to, a nop instruction must be placed in between these consecutive instructions for the value to be correctly read.
The state of the sequencers, including any errors, can be queried through get_sequencer_state()
.
Q1ASM
The sequence programs are written in the custom Q1ASM assembly language described on this page. All sequence processor instructions are executed by the classical pipeline and the real-time instructions are also executed by the real-time pipeline. These latter instructions are intended to control the AWG and acquisition paths in a real-time fashion. Once processed by the classical pipeline they are queued in the real-time pipeline awaiting further execution. A total of 32 instructions can be queued and once the queue is full, the classical part will stall on any further real-time instructions.
Once execution of the real-time instructions by the real-time pipeline is started, care must be taken to not cause an underrun of the queue. An underrun will potentially cause undetermined real-time behavior and desynchronize any synchronized sequencers. Therefore, when this is detected, the sequencer is completely stopped. A likely cause of underruns is a loop with a very short (i.e. < 24ns) real-time run-time, since the jump of a loop takes some cycles to be executed by the classical pipeline.
Finally, be aware that moving data into a register using an instruction takes a cycle to complete. This means that when an instruction reads from a register that the previous instruction has written to, a nop instruction must be placed in between these consecutive instructions for the value to be correctly read.
The state of the sequencers, including any errors, can be queried through get_sequencer_state()
.
Assembly syntax
Assembly source for the Q1 processor consists of lines containing directives or code, all of which are case
sensitive. Any input starting with #
until end-of-line is treated as comment.
Directives
The assembler supports user-defined aliases using the .DEF <name> <value>
directive, which defines name
as an
alias for value
. name
is an identifier consisting of upper- and lower-case letters and numbers, starting with a
letter. value
can be any string (e.g. 42
or R63
).
Code
A source line has the following format:
[label:] instruction argument,argument,... [comment]
Fields must be separated by white space (combinations of space and tab), operands may be separated by white space.
Arguments
Q1ASM instructions make use of the following argument types:
Type |
Acronym |
Format |
Description |
---|---|---|---|
Immediate |
|
# |
32-bit decimal or hexadecimal value (e.g. |
Register |
|
R# |
Register address in range 0 to 63 (e.g. |
Labels
Any instruction can be preceded by a label, i.e. an identifier followed by a ‘:’ character. Labels are also allowed to be on a separate line. A label represents the instruction address of the following instruction.
Label references
A label defined as label:
can be referred to in (immediate) instruction arguments as @label
. Forward
references are allowed, the definition need not precede the reference. Labels can be used with instructions that can
alter program flow (i.e. jmp, jge, jlt and loop), but also with any other instruction.
Alias references
Names defined by .DEF name ...
can be referred to in (immediate or register) instruction arguments as
$name
. Forward references are not allowed, the .DEF
must precede the reference.
Instructions
The arguments of an instruction are specified as arg0_name: type, arg1_name: type, ...
.
An instruction may have multiple allowed combinations of arguments, those are specified on separate lines.
The instruction time of the classical pipeline may depend on the argument types. It is specified in ns, separately for each
combination of arguments.
Instruction |
Signature |
Execution time (ns) |
---|---|---|
Description of instruction |
||
Control instructions |
||
illegal |
4 |
|
Instruction that should not be executed. If it is executed, the sequencer will stop with the illegal instruction flag set. |
||
stop |
4 |
|
Instruction that stops the sequencer. |
||
nop |
4 |
|
No operation instruction, that does nothing. It is used to pass a single cycle in the classic part of the sequencer without any operations. |
||
Jump instructions |
||
jmp |
|
16 16 |
Jump to the instruction indicated by address. |
||
jge |
|
24 on jump, 12 on continue 24 on jump, 12 on continue |
If a is greater or equal to b, jump to the instruction indicated by address. |
||
jlt |
|
24 on jump, 12 on continue 24 on jump, 12 on continue |
If a is less than b, jump to the instruction indicated by address. |
||
loop |
|
24 on jump, 12 on continue 24 on jump, 12 on continue |
Decrement a by one and, if the result is non-zero, jump to the instruction indicated by address. |
||
Arithmetic instructions |
||
move |
|
4 4 |
source is moved / copied to destination. |
||
not |
|
12 12 |
Bit-wise invert source and move the result to destination. |
||
add |
|
12 16 |
Add b to a and move the result to destination. |
||
sub |
|
12 16 |
Subtract b from a and move the result to destination. |
||
and |
|
12 16 |
Bit-wise AND a and b and move the result to destination. |
||
or |
|
12 16 |
Bit-wise OR a and b and move the result to destination. |
||
xor |
|
12 16 |
Bit-wise XOR a and b and move the result to destination. |
||
asl |
|
12 16 |
Bit-wise left-shift a by b number of bits and move the result to destination.
|
||
asr |
|
12 16 |
Bit-wise right-shift a by b number of bits and move the result to destination.
|
||
Parameter operation instructions The parameters are latched and only updated when the upd_param, play, acquire, acquire_weighed or acquire_ttl instructions are executed. |
||
set_mrk |
|
4 4 |
Set marker output channels to val (bits 0-3), where the bit index corresponds to the channel index for baseband modules. For QCM-RF modules, bit indices 0 & 1 correspond to output enable 1 and 2 respectively; indices 2 & 3 correspond to marker output 2 and 1 respectively. For QRM-RF modules, bit indices 0 & 1 correspond to input 1 and output 1 switch respectively; indices 2 & 3 correspond to marker output 1 and 2 respectively. The values are OR´ed by that of other sequencers. |
||
set_freq |
|
4 4 |
Set the frequency of the NCO used by the AWG and acquisition using value. The frequency is divided into 4e9 steps between -500 and 500 MHz and expressed as an integer between -2e9 and 2e9 (e.g.1 MHz=4e6). |
||
reset_ph |
4 |
|
Reset the absolute phase of the NCO used by the AWG and acquisition to 0°. This also resets any relative phase offsets that were already statically or dynamically set. |
||
set_ph |
|
4 4 |
Set the absolute phase of the NCO used by the AWG and acquisition using value. The phase is divided into 1e9 steps between 0° and 360°, expressed as an integer between 0 and 1e9 (e.g 45°=125e6). |
||
set_ph_delta |
|
4 4 |
Set an offset on top of the relative phase of the NCO used by the AWG and acquisition. The offset is applied on top of the phase set using set_ph. See set_ph for more details regarding the argument. |
||
set_awg_gain |
|
4 8 |
Set AWG gain for path 0 using value_0 and path 1 using value_1. Both are integers in [-32 768, 32 767]. |
||
set_awg_offs |
|
4 8 |
Set AWG offset for path 0 using value_0 and path 1 using value_1. Both values are integers in [-32 768, 32 767]. |
||
Conditional instructions |
||
set_cond |
|
4 12 |
Enable/disable conditionality on all following real-time instructions based on enable. The condition is based on the trigger network address counters being thresholded based on the associated counter threshold parameters set through QCoDeS. The results are masked using mask (bits 0-14), where the bit index plus one corresponds to the trigger address. This creates a selection to include in the final logical operation set using operator. Logical operators are OR, NOR, AND, NAND, XOR, XNOR, where a value for operator of 0 is OR and 5 is XNOR respectively. The logical operation result (true/false) determines the condition. If the condition is true upon evaluation, the next real-time instruction is executed. Else the real-time path ignores the instruction and waits for duration nanoseconds before continuing to the next. All following real-time instructions are subject to the same condition, until either the conditionality is disabled or updated. Disabling the conditionality does not affect the address counters. See also Feedback. |
||
Real-time IO operation instructions |
||
upd_param |
|
4 |
Update the latched parameters, and then wait for duration nanoseconds. |
||
play |
|
4 8 |
Update the latched parameters, start playing AWG waveforms stored at indexes wave_0 on path 0 and wave_1 on path 1 and finally wait for duration nanoseconds. |
||
acquire |
|
4 4 |
Update the latched parameters, start the acquisition referred to using index acquisition and store the bin data in bin index bin, finally wait for duration nanoseconds. Integration is executed using a square weight with a preset length through the associated QCoDeS parameter. |
||
acquire_weighted |
|
4 12 |
Update the latched parameters, start the acquisition referred to using index acquisition and store the bin data in bin index bin, finally wait for duration nanoseconds. Integration is executed using weights stored at indices weight_0 for path 0 and weight_1 for path 1. |
||
acquire_ttl |
|
4 4 |
Update the latched parameters, start the TTL trigger acquisition referred to using index acquisition and store the bin data in bin index bin. Enable the acquisition by writing 1 to enable, finally wait for duration number of nanoseconds. The TTL trigger acquisition has to be actively disabled afterwards by writing 0 to enable. |
||
Real-time trigger count control instructions |
||
set_latch_en |
|
4 4 |
Enable/disable all trigger network address counters based on mask and then wait for duration nanoseconds. Once enabled, the trigger network address counters will count all triggers on the trigger network. When disabled, the counters hold their last values. |
||
latch_rst |
|
4 4 |
Reset all trigger network address counters back to 0 and then wait for duration nanoseconds. |
||
Real-time wait operation instructions |
||
wait |
|
4 4 |
Wait for duration` nanoseconds. |
||
wait_trigger |
|
4 4 |
Wait for a trigger on the trigger network at the address set using trigger and then wait for duration nanoseconds. |
||
wait_sync |
|
4 4 |
Wait for SYNQ to complete on all connected sequencers over all connected instruments and then wait for duration nanoseconds. |
Note
The duration argument for set_cond, upd_param, play, acquire, acquire_weighed, acquire_ttl, wait, wait_trigger and wait_sync can be set at a resolution of 1 ns, with a minimum of 4 ns. All operations and parameters are executed/updated on this 1 ns timegrid, except for instructions that operate on the sequencer’s NCOs (set_freq, reset_ph, set_ph, set_ph_delta`). For now, those parameters are updated on a 4 ns timegrid. The minimum time between instructions for the NCOs is 8ns. Scope acquisitions can be started on a 1 ns time resolution as well. However, when doing back-to-back scope acquisitions, their duration must be a multiple of 4 ns. This behavior of the scope acquisitions will be patched in a following release.
Example
This is a simple example of a Q1ASM program. It enables each marker channel output for 1μs and then stops.
move 1,R0 # Start at marker output channel 0 (move 1 into R0)
nop # Wait a cycle for R0 to be available.
loop: set_mrk R0 # Set marker output channels to R0
upd_param 1000 # Update marker output channels and wait 1μs.
asl R0,1,R0 # Move to next marker output channel (left-shift R0).
nop # Wait a cycle for R0 to be available.
jlt R0,16,@loop # Loop until all 4 marker output channels have been set once.
set_mrk 0 # Reset marker output channels.
upd_param 4 # Update marker output channels.
stop # Stop sequencer.