forked from M-Labs/artiq
sawg: expose config channel
This commit is contained in:
parent
4901cb9a8a
commit
1562f79101
|
@ -1,4 +1,160 @@
|
||||||
|
from artiq.language.types import TInt32, TBool
|
||||||
|
from artiq.language.core import kernel, now_mu
|
||||||
from artiq.coredevice.spline import Spline
|
from artiq.coredevice.spline import Spline
|
||||||
|
from artiq.coredevice.rtio import rtio_output
|
||||||
|
|
||||||
|
|
||||||
|
# sawg.Config addresses
|
||||||
|
_SAWG_DIV = 0
|
||||||
|
_SAWG_CLR = 1
|
||||||
|
_SAWG_IQ_EN = 2
|
||||||
|
# _SAWF_PAD = 3 # reserved
|
||||||
|
_SAWG_DUC_I_MIN = 4
|
||||||
|
_SAWG_DUC_I_MAX = 5
|
||||||
|
_SAWG_DUC_Q_MIN = 6
|
||||||
|
_SAWG_DUC_Q_MAX = 7
|
||||||
|
_SAWG_OUT_MIN = 8
|
||||||
|
_SAWG_OUT_MAX = 9
|
||||||
|
|
||||||
|
|
||||||
|
class Config:
|
||||||
|
"""SAWG configuration.
|
||||||
|
|
||||||
|
Exposes the configurable quantities of a single SAWG channel.
|
||||||
|
|
||||||
|
:param channel: RTIO channel number of the channel.
|
||||||
|
:param core: Core device.
|
||||||
|
"""
|
||||||
|
kernel_invariants = {"channel", "core"}
|
||||||
|
|
||||||
|
def __init__(self, channel, core):
|
||||||
|
self.channel = channel
|
||||||
|
self.core = core
|
||||||
|
|
||||||
|
@kernel
|
||||||
|
def set_div(self, div: TInt32, n: TInt32=0):
|
||||||
|
"""Set the spline evolution divider and current counter value.
|
||||||
|
|
||||||
|
The divider and the spline evolution are synchronized across all
|
||||||
|
spline channels within a SAWG channel. The phase accumulator always
|
||||||
|
evolves at full speed.
|
||||||
|
|
||||||
|
:param div: Spline evolution divider, such that
|
||||||
|
``t_sawg_spline/t_rtio_coarse = div + 1``. Default: ``0``.
|
||||||
|
:param n: Current value of the counter. Default: ``0``.
|
||||||
|
"""
|
||||||
|
rtio_output(now_mu(), self.channel, _SAWG_DIV, div | (n << 16))
|
||||||
|
|
||||||
|
@kernel
|
||||||
|
def set_clr(self, clr0: TBool, clr1: TBool, clr2: TBool):
|
||||||
|
"""Set the phase clear mode for the three phase accumulators.
|
||||||
|
|
||||||
|
When the ``clr`` bit for a given phase accumulator is
|
||||||
|
set, that phase accumulator will be cleared with every phase RTIO
|
||||||
|
command and the output phase will be exactly the phase RTIO value
|
||||||
|
("absolute phase update mode").
|
||||||
|
|
||||||
|
In turn, when the bit is cleared, the phase RTIO channels only
|
||||||
|
provide a phase offset to the current value of the phase
|
||||||
|
accumulator ("relative phase update mode").
|
||||||
|
|
||||||
|
:param clr0: Auto-clear phase accumulator of the ``phase0``/
|
||||||
|
``frequency0`` DUC. Default: ``True``
|
||||||
|
:param clr1: Auto-clear phase accumulator of the ``phase1``/
|
||||||
|
``frequency1`` DDS. Default: ``True``
|
||||||
|
:param clr2: Auto-clear phase accumulator of the ``phase2``/
|
||||||
|
``frequency2`` DDS. Default: ``True``
|
||||||
|
"""
|
||||||
|
rtio_output(now_mu(), self.channel, _SAWG_CLR, int(clr1) |
|
||||||
|
(int(clr2) << 1) | (int(clr0) << 2))
|
||||||
|
|
||||||
|
@kernel
|
||||||
|
def set_iq_en(self, i_enable: TBool, q_enable: TBool):
|
||||||
|
"""Enable I/Q data on this DAC channel.
|
||||||
|
|
||||||
|
Every pair of SAWG channels forms a buddy pair.
|
||||||
|
The ``iq_en`` configuration controls which DDS data is emitted to the
|
||||||
|
DACs.
|
||||||
|
|
||||||
|
Refer to the documentation of :class:`SAWG` for a mathematical
|
||||||
|
description of ``i_enable`` and ``q_enable``.
|
||||||
|
|
||||||
|
:param i_enable: Controls adding the in-phase
|
||||||
|
DUC-DDS data of *this* SAWG channel to *this* DAC channel.
|
||||||
|
Default: ``1``.
|
||||||
|
:param q_enable: controls adding the quadrature
|
||||||
|
DUC-DDS data of this SAWG's *buddy* channel to *this* DAC
|
||||||
|
channel. Default: ``0``.
|
||||||
|
"""
|
||||||
|
rtio_output(now_mu(), self.channel, _SAWG_IQ_EN, int(i_enable) |
|
||||||
|
(int(q_enable) << 1))
|
||||||
|
|
||||||
|
@kernel
|
||||||
|
def set_duc_i_max(self, limit: TInt32):
|
||||||
|
"""Set the DUC I data summing junction upper limit.
|
||||||
|
|
||||||
|
Each of the three summing junctions has a saturating adder with
|
||||||
|
configurable upper and lower limits. The three summing junctions are:
|
||||||
|
|
||||||
|
* At the in-phase input to the ``phase0``/``frequency0`` fast DUC,
|
||||||
|
where the in-phase outputs of the two slow DDS (1 and 2) are
|
||||||
|
added together.
|
||||||
|
* At the quadrature input to the ``phase0``/``frequency0``
|
||||||
|
fast DUC, where the quadrature outputs of the two slow DDS
|
||||||
|
(1 and 2) are added together.
|
||||||
|
* Before the DAC, where the following three data streams
|
||||||
|
are added together:
|
||||||
|
|
||||||
|
* the output of the ``offset`` spline,
|
||||||
|
* (optionally, depending on ``i_enable``) the in-phase output
|
||||||
|
of the ``phase0``/``frequency0`` fast DUC, and
|
||||||
|
* (optionally, depending on ``q_enable``) the quadrature
|
||||||
|
output of the ``phase0``/``frequency0`` fast DUC of the
|
||||||
|
buddy channel.
|
||||||
|
|
||||||
|
Refer to the documentation of :class:`SAWG` for a mathematical
|
||||||
|
description of the summing junctions.
|
||||||
|
|
||||||
|
The default limits are the full range of signed 16 bit data.
|
||||||
|
|
||||||
|
.. seealso::
|
||||||
|
* :meth:`set_duc_i_max`: Upper limit of the in-phase input to
|
||||||
|
the DUC.
|
||||||
|
* :meth:`set_duc_i_min`: Lower limit of the in-phase input to
|
||||||
|
the DUC.
|
||||||
|
* :meth:`set_duc_q_max`: Upper limit of the quadrature input to
|
||||||
|
the DUC.
|
||||||
|
* :meth:`set_duc_q_min`: Lower limit of the quadrature input to
|
||||||
|
the DUC.
|
||||||
|
* :meth:`set_out_max`: Upper limit of the DAC output.
|
||||||
|
* :meth:`set_out_min`: Lower limit of the DAC output.
|
||||||
|
"""
|
||||||
|
rtio_output(now_mu(), self.channel, _SAWG_DUC_I_MAX, limit)
|
||||||
|
|
||||||
|
@kernel
|
||||||
|
def set_duc_i_min(self, limit: TInt32):
|
||||||
|
""".. seealso:: :meth:`set_duc_i_max`"""
|
||||||
|
rtio_output(now_mu(), self.channel, _SAWG_DUC_I_MIN, limit)
|
||||||
|
|
||||||
|
@kernel
|
||||||
|
def set_duc_q_max(self, limit: TInt32):
|
||||||
|
""".. seealso:: :meth:`set_duc_i_max`"""
|
||||||
|
rtio_output(now_mu(), self.channel, _SAWG_DUC_Q_MAX, limit)
|
||||||
|
|
||||||
|
@kernel
|
||||||
|
def set_duc_q_min(self, limit: TInt32):
|
||||||
|
""".. seealso:: :meth:`set_duc_i_max`"""
|
||||||
|
rtio_output(now_mu(), self.channel, _SAWG_DUC_Q_MIN, limit)
|
||||||
|
|
||||||
|
@kernel
|
||||||
|
def set_out_max(self, limit: TInt32):
|
||||||
|
""".. seealso:: :meth:`set_duc_i_max`"""
|
||||||
|
rtio_output(now_mu(), self.channel, _SAWG_OUT_MAX, limit)
|
||||||
|
|
||||||
|
@kernel
|
||||||
|
def set_out_min(self, limit: TInt32):
|
||||||
|
""".. seealso:: :meth:`set_duc_i_max`"""
|
||||||
|
rtio_output(now_mu(), self.channel, _SAWG_OUT_MIN, limit)
|
||||||
|
|
||||||
|
|
||||||
class SAWG:
|
class SAWG:
|
||||||
|
@ -13,8 +169,10 @@ class SAWG:
|
||||||
i_enable*Re(oscillators) +
|
i_enable*Re(oscillators) +
|
||||||
q_enable*Im(buddy_oscillators))
|
q_enable*Im(buddy_oscillators))
|
||||||
|
|
||||||
The nine spline interpolators are accessible as attributes:
|
The configuration channel and the nine spline interpolators are accessible
|
||||||
|
as attributes:
|
||||||
|
|
||||||
|
* :attr:`config`: :class:`Config`
|
||||||
* :attr:`offset`, :attr:`amplitude1`, :attr:`amplitude2`: in units
|
* :attr:`offset`, :attr:`amplitude1`, :attr:`amplitude2`: in units
|
||||||
of full scale
|
of full scale
|
||||||
* :attr:`phase0`, :attr:`phase1`, :attr:`phase2`: in units of turns
|
* :attr:`phase0`, :attr:`phase1`, :attr:`phase2`: in units of turns
|
||||||
|
@ -22,7 +180,8 @@ class SAWG:
|
||||||
of Hz
|
of Hz
|
||||||
|
|
||||||
:param channel_base: RTIO channel number of the first channel (amplitude).
|
:param channel_base: RTIO channel number of the first channel (amplitude).
|
||||||
Frequency and Phase are then assumed to be successive channels.
|
The configuration channel and frequency/phase/amplitude channels are
|
||||||
|
then assumed to be successive channels.
|
||||||
:param parallelism: Number of output samples per coarse RTIO clock cycle.
|
:param parallelism: Number of output samples per coarse RTIO clock cycle.
|
||||||
:param core_device: Name of the core device that this SAWG is on.
|
:param core_device: Name of the core device that this SAWG is on.
|
||||||
"""
|
"""
|
||||||
|
@ -37,7 +196,7 @@ class SAWG:
|
||||||
width = 16
|
width = 16
|
||||||
time_width = 16
|
time_width = 16
|
||||||
cordic_gain = 1.646760258057163 # Cordic(width=16, guard=None).gain
|
cordic_gain = 1.646760258057163 # Cordic(width=16, guard=None).gain
|
||||||
# cfg: channel_base
|
self.config = Config(channel_base, self.core)
|
||||||
self.offset = Spline(width, time_width, channel_base + 1,
|
self.offset = Spline(width, time_width, channel_base + 1,
|
||||||
self.core, 2.)
|
self.core, 2.)
|
||||||
self.amplitude1 = Spline(width, time_width, channel_base + 2,
|
self.amplitude1 = Spline(width, time_width, channel_base + 2,
|
||||||
|
|
|
@ -17,6 +17,21 @@ class SAWGTestTwoTone(EnvExperiment):
|
||||||
self.core.reset()
|
self.core.reset()
|
||||||
self.ttl_sma.output()
|
self.ttl_sma.output()
|
||||||
|
|
||||||
|
self.sawg0.config.set_clr(True, True, True)
|
||||||
|
delay(10*us)
|
||||||
|
self.sawg0.config.set_duc_i_max(0x7fff)
|
||||||
|
delay(10*us)
|
||||||
|
self.sawg0.config.set_duc_i_min(-0x8000)
|
||||||
|
delay(10*us)
|
||||||
|
self.sawg0.config.set_duc_q_max(0x7fff)
|
||||||
|
delay(10*us)
|
||||||
|
self.sawg0.config.set_duc_q_min(-0x8000)
|
||||||
|
delay(10*us)
|
||||||
|
self.sawg0.config.set_out_max(0x7fff)
|
||||||
|
delay(10*us)
|
||||||
|
self.sawg0.config.set_out_min(-0x8000)
|
||||||
|
delay(10*us)
|
||||||
|
|
||||||
while True:
|
while True:
|
||||||
t_up = t_hold = t_down = 800*ns
|
t_up = t_hold = t_down = 800*ns
|
||||||
a1 = .3
|
a1 = .3
|
||||||
|
|
Loading…
Reference in New Issue