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: 62669f9ff2d8
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: a61d701d47eb
Choose a head ref
  • 2 commits
  • 15 files changed
  • 1 contributor

Commits on May 2, 2015

  1. Copy the full SHA
    65b4b7b View commit details
  2. Copy the full SHA
    a61d701 View commit details
8 changes: 4 additions & 4 deletions artiq/coredevice/dds.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
from artiq.language.core import *
from artiq.language.db import *
from artiq.language.units import *
from artiq.coredevice import rtio
from artiq.coredevice import ttl


PHASE_MODE_DEFAULT = -1
@@ -14,7 +14,7 @@ class DDS(AutoDB):
"""Core device Direct Digital Synthesis (DDS) driver.
Controls DDS devices managed directly by the core device's runtime. It also
uses a RTIO channel (through :class:`artiq.coredevice.rtio.RTIOOut`) to
uses a RTIO TTL channel (through :class:`artiq.coredevice.ttl.TTLOut`) to
control a RF switch that gates the output of the DDS device.
:param dds_sysclk: DDS system frequency, used for computing the frequency
@@ -34,7 +34,7 @@ def build(self):
self.previous_on = False
self.previous_frequency = 0*MHz
self.set_phase_mode(PHASE_MODE_CONTINUOUS)
self.sw = rtio.RTIOOut(core=self.core, channel=self.rtio_switch)
self.sw = ttl.TTLOut(core=self.core, channel=self.rtio_switch)

@portable
def frequency_to_ftw(self, frequency):
@@ -93,7 +93,7 @@ def on(self, frequency, phase_mode=PHASE_MODE_DEFAULT, phase_offset=0):
self.set_phase_mode(phase_mode)

if self.previous_frequency != frequency:
merge = self.sw.previous_timestamp == time_to_cycles(now())
merge = self.sw.o_previous_timestamp == time_to_cycles(now())
if not merge:
self.sw.sync()
# Channel is already on:
2 changes: 1 addition & 1 deletion artiq/coredevice/runtime.py
Original file line number Diff line number Diff line change
@@ -14,7 +14,7 @@
_syscalls = {
"watchdog_set": "i:i",
"watchdog_clear": "i:n",
"rtio_set_o": "Iii:n",
"rtio_set_o": "Iib:n",
"rtio_set_oe": "Iib:n",
"rtio_set_sensitivity": "Iii:n",
"rtio_get_counter": "n:I",
133 changes: 80 additions & 53 deletions artiq/coredevice/rtio.py → artiq/coredevice/ttl.py
Original file line number Diff line number Diff line change
@@ -2,26 +2,21 @@
from artiq.language.db import *


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

def build(self):
self._set_oe()

@kernel
def _set_oe(self):
syscall("rtio_set_oe", time_to_cycles(now()), self.channel, True)

@kernel
def set_o(self, t, value):
"""Sets the output value of the RTIO channel.
@@ -37,27 +32,21 @@ def on(self, t):
:param t: timestamp in RTIO cycles (64-bit integer).
"""
self.set_o(t, 1)
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, 0)

self.set_o(t, False)

class RTIOOut(AutoDB):
"""RTIO output driver.

Configures the corresponding RTIO channel as output on the core device and
provides functions to set its level.
class TTLOut(AutoDB):
"""RTIO TTL output driver.
This driver supports zero-length transition suppression. For example, if
two pulses are emitted back-to-back with no delay between them, they will
be merged into a single pulse with a duration equal to the sum of the
durations of the original pulses.
This should be used with output-only channels.
:param core: core device
:param channel: channel number
@@ -66,39 +55,31 @@ class DBKeys:
core = Device()
channel = Argument()

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

@kernel
def _set_oe(self):
syscall("rtio_set_oe", time_to_cycles(now()), self.channel, True)
def build(self):
# in RTIO cycles
self.o_previous_timestamp = int64(0)

@kernel
def _set_o(self, value):
syscall("rtio_set_o", time_to_cycles(now()), self.channel, value)
self.previous_timestamp = time_to_cycles(now())
def _set_o(self, o):
syscall("rtio_set_o", time_to_cycles(now()), self.channel, o)
self.o_previous_timestamp = time_to_cycles(now())

@kernel
def sync(self):
"""Busy-waits until all programmed level switches have been effected.
This function is useful to synchronize CPU-controlled devices (such as
the AD9858 DDS bus) with related RTIO controls (such as RF switches at
the output of the DDS).
"""
while syscall("rtio_get_counter") < self.previous_timestamp:
"""Busy-waits 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."""
self._set_o(1)
self._set_o(True)

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

@kernel
def pulse(self, duration):
@@ -108,12 +89,20 @@ def pulse(self, duration):
self.off()


class RTIOIn(AutoDB):
"""RTIO input driver.
class TTLInOut(AutoDB):
"""RTIO TTL input/output driver.
In output mode, provides functions to set the logic level on the signal.
Configures the corresponding RTIO channel as input on the core device and
provides functions to analyze the incoming signal, with real-time gating
to prevent overflows.
In input mode, provides functions to analyze the incoming signal, with
real-time gating to prevent overflows.
RTIO TTLs supports zero-length transition suppression. For example, if
two pulses are emitted back-to-back with no delay between them, they will
be merged into a single pulse with a duration equal to the sum of the
durations of the original pulses.
This should be used with bidirectional channels.
:param core: core device
:param channel: channel number
@@ -123,17 +112,54 @@ class DBKeys:
channel = Argument()

def build(self):
self.previous_timestamp = int64(0) # in RTIO cycles
self._set_oe()
# in RTIO cycles
self.o_previous_timestamp = int64(0)
self.i_previous_timestamp = int64(0)

@kernel
def _set_oe(self):
syscall("rtio_set_oe", time_to_cycles(now()), self.channel, False)
def _set_oe(self, oe):
syscall("rtio_set_oe", time_to_cycles(now()), self.channel, oe)

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

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

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

@kernel
def sync(self):
"""Busy-waits 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."""
self._set_o(True)

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

@kernel
def pulse(self, duration):
"""Pulses the output high for the specified duration."""
self.on()
delay(duration)
self.off()

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

@kernel
def gate_rising(self, duration):
@@ -162,7 +188,8 @@ def count(self):
"""Poll the RTIO input during all the previously programmed gate
openings, and returns the number of registered events."""
count = 0
while syscall("rtio_get", self.channel, self.previous_timestamp) >= 0:
while syscall("rtio_get", self.channel,
self.i_previous_timestamp) >= 0:
count += 1
return count

@@ -174,4 +201,4 @@ def timestamp(self):
If the gate is permanently closed, returns a negative value.
"""
return cycles_to_time(syscall("rtio_get", self.channel,
self.previous_timestamp))
self.i_previous_timestamp))
10 changes: 5 additions & 5 deletions artiq/devices/pdq2/mediator.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
from artiq.language.core import *
from artiq.language.db import *
from artiq.language.units import *
from artiq.coredevice import rtio
from artiq.coredevice import ttl


