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: d7ef885d9e8e
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: e5e035d0311d
Choose a head ref
  • 4 commits
  • 16 files changed
  • 1 contributor

Commits on Jul 1, 2015

  1. Copy the full SHA
    9d6287a View commit details
  2. Copy the full SHA
    5ace0f8 View commit details
  3. Copy the full SHA
    771ad6c View commit details
  4. Copy the full SHA
    e5e035d View commit details
7 changes: 3 additions & 4 deletions artiq/coredevice/core.py
Original file line number Diff line number Diff line change
@@ -121,10 +121,9 @@ def run(self, k_function, k_args, k_kwargs):
self.first_run = False

@kernel
def get_rtio_time(self):
return cycles_to_time(syscall("rtio_get_counter"))
def get_rtio_counter_mu(self):
return syscall("rtio_get_counter")

@kernel
def break_realtime(self):
t = syscall("rtio_get_counter") + 125000
at(cycles_to_time(t))
at_mu(syscall("rtio_get_counter") + 125000)
30 changes: 24 additions & 6 deletions artiq/coredevice/dds.py
Original file line number Diff line number Diff line change
@@ -37,7 +37,7 @@ def build(self):
def batch_enter(self):
"""Starts a DDS command batch. All DDS commands are buffered
after this call, until ``batch_exit`` is called."""
syscall("dds_batch_enter", time_to_cycles(now()))
syscall("dds_batch_enter", now_mu())

@kernel
def batch_exit(self):
@@ -76,12 +76,24 @@ def ftw_to_frequency(self, ftw):
"""
return ftw*self.sysclk/2**32

@portable
def turns_to_pow(self, turns):
"""Returns the phase offset word corresponding to the given phase
in turns."""
return round(turns*2**14)

@portable
def pow_to_turns(self, pow):
"""Returns the phase in turns corresponding to the given phase offset
word."""
return pow/2**14

@kernel
def init(self):
"""Resets and initializes the DDS channel.
The runtime does this for all channels upon core device startup."""
syscall("dds_init", time_to_cycles(now()), self.channel)
syscall("dds_init", now_mu(), self.channel)

@kernel
def set_phase_mode(self, phase_mode):
@@ -104,17 +116,23 @@ def set_phase_mode(self, phase_mode):
self.phase_mode = phase_mode

@kernel
def set(self, frequency, phase=0, phase_mode=_PHASE_MODE_DEFAULT):
def set_mu(self, frequency, phase=0, phase_mode=_PHASE_MODE_DEFAULT):
"""Sets the DDS channel to the specified frequency and phase.
This uses machine units (FTW and POW).
:param frequency: frequency to generate.
:param phase: adds an offset, in turns, to the phase.
:param phase_mode: if specified, overrides the default phase mode set
by ``set_phase_mode`` for this call.
"""
if phase_mode == _PHASE_MODE_DEFAULT:
phase_mode = self.phase_mode
syscall("dds_set", now_mu(), self.channel,
frequency, round(phase*2**14), phase_mode)

syscall("dds_set", time_to_cycles(now()), self.channel,
self.frequency_to_ftw(frequency), round(phase*2**14),
phase_mode)
@kernel
def set(self, frequency, phase=0, phase_mode=_PHASE_MODE_DEFAULT):
"""Like ``set_mu``, but uses Hz and turns."""
self.set_mu(self.frequency_to_ftw(frequency),
self.turns_to_pow(phase), phase_mode)
132 changes: 67 additions & 65 deletions artiq/coredevice/ttl.py
Original file line number Diff line number Diff line change
@@ -2,47 +2,6 @@
from artiq.language.db import *


class LLTTLOut(AutoDB):
"""Low-level RTIO TTL output driver.
Allows setting RTIO TTL outputs at arbitrary times, without time
unit conversion.
This is meant to be used mostly in drivers; consider using
``TTLOut`` instead.
This should be used with output-only channels.
"""
class DBKeys:
core = Device()
channel = Argument()

@kernel
def set_o(self, t, value):
"""Sets the output value of the RTIO channel.
:param t: timestamp in RTIO cycles (64-bit integer).
:param value: value to set at the output.
"""
syscall("ttl_set_o", t, self.channel, value)

@kernel
def on(self, t):
"""Turns the RTIO channel on.
:param t: timestamp in RTIO cycles (64-bit integer).
"""
self.set_o(t, True)

@kernel
def off(self, t):
"""Turns the RTIO channel off.
:param t: timestamp in RTIO cycles (64-bit integer).
"""
self.set_o(t, False)


class TTLOut(AutoDB):
"""RTIO TTL output driver.
@@ -61,9 +20,9 @@ def build(self):
self.o_previous_timestamp = int64(0)

