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.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:
|
||||
|
@ -13,8 +169,10 @@ class SAWG:
|
|||
i_enable*Re(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
|
||||
of full scale
|
||||
* :attr:`phase0`, :attr:`phase1`, :attr:`phase2`: in units of turns
|
||||
|
@ -22,7 +180,8 @@ class SAWG:
|
|||
of Hz
|
||||
|
||||
: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 core_device: Name of the core device that this SAWG is on.
|
||||
"""
|
||||
|
@ -37,7 +196,7 @@ class SAWG:
|
|||
width = 16
|
||||
time_width = 16
|
||||
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.core, 2.)
|
||||
self.amplitude1 = Spline(width, time_width, channel_base + 2,
|
||||
|
|
|
@ -17,6 +17,21 @@ class SAWGTestTwoTone(EnvExperiment):
|
|||
self.core.reset()
|
||||
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:
|
||||
t_up = t_hold = t_down = 800*ns
|
||||
a1 = .3
|
||||
|
|
Loading…
Reference in New Issue