frame_setup = 20*ns
@@ -162,13 +162,13 @@ class DBKeys:

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

self.frames = []
7 changes: 6 additions & 1 deletion artiq/gateware/rtio/core.py
Original file line number Diff line number Diff line change
@@ -257,6 +257,7 @@ class _KernelCSRs(AutoCSR):
def __init__(self, chan_sel_width,
data_width, address_width, full_ts_width):
self.reset = CSRStorage(reset=1)
self.reset_phy = CSRStorage(reset=1)
self.chan_sel = CSRStorage(chan_sel_width)

if data_width:
@@ -296,17 +297,21 @@ def __init__(self, channels, clk_freq, full_ts_width=63,
full_ts_width)

# Clocking/Reset
# Create rsys and rio domains based on sys and rio
# Create rsys, rio and rio_phy domains based on sys and rtio
# with reset controlled by CSR.
self.clock_domains.cd_rsys = ClockDomain()
self.clock_domains.cd_rio = ClockDomain()
self.clock_domains.cd_rio_phy = ClockDomain()
self.comb += [
self.cd_rsys.clk.eq(ClockSignal()),
self.cd_rsys.rst.eq(self.kcsrs.reset.storage)
]
self.comb += self.cd_rio.clk.eq(ClockSignal("rtio"))
self.specials += AsyncResetSynchronizer(self.cd_rio,
self.kcsrs.reset.storage)
self.comb += self.cd_rio_phy.clk.eq(ClockSignal("rtio"))
self.specials += AsyncResetSynchronizer(self.cd_rio_phy,
self.kcsrs.reset_phy.storage)

# Managers
self.submodules.counter = _RTIOCounter(full_ts_width - fine_ts_width)
8 changes: 4 additions & 4 deletions artiq/gateware/rtio/phy/ttl_simple.py
Original file line number Diff line number Diff line change
@@ -10,7 +10,7 @@ def __init__(self, pad):

# # #

self.sync.rio += If(self.rtlink.o.stb, pad.eq(self.rtlink.o.data))
self.sync.rio_phy += If(self.rtlink.o.stb, pad.eq(self.rtlink.o.data))


class Inout(Module):
@@ -25,7 +25,7 @@ def __init__(self, pad):
self.specials += ts.get_tristate(pad)
sensitivity = Signal(2)

self.sync.rio += If(self.rtlink.o.stb,
self.sync.rio_phy += If(self.rtlink.o.stb,
Case(self.rtlink.o.address, {
0: ts.o.eq(self.rtlink.o.data[0]),
1: ts.oe.eq(self.rtlink.o.data[0]),
@@ -35,8 +35,8 @@ def __init__(self, pad):

i = Signal()
i_d = Signal()
self.specials += MultiReg(ts.i, i, "rio")
self.sync.rio += i_d.eq(i)
self.specials += MultiReg(ts.i, i, "rio_phy")
self.sync.rio_phy += i_d.eq(i)
self.comb += [
self.rtlink.i.stb.eq(
(sensitivity[0] & ( i & ~i_d)) |
2 changes: 1 addition & 1 deletion artiq/gateware/rtio/phy/wishbone.py
Original file line number Diff line number Diff line change
@@ -18,7 +18,7 @@ def __init__(self, wb, address_width):
# # #

active = Signal()
self.sync.rio += [
self.sync.rio_phy += [
If(self.rtlink.o.stb,
active.eq(1),
wb.adr.eq(self.rtlink.o.address[:address_width]),
Loading