LINQ-Based Feedback#
Every Q1 sequencer has a low-latency hardware feedback system that enables real-time data sharing between Q1 sequencers within a Qblox Cluster.
This capability is essential for advanced quantum operations, including:
Repeat until success
Conditional branching of the Q1 core program
Conditional playback
Real-time qubit calibrations
PID controllers for qubit stabilization
LINQ allows a source sequencer to transmit payloads—thresholded bits (TB), IQ values, time-tags and TTL counts, and immediates and registers—to one or many receiver sequencers in real-time.
The overall data flow is: the source sequencer sends data tagged with an id, the cluster routes that data
based on the routing configuration for that id, and the destination sequencer receives it via its feedback queue.
For an overview of LINQ-based feedback commands (see the Q1 instruction reference).
Data Routing#
Every data item a sequencer sends is tagged with an id (an 8-bit immediate in Q1ASM). This id serves three purposes:
Routing control: The
iddetermines which sequencers receive the data (see Routing Configuration below).IDs 1–15 are reserved for self-cast, which returns data exclusively to the originating sequencer.
IDs 16–255 can be configured for intra-cast, multi-cast, or broadcast routing, which return data to other sequencers than the originating sequencer.
Selective receiving: On the receiver side,
ids are used to filter feedback queue entries:fb_pop_data I, Rretrieves data with the specificidgiven inI, discards all preceding queue entries, and stores the matching value in registerR(see Figure 2).fb_pull_data R0, R1performs standard FIFO retrieval: it fetches the next available entry, storing theidinR0and the value inR1(see Figure 3).
Disabling sharing: Setting
idto0disables sharing of the respective data type for the next acquisition. Use this to dynamically enable or disable sharing without changing the sequencer program structure.
Routing Configuration#
The routing configuration determines which sequencers receive data for a given id (as can be seen in
Figure 1). Correct configuration prevents irrelevant data from filling the feedback queue.
Figure 1: Click on the Routing type to highlight the Routes.
There are four routing modes, set via the sequencer configuration:
Self-cast: Data is sent only to the originating sequencer.
Intra-cast: Data is sent to selected sequencers within the same module.
Multi-cast: Data is sent to selected sequencers across modules via the CMM route.
Broadcast: Data is sent to all sequencers in the cluster via the CMM route. Broadcast is equivalent to multi-cast targeting every sequencer in the cluster.
See also
Data latency depends on the routing path (multi-cast/broadcast, intra-cast, or self-cast), the data type, and data size. See the latencies section.
IDs 1–15 default to self-cast. Self-cast is always enabled; data automatically streams back to the originating sequencer with no additional configuration.
IDs 16–255 default to discard. Intra-cast and multi-cast are disabled by default and any data assigned these ids is
dropped. To enable intra-cast, multi-cast, or broadcast routing, configure the router before sending data.
Use the following Python API methods to configure routing:
Command |
Description |
|---|---|
|
Reset all routing to factory defaults. |
|
Intra-cast: route |
|
Multi-cast: route |
|
Broadcast: route |
|
Reset a module’s router configuration to factory defaults. |
|
Retrieve the router configuration for the module. |
See the API documentation for Cluster.set_cmm_route(), QRM.set_local_route(), Cluster.set_broadcast(),
Cluster.clear_router(), QRM.clear_router(), and QRM.get_router_config() for full parameter details.
Example
# 1. Broadcast data with id 16 to all sequencers in all modules
cluster.set_broadcast(16)
# 2. Multi-cast data with id 17 to all sequencers in module5 and sequencer0 in module3
cluster.set_cmm_route(17, [module5, module3.sequencer0])
# 3. Intra-cast data with id 19 to only sequencer1 and sequencer4 in module4
module4.set_local_route(19, [module4.sequencer1, module4.sequencer4])
# Reset all routers in the cluster to factory defaults
cluster.clear_router()
# Reset only the router for module3 to factory defaults
module3.clear_router()
See the LINQ Routing Configuration tutorial for a step-by-step example of configuring LINQ routing.
Data Receiving#
Incoming data arrives at the Q1 core in a dedicated feedback queue. This queue has a fixed capacity of 32 entries, each 32 bits wide.
There are two ways to retrieve data from the feedback queue:
Selective pop by
id:fb_pop_data id:I8, data:RFIFO pull:
fb_pull_data id_dest:R, data:R
fb_pop_data#
fb_pop_data is a Q1 core command, not a real-time instruction. It executes on the Q1 core
and takes 4 ns Q1 execution time (one register write).
The id operand is an 8-bit immediate, it must be a compile-time constant, not a register value.
The command discards all feedback queue entries preceding the target id, then stores the matching entry’s data in the
specified register.
The video below shows the Q1 core targeting id 7: it discards all preceding entries until it finds the entry with id
7.
fb_pull_data#
fb_pull_data performs a standard FIFO retrieval without filtering by id. It fetches the next available entry from
the feedback queue, storing the id in the first register and the data in the second.
Because fb_pull_data writes two registers, it takes 8 ns Q1 execution time.
Warning
The sections above assume LINQ data is already present in the feedback queue before calling
fb_pop_data or fb_pull_data.
If
fb_pull_datais called when the queue is empty, orfb_pop_datais called when no entry with the requestedidis present, the Q1 core blocks until a matching entry arrives.While the Q1 core is blocked, if the RT core exhausts its RT queue, the sequencer raises a
SEQUENCE_PROCESSOR_RT_EXEC_COMMAND_UNDERFLOWerror.
See below for how to suppress this error when data arrival time is unknown.
The recommended approach is to account for the Q1-to-Q1 latencies and ensure the receiving sequencer’s RT queue does not run out while the Q1 core waits for data.
When data arrival time is non-deterministic, suppress the SEQUENCE_PROCESSOR_RT_EXEC_COMMAND_UNDERFLOW error by
issuing a real-time instruction with duration = 0 immediately before fb_pop_data or fb_pull_data.
Note
duration = 0 is a special value that suspends the RT underflow guard. It is an exception to the
4 ns minimum described in the sequencer documentation.
When the RT core executes an instruction with duration = 0 (e.g. wait 0), it executes the instruction and 4 ns later
attempts to pop the next RT instruction. If the RT queue is empty at that point, the RT core waits until the next
instruction arrives, then pops and executes it.
When the RT core executes an instruction with a non-zero duration, the underflow guard is re-enabled.
Example
Selectively popping data with id 16:
wait 0 # suspend RT underflow guard; wait indefinitely
fb_pop_data 16, R1 # pop data with id 16 into R1 as soon as it arrives
Pulling the first available entry in FIFO order:
wait 0 # suspend RT underflow guard; wait indefinitely
fb_pull_data R0, R1 # pull next entry: id → R0, data → R1
Important
Using wait 0 before fb_pop_data or fb_pull_data forces synchronization between the
Q1 core and the RT core. The next real-time instruction will not execute
until the Q1 core completes the pop or pull, including its Q1 execution time. Account for this
when planning the RT timeline.
Data Sharing#
Sequencers can transmit Q1 immediates and registers, IQ values, thresholded bits (TB), time-tags, and TTL counts via LINQ.
All Q1 commands that enable/disable sharing or that are used for configuration are real-time instructions executed
by the RT core. Each takes a duration argument specifying how long the RT core waits before executing the next RT
instruction.
The interactive figure below maps supported data types to sequencer types.
Figure 4: Click on the sequencer type to highlight the supported datatypes.
Readout Sequencer Data Types#
Knowledge of TB and IQ values in real time is essential for active feedback in quantum circuits.
Readout sequencers can share TB and IQ values in real time with multiple Q1 sequencers in the cluster.
Warning
When sharing TB or IQ values, the ReadoutSequencer.integration_length_acq() parameter decides when the measurement is sent over LINQ.
See the Sharing Measurement Results with LINQ-based Feedback tutorial for a step-by-step example of using LINQ-based feedback with a readout sequencer.
Thresholded Bits#
Enable sending thresholded bits (TB) from a readout sequencer with the following command (see the Q1 instruction reference):
fb_acq_tb_id id:I8/R, duration:I16
This sets the id attached to the TB when sent via LINQ. TB are transmitted as 2-bit values: bit 0 is the thresholded
bit result; bit 1 is a validation bit (default: 1). TB are automatically sent at the end of the acquisition window.
To override the default validation bit value, use fb_acq_tb_valid valid_bit:I1, duration:I16.
Write-Combine Mode#
When many qubits are measured simultaneously, the number of TB can exceed the feedback queue capacity. Write-combine mode packs TB from multiple sequencers into a single 32-bit entry, reducing queue pressure.
Prerequisite: all participating acquisitions must end at the same time on the RT core.
Configure write-combine mode with:
fb_acq_tb_cfg write_combine:I1, bit_pos:I10, length:I7, duration:I16
write_combine—1to enable,0to disable.bit_pos— starting bit position in the shared payload where this sequencer writes its 2-bit TB.length— total length of the shared payload, in bytes.duration— RT wait time after this command, in ns.
Example
Two readout sequencers each contribute one TB to a shared 1-byte payload at id 16.
Sequencer 0 (writes to bit position 0):
fb_acq_tb_id 16, 8 # id = 16, wait 8 ns
fb_acq_tb_cfg 1, 0, 1, 8 # write-combine on; bit_pos=0; length=1 byte; wait 8 ns
acquire 0, 0, 200 # acquire for 200 ns
fb_acq_tb_id 0, 8 # id = 0 disables TB sharing for next acquisition
Sequencer 1 (writes to bit position 2):
fb_acq_tb_id 16, 8 # id = 16, wait 8 ns
fb_acq_tb_cfg 1, 2, 1, 8 # write-combine on; bit_pos=2; length=1 byte; wait 8 ns
acquire 0, 0, 200 # acquire for 200 ns
fb_acq_tb_id 0, 8 # id = 0 disables TB sharing for next acquisition
After acquisition (if the integrated signal does not pass the threshold), both sequencers send their TB to id = 16. The combined 1-byte payload layout:
Bit position |
b7 |
b6 |
b5 |
b4 |
b3 |
b2 |
b1 |
b0 |
|---|---|---|---|---|---|---|---|---|
Meaning |
- |
- |
- |
- |
valid |
data |
valid |
data |
Value |
0 |
0 |
0 |
0 |
1 |
0 |
1 |
0 |
After executing fb_pop_data 16, R1 on a receiving sequencer: R1 = 0b00001010.
See the Combining Thresholded Bits via LINQ tutorial for a step-by-step example of using write-combine mode to share TB from readout sequencers.
IQ Values#
Enable sending IQ values from a readout sequencer with:
fb_acq_iq_id id:I8/R, duration:I16
IQ data is transmitted as two consecutive 32-bit entries: the first carries the I value, the second carries the Q value. Both are sent at the end of the acquisition window.
Note
The received 32-bit signed integer encodes the normalized integration-path value v ∈ [-1, 1]
as linq_val = floor(v × 2^22). To recover the normalized float from a LINQ register value,
apply the inverse: v ≈ linq_val / 2^22.
The integration accumulator is 48 bits wide, but LINQ transmits only 32 bits. By default, the lower 32 bits are sent. At low signal levels or short integration windows this is fine — the signal lives in the lower bits. At high power or long integration times, however, the accumulated value grows into the upper bits of the 48-bit result, leaving only noise in the lower 32 bits that LINQ transmits by default. The receiver then reads meaningless data.
To shift the transmitted window up through the accumulator, use:
fb_acq_iq_shift shift:I8, duration:I16
shift moves the 32-bit transmission window upward by shift bits, selecting bits [31+shift : shift] of the 48-bit
accumulator instead of the default [31:0]. The lowest shift bits are discarded, but because the signal is concentrated
in the upper bits, no meaningful information is lost — the reduction in nominal resolution does not affect the result.
Apply a shift whenever signal power or integration time is high enough that the accumulator value would otherwise
overflow the lower 32-bit window.
Example
Readout sequencer sending IQ values at id 36, right-shifted by 8 bits:
fb_acq_iq_id 36, 8 # id = 36, wait 8 ns
fb_acq_iq_shift 8, 8 # right-shift IQ by 8 bits, wait 8 ns
acquire 0, 0, 200 # acquire for 200 ns
fb_acq_iq_id 0, 8 # id = 0 disables IQ sharing for next acquisition
IQ data occupies two consecutive feedback queue entries. Pop them separately on the receiving sequencer:
fb_pop_data 36, R1 # pop I value → R1
fb_pop_data 36, R2 # pop Q value → R2
Time-Tag Sequencer Data Types#
For optically addressable qubits, real-time feedback on photon emission — TTL counts and time-tags — is a key factor in synchronizing quantum network nodes and mitigating dephasing noise in Bell states.
Time-tag sequencers can share TTL counts and time-tags in real time with multiple Q1 sequencers in the cluster.
There are four data variants available from the time-tag sequencer: Low-Latency Time-Tags, Low-Latency TTL Counts, High-Resolution Time-Tags, Time Delta, listed below.
See the LINQ-based feedback with QTM tutorial for a step-by-step example of using LINQ-based feedback with a time-tag sequencer.
Low-Latency TTL Counts#
Enable sending TTL (photon-detection event) counts with:
fb_llp_ttls_id id:I8/R, duration:I16
This sends the count of detected TTL events above the user-defined threshold. The count is transmitted at the end of the acquisition window.
Example
Time-tag sequencer sending photon counts at id 36:
fb_llp_ttls_id 36, 8 # id = 36, wait 8 ns
acquire_timetags 0, 0, 1, 0, 4 # open acquisition window
wait 400 # wait 400 ns
acquire_timetags 0, 0, 0, 0, 4 # close acquisition window
fb_llp_ttls_id 0, 8 # id = 0 disables TTL count sharing
Time Delta#
Enable sending the time delta between two detected events with:
fb_tdc_tdelta_id id:I8/R, duration:I16
Configure one channel as the time reference (io_channelX) and another as the time source (io_channelY). Both
channels can be the same physical channel. The sequencer computes the difference between the two timestamps and sends
the result with 1/128 ns resolution and a ±16.7 ms range via LINQ.
Example
Configure the time reference and time source using the QCoDeS API, then enable transmission in Q1ASM.
moduleX.io_channelX.binned_acq_time_ref("firstX") # time reference: first event on channel X
moduleX.io_channelY.binned_acq_time_source("second") # time source: event on channel Y
Q1ASM for the time-tag sequencer:
fb_tdc_tdelta_id 36, 8 # id = 36, wait 8 ns
acquire_timetags 0, 0, 1, 0, 4 # open acquisition window
wait 400 # wait 400 ns
acquire_timetags 0, 0, 0, 0, 4 # close acquisition window
fb_tdc_tdelta_id 0, 8 # id = 0 disables time-delta sharing
Q1 Immediates and Registers#
All Q1 sequencer types can share register values or immediates. Use:
fb_com_data id:I8, value:I32/R, duration:I16
This sends the value of register R or a 32-bit immediate with the specified id. The RT core then waits duration ns
before executing the next instruction.
Example
Sequencer sending the value of R0 at id 36:
fb_com_data 36, R0, 8 # id = 36, value from R0, wait 8 ns
The routing configuration for id 36 determines which sequencers receive this value in their
feedback queue.
Additional configuration commands fb_com_cfg and fb_com_extra are available; see the
Q1 instruction reference.
See the Sharing Q1 Registers and Immediates tutorial for a step-by-step example of sharing Q1 register values via LINQ.
Latencies of LINQ-Based Feedback Data Types#
Latency is defined as the time for data to travel from the source sequencer’s Q1 core to the destination sequencer’s feedback queue, excluding input/output signal paths.
Latency depends on the routing path, data type, data size, and sequencer type.
Sequencer Type |
Data type |
Multi-cast (ns) |
Intra-cast (ns) |
Self-cast (ns) |
|---|---|---|---|---|
Readout |
Thresholded Bits |
472 |
250 |
160 |
IQ Values |
492 |
270 |
164 |
|
Time-tag |
High-resolution time-tags |
1260 |
1000 |
910 |
Time delta |
1260 |
1000 |
910 |
|
TTL counts |
480 |
236 |
146 |
|
Low-latency time-tags |
480 |
236 |
146 |
|
All |
Q1 registers / immediates |
380 |
150 |
60 |
For complete round-trip latency including the input and output signal paths of specific modules, use the interactive table below.
Table 1: Interactive table to calculate input-output latencies.
Note
The QTM has a negative input latency of -66 ns. The acquisition window on the QTM starts
after the acquire_timetags command is issued, which shifts the time grid relative to the Q1
instruction timeline. As a result, the effective input latency appears negative when referenced to
that timeline.