Sequencer¶
This section will explain how the sequencers are controlled. Every sequencer is controlled using the same functions and parameters, which either take the sequencer index as a parameter or indicate which sequencer they operate on based on the index in their name.
Overview¶
The sequencers are split into the sequence processor, AWG and acquisition paths as shown in the figures below. Each sequence processor controls one AWG path and, in case of the Pulsar QRM, one acquisiton path. The AWG path and acquisition path are discussed in more detail in section Pulsar. Each sequencer processor is, in turn, split into a classical and real-time pipeline. The classical pipeline is reponsible for any classical instructions related to program flow or arithmatic and the real-time pipeline is responsible for real-time instructions that are used to create the experiment timeline.
The sequencers are started and stopped by calling the arm_sequencer()
, start_sequencer()
and
stop_sequencer()
functions. Once started they will execute the sequence described in the next section.
Sequence¶
The sequencers are programmed with a sequence using the sequencer#_waveforms_and_program()
function parameter. This parameter expects
a sequence in the form of a JSON compatible file that contains the waveforms and a program. The JSON file is expected to adhere to the following format:
program: Single string containing the entire sequence processor Q1ASM program.
awg: 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.
acq: Indicates that the following waveforms are intented for the acquisition path’s integration unit (only used by the Pulsar QRM).
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.
Program¶
The sequence programs are written in the custom Q1ASM assembly language desribed in the following sections. 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 instuctions 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 behaviour and desycnhronize 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.
The state of the sequencers, including any errors, can be queried through get_sequencer_state()
.
Instructions¶
Instructions |
Argument 0 |
Argument 1 |
Argument 2 |
Description |
---|---|---|---|---|
illegal |
Instruction that should not be executed. If it is executed, the
sequencer will stop with the illegal instruction flag set.
|
|||
stop |
Instruction that stops the sequencer.
|
|||
nop |
No operation instruction, that does nothing. It is used to pass
a single cycle in the classic part of the sequencer without any
operations.
|
|||
Jumps |
||||
jmp |
Immediate,
Register,
Label
|
Jump to the next instruction indicated by argument 0.
|
||
jge |
Register
|
Immediate
|
Immediate,
Register,
Label
|
If argument 0 is greater of equal to argument 1, jump to the
instruction indicated by argument 2.
|
jlt |
Register
|
Immediate
|
Immediate,
Register,
Label
|
If argument 0 is less than argument 1, jump to the instruction
indicated by argument 2.
|
loop |
Register
|
Immediate,
Register,
Label
|
Subtract argument 0 by one and jump to the instruction indicated by
argument 1 until argument 0 reaches zero.
|
|
Arithmatic |
||||
move |
Immediate,
Register
|
Register
|
Argument 0 is moved / copied to argument 1.
|
|
not |
Immediate,
Register
|
Register
|
Bit-wise invert argument 0 and move the result to argument 1.
|
|
add |
Register
|
Immediate,
Register
|
Register
|
Add argument 1 to argument 0 and move the result to argument 2.
|
sub |
Register
|
Immediate,
Register
|
Register
|
Subtract argument 1 from argument 0 and move the result to
argument 2.
|
and |
Register
|
Immediate,
Register
|
Register
|
Bit-wise AND argument 1 and argument 0 and move the result to
argument 2.
|
or |
Register
|
Immediate,
Register
|
Register
|
Bit-wise OR argument 1 and argument 0 and move the result to
argument 2.
|
xor |
Register
|
Immediate,
Register
|
Register
|
Bit-wise XOR argument 1 and argument 0 and move the result to
argument 2.
|
asl |
Register
|
Immediate,
Register
|
Register
|
Bit-wise left-shift argument 1 by argument 0 number of bits and
move the result to argument 2.
|
asr |
Register
|
Immediate,
Register
|
Register
|
Bit-wise right-shift argument 1 by argument 0 number of bits and
move the result to argument 2.
|
Software request |
||||
sw_req |
Immediate,
Register
|
Generate software request interrupt with argument 0 value being passed
as interrupt argument (currently not implemented).
|
||
Real-time pipeline instructions |
||||
set_mrk |
Immediate,
Register
|
Set marker output channels to argument 0 (bits 0-3), where the bit
index corresponds to the channel index. The set value is OR’ed by that
of other sequencers.
The parameters are cached and only updated when the upd_param or
play instructions are executed.
|
||
set_ph |
Immediate,
Register
|
Immediate,
Register
|
Immediate,
Register
|
Set sequencer’s AWG and acquisition phase. The phase is divided into
a coarse (argument 0), fine (argument 1) and ultra-fine
(argument 2) segment. The coarse segment is divided into 400 steps of
0.9°. The fine segment is divided into 400 steps of 2.25e-3°. And the
ultra-fine segment is divided into 6250 steps of 3.6e-7°.
The parameters are cached and only updated when the upd_param or
play instructions are executed.
The arguments are either all set through immediates or registers.
|
set_ph_delta |
Immediate,
Register
|
Immediate,
Register
|
Immediate,
Register
|
Set sequencer’s AWG and acquisition phase offset. Offset that is applied
on top of the phase set using set_phase.
See set_phase for more details regarding the arguments.
The parameters are cached and only updated when the upd_param or
play instructions are executed.
|
set_awg_gain |
Immediate,
Register
|
Immediate,
Register
|
Set AWG gain for path 0 using argument 0 and path 1 using
argument 1. Both gain values are divided in 2**sample path width
steps.
The parameters are cached and only updated when the upd_param or
play instructions are executed.
The arguments are either all set through immediates or registers.
|
|
set_acq_gain |
Immediate,
Register
|
Immediate,
Register
|
Set acquisition gain for path 0 using argument 0 and path 1 using
argument 1. Both gain values are divided in 2**sample path width
steps.
The parameters are cached and only updated when the upd_param or
play instructions are executed.
The arguments are either all set through immediates or registers.
|
|
set_awg_offs |
Immediate,
Register
|
Immediate,
Register
|
Set AWG gain for path 0 using argument 0 and path 1 using
argument 1. Both offset values are divided in 2**sample path width
steps.
The parameters are cached and only updated when the upd_param or
play instructions are executed.
The arguments are either all set through immediates or registers.
|
|
set_acq_offs |
Immediate,
Register
|
Immediate,
Register
|
Set acquisition gain for path 0 using argument 0 and path 1 using
argument 1. Both offset values are divided in 2**sample path width
steps.
The parameters are cached and only updated when the upd_param or
play instructions are executed.
The arguments are either all set through immediates or registers.
|
|
upd_param |
Immediate
|
Update the marker, phase, phase offset, gain and offset parameters
set using their respective instructions and then wait for argument 0
number of nanoseconds.
|
||
play |
Immediate,
Register
|
Immediate,
Register
|
Update the marker, phase, phase offset, gain and offset parameters
set using their respective instructions, start playing AWG waveforms
stored at indexes argument 0 on path 0 and argument 1 on path 1 and
finally wait for argument 2 number of nanoseconds.
The arguments are either all set through immediates or registers.
|
|
acquire |
Immediate,
Register
|
Immediate,
Register
|
Update the marker, phase, phase offset, gain and offset parameters
set using their respective instruction, start acquisition using
integration waveforms stored at indexes argument 0 for path 0 and
argument 1 for path 1 and finally wait for argument 2 number of
nanoseconds.
The arguments are either all set through immediates or registers.
|
|
wait |
Immediate,
Register
|
Wait for argument 0 number of nanoseconds.
|
||
wait_trigger |
Immediate,
Register
|
Wait for external trigger and then wait for argument 0 number of
nanoseconds.
|
||
wait_sync |
Immediate,
Register
|
Wait SYNC to complete on all connected sequencers over all connected
instruments and then wait for argument 0 number of nanoseconds.
|
Note
The duration argument for upd_param, play, acquire, wait, wait_trigger and wait_sync needs to a be multiple of 4ns. This will be reduced to 1ns in the future.
Arguments¶
Arguments |
Format |
Description |
---|---|---|
Immediate |
# |
32-bit decimal value (e.g. 1000). |
Register |
R# |
Register address (e.g. R0). |
Label |
@label |
Label name string (e.g. @main). |
Labels¶
Any instruction can be preceded by a label. This label can be used as a reference to that specific instruction. In other words it can be used as a goto-point by any instruction that can alter program flow (i.e. jmp, jge, jlt and loop). The label must be followed by a ‘:’ character and a whitespace before the actual referenced instruction.
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)
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).
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.
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 and acquisition paths use the same format for these waveforms for different purposes. The AWG path uses these waveforms to parametrically generate pulses on it’s outputs and the acquisition path uses these waveforms as integration functions.
Waveform playback is started by the play and acquire instructions. Each waveform is paired with an index, which is used by these instructions 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. When waveforms are not played back-to-back, the intermediate time will be filled by samples with a value of zero.
The programmed waveforms can be retrieved using get_waveforms()
.
Note
The integration feature in the acquisition path is not implemented yet and the waveforms in that path are therefore not used.
Acquisitions¶
Acquisitions are started by the acquire instruction 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. Everytime an acquisisiton 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 be done by calling store_acquisition()
,
which moves the samples into the sequencer’s acquisition list located in the instrument’s RAM. 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 lists containing floating point values in a
range of 1.0 to -1.0 with a resolution of one nanosecond per sample. The list can be cleared by calling delete_acquisitions()
.
The acquisition path also has an averaging function set through the sequencer#_avg_mode_en_acq_path#()
parameters. This enables the automatic
accumulation of acquisitions, where sample N of acquistion 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_acquisition()
to store the
accumulated result in the acquisition list. Once retrieved from the instrument you will need to divide the accumulated samples 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.
Note
The acquisition path is still in development and more acquisitions modes will be added in the near future.
Continuous waveform mode¶
The sequencer also supports a continuous waveform mode of operation, where the sequence processor’s waveform playback control 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 be a multiple of four samples long (i.e. 4ns).
When in continuous mode, simply program, arm, start and stop the sequencer using the regular control functions and parameters (i.e. sequencer#_waveforms_and_program()
,
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 to program the sequence processor with a single
stop instruction.
Note
We realise that the current way of controlling this mode is not optimal, so in the near future we will be implementing additional driver support to streamline this mode.