Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: m-labs/artiq
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: b41b9de905ef
Choose a base ref
...
head repository: m-labs/artiq
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: 9ba6be879605
Choose a head ref
  • 5 commits
  • 6 files changed
  • 1 contributor

Commits on Oct 14, 2016

  1. phaser: cleanup prbs

    jordens committed Oct 14, 2016
    Copy the full SHA
    9b43f09 View commit details
  2. sawg: absolute phase updates

    jordens committed Oct 14, 2016
    Copy the full SHA
    d16068d View commit details
  3. phaser: add another sawg demo

    jordens committed Oct 14, 2016
    Copy the full SHA
    4b4fd32 View commit details
  4. phaser: update README

    jordens committed Oct 14, 2016
    Copy the full SHA
    4968de0 View commit details
  5. Copy the full SHA
    9ba6be8 View commit details
14 changes: 12 additions & 2 deletions README_PHASER.rst
Original file line number Diff line number Diff line change
@@ -92,18 +92,28 @@ Setup
If the board was running stock ARTIQ before, the settings will be kept.
* A 2 GHz of roughly 10 dBm (0.2 to 3.4 V peak-to-peak into 50 Ohm) must be connected to the AD9154-FMC-EBZ J1.
The external RTIO clock, DAC deviceclock, FPGA deviceclock, and SYSREF are derived from this signal.
* An example device database, several status and test scripts are provided in ``artiq/examples/phaser/``. ::

cd artiq/examples/phaser

* Edit ``device_db.pyon`` to match the hostname or IP address of the core device.
* The ``startup_clock`` needs to be set to internal (``i``) for bootstrapping the clock distribution tree.
* Compile and flash the startup kernel in ``artiq/examples/phaser/startup_kernel.py``.
* Erase any possible idle kernels.
* Use ``ping`` and ``flterm`` to verify that the core device starts up and boots correctly.

Usage
-----

* An example device database, several status and test scripts are provided in ``artiq/examples/phaser/``.
* After each boot, run the ``dac_setup.py`` experiment to establish the JESD204B links (``artiq_run repository/dac_setup.py``).
* Run ``artiq_run repository/ad9154_test_status.py`` to retrieve and print several status registers from the AD9154 DAC.
* Run ``artiq_run repository/ad9154_test_prbs.py`` to test the JESD204B PHY layer for bit errors. Reboot the core device afterwards.
* Run ``artiq_run repository/ad9154_test_stpl.py`` to executes a JESD204B short transport layer test.
* Run ``artiq_run repository/sawg.py`` for an example that sets up amplitudes, frequencies, and phases on all four DDS channels.
* Run ``artiq_run repository/demo.py`` for an example that exercises several different use cases of synchronized phase, amplitude, and frequency updates.
for an example that exercises several different use cases of synchronized phase, amplitude, and frequency updates.
* Implement your own experiments using the SAWG channels.
* Verify clock stability between the 2 GHz reference clock and the DAC outputs.
* Verify phase alignment between the DAC channels.
* Changes to the AD9154 configuration can also be performed at runtime in experiments.
See the example ``dac_setup.py``.
This can e.g. be used to enable and evaluate mix mode without having to change any other code (bitstream/bios/runtime/startup_kernel).
2 changes: 1 addition & 1 deletion artiq/examples/phaser/repository/dac_setup.py
Original file line number Diff line number Diff line change
@@ -62,7 +62,7 @@ def run(self):

@kernel
def busywait_us(self, t):
t = now_mu() + seconds_to_mu(t*us)
t = self.core.get_rtio_counter_mu() + seconds_to_mu(t*us)
while self.core.get_rtio_counter_mu() < t:
pass

50 changes: 50 additions & 0 deletions artiq/examples/phaser/repository/demo.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
from artiq.experiment import *


class SAWGTest(EnvExperiment):
def build(self):
self.setattr_device("core")
self.setattr_device("led")
self.setattr_device("ttl_sma")

self.setattr_device("sawg0")
self.setattr_device("sawg1")
self.setattr_device("sawg2")
self.setattr_device("sawg3")

@kernel
def run(self):
self.core.break_realtime()
self.ttl_sma.output()

while True:
self.sawg0.set_amplitude(0.)
self.sawg0.set_frequency(0*MHz)
self.sawg1.set_amplitude(0.)
self.sawg1.set_frequency(0*MHz)
delay(20*ms)

self.sawg0.set_amplitude(.4)
self.sawg0.set_frequency(10*MHz)
self.sawg0.set_phase(0.)
self.sawg1.set_amplitude(.4)
self.sawg1.set_frequency(10*MHz)
self.sawg1.set_phase(0.)
self.ttl_sma.pulse(200*ns)
self.sawg1.set_amplitude(.1)
delay(200*ns)
self.sawg1.set_amplitude(-.4)
self.ttl_sma.pulse(200*ns)
self.sawg1.set_amplitude(.4)
delay(200*ns)
self.sawg1.set_phase(.25)
self.ttl_sma.pulse(200*ns)
self.sawg1.set_phase(.5)
delay(200*ns)
self.sawg0.set_phase(.5)
self.ttl_sma.pulse(200*ns)
self.sawg1.set_frequency(30*MHz)
delay(200*ns)
self.sawg1.set_frequency(10*MHz)
self.sawg1.set_phase(0.)
self.ttl_sma.pulse(200*ns)
29 changes: 20 additions & 9 deletions artiq/examples/phaser/repository/test_ad9154_prbs.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
import time