@kernel
def _set_o(self, o):
syscall("ttl_set_o", time_to_cycles(now()), self.channel, o)
self.o_previous_timestamp = time_to_cycles(now())
def set_o(self, o):
syscall("ttl_set_o", now_mu(), self.channel, o)
self.o_previous_timestamp = now_mu()

@kernel
def sync(self):
@@ -74,16 +33,25 @@ def sync(self):
@kernel
def on(self):
"""Sets the output to a logic high state."""
self._set_o(True)
self.set_o(True)

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

@kernel
def pulse_mu(self, duration):
"""Pulses 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."""
"""Pulses the output high for the specified duration
(in seconds)."""
self.on()
delay(duration)
self.off()
@@ -117,21 +85,21 @@ def build(self):
self.i_previous_timestamp = int64(0)

@kernel
def _set_oe(self, oe):
syscall("ttl_set_oe", time_to_cycles(now()), self.channel, oe)
def set_oe(self, oe):
syscall("ttl_set_oe", now_mu(), self.channel, oe)

@kernel
def output(self):
self._set_oe(True)
self.set_oe(True)

@kernel
def input(self):
self._set_oe(False)
self.set_oe(False)

@kernel
def _set_o(self, o):
syscall("ttl_set_o", time_to_cycles(now()), self.channel, o)
self.o_previous_timestamp = time_to_cycles(now())
def set_o(self, o):
syscall("ttl_set_o", now_mu(), self.channel, o)
self.o_previous_timestamp = now_mu()

@kernel
def sync(self):
@@ -142,43 +110,78 @@ def sync(self):
@kernel
def on(self):
"""Sets the output to a logic high state."""
self._set_o(True)
self.set_o(True)

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

@kernel
def pulse_mu(self, duration):
"""Pulses 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."""
"""Pulses the output high for the specified duration
(in seconds)."""
self.on()
delay(duration)
self.off()

@kernel
def _set_sensitivity(self, value):
syscall("ttl_set_sensitivity", time_to_cycles(now()), self.channel, value)
self.i_previous_timestamp = time_to_cycles(now())
syscall("ttl_set_sensitivity", now_mu(), self.channel, value)
self.i_previous_timestamp = now_mu()

@kernel
def gate_rising_mu(self, duration):
"""Register rising edge events for the specified duration
(in machine units)."""
self._set_sensitivity(1)
delay_mu(duration)
self._set_sensitivity(0)

@kernel
def gate_falling_mu(self, duration):
"""Register falling edge events for the specified duration
(in machine units)."""
self._set_sensitivity(2)
delay_mu(duration)
self._set_sensitivity(0)

@kernel
def gate_both_mu(self, duration):
"""Register both rising and falling edge events for the specified
duration (in machine units)."""
self._set_sensitivity(3)
delay_mu(duration)
self._set_sensitivity(0)

@kernel
def gate_rising(self, duration):
"""Register rising edge events for the specified duration."""
"""Register rising edge events for the specified duration
(in seconds)."""
self._set_sensitivity(1)
delay(duration)
self._set_sensitivity(0)

