miqro: docs

This commit is contained in:
Robert Jördens 2022-09-16 12:14:59 +00:00
parent 14ab1d4bbc
commit aedcf205c7
1 changed files with 104 additions and 70 deletions

View File

@ -47,7 +47,7 @@ PHASER_ADDR_SERVO_CFG1 = 0x31
# 0x32 - 0x71 servo coefficients + offset data # 0x32 - 0x71 servo coefficients + offset data
PHASER_ADDR_SERVO_DATA_BASE = 0x32 PHASER_ADDR_SERVO_DATA_BASE = 0x32
# 0x78 Miqro channel profile/window memories # 0x72 - 0x78 Miqro channel profile/window memories
PHASER_ADDR_MIQRO_MEM_ADDR = 0x72 PHASER_ADDR_MIQRO_MEM_ADDR = 0x72
PHASER_ADDR_MIQRO_MEM_DATA = 0x74 PHASER_ADDR_MIQRO_MEM_DATA = 0x74
@ -84,6 +84,19 @@ class Phaser:
Phaser contains a 4 channel, 1 GS/s DAC chip with integrated upconversion, Phaser contains a 4 channel, 1 GS/s DAC chip with integrated upconversion,
quadrature modulation compensation and interpolation features. quadrature modulation compensation and interpolation features.
The coredevice RTIO PHY and the Phaser gateware come in different modes
that have different features. Phaser mode and coredevice PHY are both
both selected at gateware compile-time and need to match.
Phaser gateware | Coredevice PHY | Features per :class:`PhaserChannel`
--------------- | -------------- | -----------------------------------
Base <= v0.5 | Base | Base (5 :class:`PhaserOscillator`)
Base >= v0.6 | Base | Base + Servo
Miqro >= v0.6 | Miqro | :class:`Miqro`
Base mode
---------
The coredevice produces 2 IQ (in-phase and quadrature) data streams with 25 The coredevice produces 2 IQ (in-phase and quadrature) data streams with 25
MS/s and 14 bit per quadrature. Each data stream supports 5 independent MS/s and 14 bit per quadrature. Each data stream supports 5 independent
numerically controlled IQ oscillators (NCOs, DDSs with 32 bit frequency, 16 numerically controlled IQ oscillators (NCOs, DDSs with 32 bit frequency, 16
@ -114,6 +127,16 @@ class Phaser:
absolute phase with respect to other RTIO input and output events absolute phase with respect to other RTIO input and output events
(see `get_next_frame_mu()`). (see `get_next_frame_mu()`).
Miqro mode
----------
See :class:`Miqro`
Here the DAC operates in 4x interpolation.
Analog flow
-----------
The four analog DAC outputs are passed through anti-aliasing filters. The four analog DAC outputs are passed through anti-aliasing filters.
In the baseband variant, the even/in-phase DAC channels feed 31.5 dB range In the baseband variant, the even/in-phase DAC channels feed 31.5 dB range
@ -131,6 +154,9 @@ class Phaser:
configured through a shared SPI bus that is accessed and controlled via configured through a shared SPI bus that is accessed and controlled via
FPGA registers. FPGA registers.
Servo
-----
Each phaser output channel features a servo to control the RF output amplitude Each phaser output channel features a servo to control the RF output amplitude
using feedback from an ADC. The servo consists of a first order IIR (infinite using feedback from an ADC. The servo consists of a first order IIR (infinite
impulse response) filter fed by the ADC and a multiplier that scales the I impulse response) filter fed by the ADC and a multiplier that scales the I
@ -1290,90 +1316,98 @@ class Miqro:
""" """
Miqro pulse generator. Miqro pulse generator.
Notes A Miqro instance represents one RF output. The DSP components are fully
----- contained in the Phaser gateware. The output is generated by with
* The annotation that some operation is "expensive" does not mean it is impossible, just the following data flow:
that it may take a significant amount of time and resources to execute such that
it may be impractical when used often or during fast pulse sequences.
They are intended for use in calibration and initialization.
Functionality Oscillators
------------- ...........
A Miqro instance represents one RF output.
The output is generated by with the following data flow:
### Oscillators
* There are n_osc = 16 oscillators with oscillator IDs 0..n_osc-1. * There are n_osc = 16 oscillators with oscillator IDs 0..n_osc-1.
* Each oscillator outputs one tone at any given time * Each oscillator outputs one tone at any given time
I/Q (quadrature, a.k.a. complex) 2x16 bit signed data
at tau = 4 ns sample intervals, 250 MS/s, Nyquist 125 MHz, bandwidth 200 MHz * I/Q (quadrature, a.k.a. complex) 2x16 bit signed data
(from f = -100..+100 MHz, taking into account the interpolation anti-aliasing at tau = 4 ns sample intervals, 250 MS/s, Nyquist 125 MHz, bandwidth 200 MHz
filters in subsequent interpolators), (from f = -100..+100 MHz, taking into account the interpolation anti-aliasing
32 bit frequency (f) resolution (~ 1/16 Hz), filters in subsequent interpolators),
16 bit unsigned amplitude (a) resolution * 32 bit frequency (f) resolution (~ 1/16 Hz),
16 bit phase (p) resolution * 16 bit unsigned amplitude (a) resolution
* 16 bit phase offset (p) resolution
* The output phase p' of each oscillator at time t (boot/reset/initialization of the * The output phase p' of each oscillator at time t (boot/reset/initialization of the
device at t=0) is then p' = f*t + p (mod 1 turn) where f and p are the device at t=0) is then p' = f*t + p (mod 1 turn) where f and p are the (currently
(currently active) profile frequency and phase. active) profile frequency and phase offset.
The terms "phase coherent" and "phase tracking" are defined to refer to this * Note: The terms "phase coherent" and "phase tracking" are defined to refer to this
choice of oscillator output phase p'. choice of oscillator output phase p'. Note that the phase offset p is not relative to
Note that the phase p is not accumulated (on top of previous (on top of previous phase/profiles/oscillator history).
phases, previous profiles, or oscillator history). It is "absolute" in the It is "absolute" in the sense that frequency f and phase offset p fully determine
sense that frequency f and phase p fully determine oscillator oscillator output phase p' at time t. This is unlike typical DDS behavior.
output phase p' at time t. This is unlike typical DDS behavior.
* Frequency, phase, and amplitude of each oscillator are configurable by selecting one of * Frequency, phase, and amplitude of each oscillator are configurable by selecting one of
n_profile = 32 profiles 0..n_profile-1. This selection is fast and can be done for n_profile = 32 profiles 0..n_profile-1. This selection is fast and can be done for
each pulse. The phase coherence defined above is guaranteed for each each pulse. The phase coherence defined above is guaranteed for each
profile individually. profile individually.
* Note: one profile per oscillator (usually profile index 0) should be reserved * Note: one profile per oscillator (usually profile index 0) should be reserved
for the NOP (no operation, identity) profile, usually with zero for the NOP (no operation, identity) profile, usually with zero amplitude.
amplitude.
* Data for each profile for each oscillator can be configured * Data for each profile for each oscillator can be configured
individually. Storing profile data should be considered "expensive". individually. Storing profile data should be considered "expensive".
* Note: The annotation that some operation is "expensive" does not mean it is
impossible, just that it may take a significant amount of time and
resources to execute such that it may be impractical when used often or
during fast pulse sequences. They are intended for use in calibration and
initialization.
Summation
.........
### Summation
* The oscillator outputs are added together (wrapping addition). * The oscillator outputs are added together (wrapping addition).
* The user must ensure that the sum of oscillators outputs does * The user must ensure that the sum of oscillators outputs does not exceed the
not exceed the (16 bit signed) data range. In general that means that the sum of the data range. In general that means that the sum of the amplitudes must not
amplitudes must not exceed the range. exceed one.
### Shaper Shaper
* The summed output stream is then multiplied with a the complex-valued output of a ......
triggerable shaper.
* Triggering the shaper corresponds to passing a pulse from all * The summed complex output stream is then multiplied with a the complex-valued
oscillators to the RF output. output of a triggerable shaper.
* Selected profiles become active simultaneously * Triggering the shaper corresponds to passing a pulse from all oscillators to
(on the same output sample) when triggering the shaper. the RF output.
* The shaper reads (replays) window samples from a memory of size n_window = 1 << 10 starting * Selected profiles become active simultaneously (on the same output sample) when
and stopping at memory locations specified. triggering the shaper with the first shaper output sample.
* Each window memory segment starts with a header determining segment * The shaper reads (replays) window samples from a memory of size n_window = 1 << 10.
length and interpolation parameters.
* The window samples are interpolated by a factor (rate change)
between 1 and r = 1 << 12.
* The interpolation order is constant, linear, quadratic, or cubic. This
corresponds to interpolation modes from rectangular window (1st order CIC)
or zero order hold) and to Parzen window (4th order CIC, cubic spline).
* This results in support for pulse lengths of between tau and a bit more than
r * n_window * tau = (1 << 12 + 10) tau ~ 17 ms.
* Windows can be configured to be head-less and/or tail-less, meaning, they
do not feed zero-amplitude samples into the shaper before and after
each window. This is used to implement pulses with arbitrary length or
CW output.
* The window memory can be segmented by choosing different start indices * The window memory can be segmented by choosing different start indices
to support different windows. to support different windows.
* Each window memory segment starts with a header determining segment
length and interpolation parameters.
* The window samples are interpolated by a factor (rate change) between 1 and
r = 1 << 12.
* The interpolation order is constant, linear, quadratic, or cubic. This
corresponds to interpolation modes from rectangular window (1st order CIC)
or zero order hold) to Parzen window (4th order CIC or cubic spline).
* This results in support for single shot pulse lengths (envelope support) between
tau and a bit more than r * n_window * tau = (1 << 12 + 10) tau ~ 17 ms.
* Windows can be configured to be head-less and/or tail-less, meaning, they
do not feed zero-amplitude samples into the shaper before and after
each window respectively. This is used to implement pulses with arbitrary
length or CW output.
Overall properties
..................
### Overall properties
* The DAC may upconvert the signal by applying a frequency offset f1 with * The DAC may upconvert the signal by applying a frequency offset f1 with
phase p1. phase p1.
* In the Upconverter Phaser variant, the analog quadrature upconverter * In the Upconverter Phaser variant, the analog quadrature upconverter
applies another frequency of f2 and phase p2. applies another frequency of f2 and phase p2.
* The resulting phase of the signal at the SMA output is * The resulting phase of the signal from one oscillator at the SMA output is
(f + f1 + f2)*t + p + s(t - t0) + p1 + p2 (mod 1 turn) (f + f1 + f2)*t + p + s(t - t0) + p1 + p2 (mod 1 turn)
where s(t - t0) is the phase of the interpolated where s(t - t0) is the phase of the interpolated
shaper output, and t0 is the trigger time (fiducial of the shaper). shaper output, and t0 is the trigger time (fiducial of the shaper).
Unsurprisingly the frequency is the derivative of the phase. Unsurprisingly the frequency is the derivative of the phase.
* Group delays between pulse parameter updates are matched across oscillators,
shapers, and channels.
* The minimum time to change profiles and phase offsets is ~128 ns (estimate, TBC). * The minimum time to change profiles and phase offsets is ~128 ns (estimate, TBC).
This is the minimum pulse interval. This is the minimum pulse interval.
The sustained pulse rate of the RTIO PHY/Fastlink is one pulse per Fastlink frame
(may be increased, TBC).
""" """
def __init__(self, channel): def __init__(self, channel):
@ -1458,7 +1492,7 @@ class Miqro:
for iqi in iq for iqi in iq
] ]
self.set_window_mu(start, iq_mu, rate, shift, order, head, tail) self.set_window_mu(start, iq_mu, rate, shift, order, head, tail)
return rate return rate*4*ns
@kernel @kernel
def encode(self, window, profiles, data): def encode(self, window, profiles, data):