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: 3471ef80fdbc
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: 65ec6c28f4ef
Choose a head ref
  • 5 commits
  • 12 files changed
  • 1 contributor

Commits on Jul 4, 2015

  1. Copy the full SHA
    a615a38 View commit details
  2. Copy the full SHA
    753d61b View commit details
  3. remove unneeded import

    sbourdeauducq committed Jul 4, 2015
    Copy the full SHA
    504576d View commit details
  4. pxi6733: small cleanup

    sbourdeauducq committed Jul 4, 2015
    Copy the full SHA
    abd5866 View commit details
  5. Copy the full SHA
    65ec6c2 View commit details
1 change: 1 addition & 0 deletions artiq/coredevice/runtime.py
Original file line number Diff line number Diff line change
@@ -21,6 +21,7 @@
"ttl_set_oe": "Iib:n",
"ttl_set_sensitivity": "Iii:n",
"ttl_get": "iI:I",
"ttl_clock_set": "Iii:n",
"dds_init": "Ii:n",
"dds_batch_enter": "I:n",
"dds_batch_exit": "n:n",
83 changes: 76 additions & 7 deletions artiq/coredevice/ttl.py
Original file line number Diff line number Diff line change
@@ -26,7 +26,8 @@ def set_o(self, o):

@kernel
def sync(self):
"""Busy-waits until all programmed level switches have been effected."""
"""Busy-wait until all programmed level switches have been
effected."""
while syscall("rtio_get_counter") < self.o_previous_timestamp:
pass

@@ -37,20 +38,20 @@ def on(self):

@kernel
def off(self):
"""Sets the output to a logic low state."""
"""Set the output to a logic low state."""
self.set_o(False)

@kernel
def pulse_mu(self, duration):
"""Pulses the output high for the specified duration
"""Pulse the output high for the specified duration
(in machine units)."""
self.on()
delay_mu(duration)
self.off()

@kernel
def pulse(self, duration):
"""Pulses the output high for the specified duration
"""Pulse the output high for the specified duration
(in seconds)."""
self.on()
delay(duration)
@@ -103,18 +104,19 @@ def set_o(self, o):

@kernel
def sync(self):
"""Busy-waits until all programmed level switches have been effected."""
"""Busy-wait until all programmed level switches have been
effected."""
while syscall("rtio_get_counter") < self.o_previous_timestamp:
pass

@kernel
def on(self):
"""Sets the output to a logic high state."""
"""Set the output to a logic high state."""
self.set_o(True)

@kernel
def off(self):
"""Sets the output to a logic low state."""
"""Set the output to a logic low state."""
self.set_o(False)

