sawg: expose config channel

This commit is contained in:
Robert Jördens 2017-05-22 18:27:32 +02:00
parent 4901cb9a8a
commit 1562f79101
2 changed files with 177 additions and 3 deletions

View File

@ -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,

View File

@ -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