from artiq.coredevice.ad9154_reg import *
from artiq.experiment import *

@@ -9,14 +7,25 @@ def build(self):
self.setattr_device("core")
self.setattr_device("ad9154")

@kernel
def run(self):
for i in range(3): # prbs7, prbs15, prbs31
self.prbs(i, 100)
for e in range(2):
for i in range(3): # prbs7, prbs15, prbs31
self.prbs(i, 10, e)

@kernel
def busywait_us(self, t):
t = self.core.get_rtio_counter_mu() + seconds_to_mu(t*us)
while self.core.get_rtio_counter_mu() < t:
pass

def p(self, f, *a):
print(f % a)
print(f.format(*a))

def prbs(self, p, t, inject_errors=0):
@kernel
def prbs(self, p, t, inject_errors):
self.p("---\nprbs sequence {}, threshold {}, inject_errors {}:",
p, t, inject_errors)
self.ad9154.jesd_prbs((1 << p) | (inject_errors << 3))

self.ad9154.dac_write(AD9154_PHY_PRBS_TEST_CTRL,
@@ -35,15 +44,17 @@ def prbs(self, p, t, inject_errors=0):
self.ad9154.dac_write(AD9154_PHY_PRBS_TEST_CTRL,
AD9154_PHY_PRBS_PAT_SEL_SET(p) | AD9154_PHY_TEST_START_SET(1))

time.sleep(.5)
self.busywait_us(1000000)

self.ad9154.dac_write(AD9154_PHY_PRBS_TEST_CTRL, AD9154_PHY_PRBS_PAT_SEL_SET(p))

self.p("prbs status: 0x%02x", self.ad9154.dac_read(AD9154_PHY_PRBS_TEST_STATUS))
self.p("prbs status: {:#04x}", self.ad9154.dac_read(AD9154_PHY_PRBS_TEST_STATUS))

for i in range(8):
self.ad9154.dac_write(AD9154_PHY_PRBS_TEST_CTRL, AD9154_PHY_SRC_ERR_CNT_SET(i))
self.p("prbs errors[%d]: 0x%08x", i,
self.p("prbs errors[{}]: {:#08x}", i,
self.ad9154.dac_read(AD9154_PHY_PRBS_TEST_ERRCNT_LOBITS) |
(self.ad9154.dac_read(AD9154_PHY_PRBS_TEST_ERRCNT_MIDBITS) << 8) |
(self.ad9154.dac_read(AD9154_PHY_PRBS_TEST_ERRCNT_HIBITS) << 16))

self.ad9154.jesd_prbs(0)
3 changes: 3 additions & 0 deletions artiq/examples/phaser/repository/test_ad9154_status.py
Original file line number Diff line number Diff line change
@@ -7,13 +7,15 @@ def build(self):
self.setattr_device("core")
self.setattr_device("ad9154")

@kernel
def run(self):
self.print_status()
self.print_temp()

def p(self, f, *a):
print(f % a)

@kernel
def print_temp(self):
self.ad9154.dac_write(AD9154_DIE_TEMP_CTRL0, AD9154_AUXADC_RESERVED_SET(0x10) |
AD9154_AUXADC_ENABLE_SET(1))
@@ -23,6 +25,7 @@ def print_temp(self):
self.ad9154.dac_write(AD9154_DIE_TEMP_CTRL0, AD9154_AUXADC_RESERVED_SET(0x10) |
AD9154_AUXADC_ENABLE_SET(0))

@kernel
def print_status(self):
x = self.ad9154.dac_read(AD9154_IRQ_STATUS0)
self.p("LANEFIFOERR: %d, SERPLLLOCK: %d, SERPLLLOST: %d, "
5 changes: 3 additions & 2 deletions artiq/gateware/dsp/sawg.py
Original file line number Diff line number Diff line change
@@ -37,8 +37,10 @@ def __init__(self, width, parallelism=4):
If(self.f.stb,
eqh(q.i.f, self.f.f)
),
q.i.clr.eq(0),
If(self.p.stb,
eqh(q.i.p, self.p.p)
eqh(q.i.p, self.p.p),
q.i.clr.eq(1)
),
q.i.stb.eq(self.f.stb | self.p.stb),
]
@@ -47,7 +49,6 @@ def __init__(self, width, parallelism=4):
self.f.ack.eq(1),
self.p.ack.eq(1),
q.o.ack.eq(1),
q.i.clr.eq(0),
]

c = []