@kernel
@@ -204,3 +206,70 @@ def timestamp(self):
If the gate is permanently closed, returns a negative value.
"""
return syscall("ttl_get", self.channel, self.i_previous_timestamp)


class TTLClockGen(AutoDB):
"""RTIO TTL clock generator driver.
This should be used with TTL channels that have a clock generator
built into the gateware (not compatible with regular TTL channels).
:param core: core device
:param channel: channel number
"""
class DBKeys:
core = Device()
channel = Argument()

def build(self):
# in RTIO cycles
self.previous_timestamp = int64(0)
self.acc_width = 24

@portable
def frequency_to_ftw(self, frequency):
"""Returns the frequency tuning word corresponding to the given
frequency.
"""
return round(2**self.acc_width*frequency*self.core.ref_period)

@portable
def ftw_to_frequency(self, ftw):
"""Returns the frequency corresponding to the given frequency tuning
word.
"""
return ftw/self.core.ref_period/2**self.acc_width

@kernel
def set_mu(self, frequency):
"""Set the frequency of the clock, in machine units.
This also sets the phase, as the time of the first generated rising
edge corresponds to the time of the call.
The clock generator contains a 24-bit phase accumulator operating on
the RTIO clock. At each RTIO clock tick, the frequency tuning word is
added to the phase accumulator. The most significant bit of the phase
accumulator is connected to the TTL line. Setting the frequency tuning
word has the additional effect of setting the phase accumulator to
0x800000.
"""
syscall("ttl_clock_set", now_mu(), self.channel, frequency)
self.previous_timestamp = now_mu()

@kernel
def set(self, frequency):
"""Like ``set_mu``, but using Hz."""
self.set_mu(self.frequency_to_ftw(frequency))

@kernel
def stop(self):
"""Stop the toggling of the clock and set the output level to 0."""
self.set_mu(0)

@kernel
def sync(self):
"""Busy-wait until all programmed frequency switches and stops have
been effected."""
while syscall("rtio_get_counter") < self.o_previous_timestamp:
pass
1 change: 0 additions & 1 deletion artiq/devices/pdq2/mediator.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
from artiq.language.core import *
from artiq.language.db import *
from artiq.language.units import *
from artiq.coredevice import ttl


frame_setup = 20*ns
8 changes: 5 additions & 3 deletions artiq/devices/pxi6733/driver.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
# Yann Sionneau <ys@m-labs.hk>, 2015

from ctypes import byref, c_ulong
import numpy as np
import logging

import numpy as np


logger = logging.getLogger(__name__)


@@ -40,7 +42,7 @@ def __init__(self, channels, clock):
self.task = None
self.daq = daq

def done_callback_py(self, taskhandle, status, callback_data):
def _done_callback(self, taskhandle, status, callback_data):
if taskhandle != self.task:
logger.warning("done callback called with unexpected task")
else:
@@ -113,7 +115,7 @@ def load_sample_values(self, sampling_freq, values):
if ret:
raise IOError("Error while writing samples to the channel buffer")

done_cb = self.daq.DAQmxDoneEventCallbackPtr(self.done_callback_py)
done_cb = self.daq.DAQmxDoneEventCallbackPtr(self._done_callback)
self.task = t.taskHandle
self.daq.DAQmxRegisterDoneEvent(t.taskHandle, 0, done_cb, None)
t.StartTask()
13 changes: 10 additions & 3 deletions artiq/gateware/rtio/phy/ttl_simple.py
Original file line number Diff line number Diff line change
@@ -78,7 +78,7 @@ def __init__(self, pad):


class ClockGen(Module):
def __init__(self, pad, ftw_width=16):
def __init__(self, pad, ftw_width=24):
self.rtlink = rtlink.Interface(
rtlink.OInterface(ftw_width, suppress_nop=False))

@@ -89,7 +89,14 @@ def __init__(self, pad, ftw_width=16):
self.sync.rio += If(self.rtlink.o.stb, ftw.eq(self.rtlink.o.data))
self.sync.rio_phy += [
acc.eq(acc + ftw),
# known phase on write: at rising edge
If(self.rtlink.o.stb, acc.eq(2**(ftw_width - 1))),
If(self.rtlink.o.stb,
If(self.rtlink.o.data != 0,
# known phase on frequency write: at rising edge
acc.eq(2**(ftw_width - 1))
).Else(
# set output to 0 on stop
acc.eq(0)
)
),
pad.eq(acc[-1])
]
28 changes: 27 additions & 1 deletion artiq/test/coredevice.py
Original file line number Diff line number Diff line change
@@ -35,6 +35,8 @@ class DBKeys:

@kernel
def run(self):
self.loop_in.input()
delay(1*us)
with parallel:
self.loop_in.gate_rising(2*us)
with sequential:
@@ -44,6 +46,26 @@ def run(self):
self.rtt = mu_to_seconds(self.loop_in.timestamp() - t0)


class ClockGeneratorLoopback(Experiment, AutoDB):
class DBKeys:
core = Device()
loop_clock_in = Device()
loop_clock_out = Device()
count = Result()

@kernel
def run(self):
self.loop_clock_in.input()
self.loop_clock_out.stop()
delay(1*us)
with parallel:
self.loop_clock_in.gate_rising(10*us)
with sequential:
delay(200*ns)
self.loop_clock_out.set(1*MHz)
self.count = self.loop_clock_in.count()


class PulseRate(Experiment, AutoDB):
class DBKeys:
core = Device()
@@ -77,7 +99,11 @@ def test_loopback(self):
rtt = self.execute(Loopback)["rtt"]
print(rtt)
self.assertGreater(rtt, 0*ns)
self.assertLess(rtt, 40*ns)
self.assertLess(rtt, 50*ns)

def test_clock_generator_loopback(self):
count = self.execute(ClockGeneratorLoopback)["count"]
self.assertEqual(count, 10)

def test_pulse_rate(self):
rate = self.execute(PulseRate)["pulse_rate"]
1 change: 1 addition & 0 deletions soc/runtime/gen_service_table.py
Original file line number Diff line number Diff line change
@@ -21,6 +21,7 @@
("ttl_set_oe", "ttl_set_oe"),
("ttl_set_sensitivity", "ttl_set_sensitivity"),
("ttl_get", "ttl_get"),
("ttl_clock_set", "ttl_clock_set"),

("dds_init", "dds_init"),
("dds_batch_enter", "dds_batch_enter"),
2 changes: 1 addition & 1 deletion soc/runtime/moninj.c
Original file line number Diff line number Diff line change
@@ -51,7 +51,7 @@ static void moninj_monitor(const ip_addr_t *addr, u16_t port)
reply.ttl_levels = 0;
reply.ttl_oes = 0;
reply.ttl_overrides = 0;
for(i=0;i<RTIO_TTL_COUNT;i++) {
for(i=0;i<RTIO_REGULAR_TTL_COUNT;i++) {
rtio_moninj_mon_chan_sel_write(i);
rtio_moninj_mon_probe_sel_write(0);
rtio_moninj_mon_value_update_write(1);
8 changes: 8 additions & 0 deletions soc/runtime/ttl.c
Original file line number Diff line number Diff line change
@@ -56,3 +56,11 @@ long long int ttl_get(int channel, long long int time_limit)
rtio_i_re_write(1);
return r;
}

void ttl_clock_set(long long int timestamp, int channel, int ftw)
{
rtio_chan_sel_write(channel);
rtio_o_timestamp_write(timestamp);
rtio_o_data_write(ftw);
rtio_write_and_process_status(timestamp, channel);
}
1 change: 1 addition & 0 deletions soc/runtime/ttl.h
Original file line number Diff line number Diff line change
@@ -5,5 +5,6 @@ void ttl_set_o(long long int timestamp, int channel, int value);
void ttl_set_oe(long long int timestamp, int channel, int oe);
void ttl_set_sensitivity(long long int timestamp, int channel, int sensitivity);
long long int ttl_get(int channel, long long int time_limit);
void ttl_clock_set(long long int timestamp, int channel, int ftw);

#endif /* __TTL_H */
4 changes: 2 additions & 2 deletions soc/targets/artiq_kc705.py
Original file line number Diff line number Diff line change
@@ -103,7 +103,7 @@ def __init__(self, platform, cpu_type="or1k", **kwargs):
phy = ttl_simple.Output(platform.request("user_led", 2))
self.submodules += phy
rtio_channels.append(rtio.Channel.from_phy(phy))
self.add_constant("RTIO_TTL_COUNT", len(rtio_channels))
self.add_constant("RTIO_REGULAR_TTL_COUNT", len(rtio_channels))

phy = ttl_simple.ClockGen(platform.request("ttl", 15))
self.submodules += phy
@@ -142,7 +142,7 @@ def __init__(self, platform, cpu_type="or1k", **kwargs):
phy = ttl_simple.Output(platform.request("user_led", 2))
self.submodules += phy
rtio_channels.append(rtio.Channel.from_phy(phy))
self.add_constant("RTIO_TTL_COUNT", len(rtio_channels))
self.add_constant("RTIO_REGULAR_TTL_COUNT", len(rtio_channels))

phy = ttl_simple.ClockGen(platform.request("ttl", 14))
self.submodules += phy
2 changes: 1 addition & 1 deletion soc/targets/artiq_pipistrello.py
Original file line number Diff line number Diff line change
@@ -113,7 +113,7 @@ def __init__(self, platform, cpu_type="or1k", **kwargs):
self.submodules += phy
rtio_channels.append(rtio.Channel.from_phy(phy, ofifo_depth=4))

self.add_constant("RTIO_TTL_COUNT", len(rtio_channels))
self.add_constant("RTIO_REGULAR_TTL_COUNT", len(rtio_channels))

phy = ttl_simple.ClockGen(platform.request("ttl", 15))
self.submodules += phy