@kernel
def gate_falling(self, duration):
"""Register falling edge events for the specified duration."""
"""Register falling edge events for the specified duration
(in seconds)."""
self._set_sensitivity(2)
delay(duration)
self._set_sensitivity(0)

@kernel
def gate_both(self, duration):
def gate_both_mu(self, duration):
"""Register both rising and falling edge events for the specified
duration."""
duration (in seconds)."""
self._set_sensitivity(3)
delay(duration)
self._set_sensitivity(0)
@@ -200,5 +203,4 @@ def timestamp(self):
If the gate is permanently closed, returns a negative value.
"""
return cycles_to_time(syscall("ttl_get", self.channel,
self.i_previous_timestamp))
return syscall("ttl_get", self.channel, self.i_previous_timestamp)
36 changes: 17 additions & 19 deletions artiq/devices/pdq2/mediator.py
Original file line number Diff line number Diff line change
@@ -99,7 +99,7 @@ def create_segment(self, name=None):

def _arm(self):
self.segment_delays = [
time_to_cycles(s.get_duration()*delay_margin_factor, self.core)
seconds_to_mu(s.get_duration()*delay_margin_factor, self.core)
for s in self.segments]

def _invalidate(self):
@@ -125,7 +125,8 @@ def advance(self):
if not self.pdq.armed:
raise ArmError

t = time_to_cycles(now()) - time_to_cycles(trigger_duration/2)
call_t = now_mu()
trigger_start_t = call_t - seconds_to_mu(trigger_duration/2)

if self.pdq.current_frame >= 0:
# PDQ is in the middle of a frame. Check it is us.
@@ -136,15 +137,16 @@ def advance(self):
# to play our first segment.
self.pdq.current_frame = self.frame_number
self.pdq.next_segment = 0
t2 = t - time_to_cycles(frame_setup)
self.pdq.frame0.set_value(t2, self.frame_number & 1)
self.pdq.frame1.set_value(t2, (self.frame_number & 2) >> 1)
self.pdq.frame2.set_value(t2, (self.frame_number & 4) >> 2)
at_mu(trigger_start_t - seconds_to_mu(frame_setup))
self.pdq.frame0.set_o(bool(self.frame_number & 1))
self.pdq.frame1.set_o(bool((self.frame_number & 2) >> 1))
self.pdq.frame2.set_o(bool((self.frame_number & 4) >> 2))

self.pdq.trigger.on(t)
self.pdq.trigger.off(t + time_to_cycles(trigger_duration))
at_mu(trigger_start_t)
self.pdq.trigger.pulse(trigger_duration)

delay(cycles_to_time(self.segment_delays[self.pdq.next_segment]))
at_mu(call_t)
delay_mu(self.segment_delays[self.pdq.next_segment])
self.pdq.next_segment += 1

# test for end of frame
@@ -157,19 +159,15 @@ class CompoundPDQ2(AutoDB):
class DBKeys:
core = Device()
pdq2_devices = Argument()
rtio_trigger = Argument()
rtio_frame = Argument()
trigger_device = Argument()
frame_devices = Argument()

def build(self):
self.pdq2s = [self.dbh.get_device(d) for d in self.pdq2_devices]
self.trigger = ttl.LLTTLOut(
core=self.core, channel=self.rtio_trigger)
self.frame0 = ttl.LLTTLOut(
core=self.core, channel=self.rtio_frame[0])
self.frame1 = ttl.LLTTLOut(
core=self.core, channel=self.rtio_frame[1])
self.frame2 = ttl.LLTTLOut(
core=self.core, channel=self.rtio_frame[2])
self.trigger = self.dbh.get_device(self.trigger_device)
self.frame0 = self.dbh.get_device(self.frame_devices[0])
self.frame1 = self.dbh.get_device(self.frame_devices[1])
self.frame2 = self.dbh.get_device(self.frame_devices[2])

self.frames = []
self.current_frame = -1
Loading