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: cb6c28006c55
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: f4f95d330b5b
Choose a head ref
  • 6 commits
  • 12 files changed
  • 1 contributor

Commits on Mar 10, 2016

  1. Copy the full SHA
    2e39802 View commit details
  2. rtio: remove NOP suppression capability

    Back when RTIO was driving TTLs, this functionality made it simpler to use by removing some irrelevant underflows.
    
    The same technique is not applicable to DDS and SPI, so the user will have to deal with such underflows.
    
    This patch makes the behavior of RTIO more consistent and the code simpler.
    sbourdeauducq committed Mar 10, 2016
    Copy the full SHA
    542a375 View commit details
  3. Copy the full SHA
    c5552f9 View commit details
  4. Copy the full SHA
    7f50182 View commit details
  5. 2
    Copy the full SHA
    1739e0f View commit details
  6. Copy the full SHA
    f4f95d3 View commit details
45 changes: 45 additions & 0 deletions artiq/coredevice/cache.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
from artiq.language.core import *
from artiq.language.types import *


@syscall
def cache_get(key: TStr) -> TList(TInt32):
raise NotImplementedError("syscall not simulated")

@syscall
def cache_put(key: TStr, value: TList(TInt32)) -> TNone:
raise NotImplementedError("syscall not simulated")


class CoreCache:
"""Core device cache access"""
def __init__(self, dmgr, core_device="core"):
self.core = dmgr.get(core_device)

@kernel
def get(self, key):
"""Extract a value from the core device cache.
After a value is extracted, it cannot be replaced with another value using
:meth:`put` until all kernel functions finish executing; attempting
to replace it will result in a :class:`artiq.coredevice.exceptions.CacheError`.
If the cache does not contain any value associated with ``key``, an empty list
is returned.
The value is not copied, so mutating it will change what's stored in the cache.
:param str key: cache key
:return: a list of 32-bit integers
"""
return cache_get(key)

@kernel
def put(self, key, value):
"""Put a value into the core device cache. The value will persist until reboot.
To remove a value from the cache, call :meth:`put` with an empty list.
:param str key: cache key
:param list value: a list of 32-bit integers
"""
cache_put(key, value)
36 changes: 0 additions & 36 deletions artiq/coredevice/core.py
Original file line number Diff line number Diff line change
@@ -41,14 +41,6 @@ def __str__(self):
def rtio_get_counter() -> TInt64:
raise NotImplementedError("syscall not simulated")

@syscall
def cache_get(key: TStr) -> TList(TInt32):
raise NotImplementedError("syscall not simulated")

@syscall
def cache_put(key: TStr, value: TList(TInt32)) -> TNone:
raise NotImplementedError("syscall not simulated")


class Core:
"""Core device driver.
@@ -127,31 +119,3 @@ def break_realtime(self):
min_now = rtio_get_counter() + 125000
if now_mu() < min_now:
at_mu(min_now)

@kernel
def get_cache(self, key):
"""Extract a value from the core device cache.
After a value is extracted, it cannot be replaced with another value using
:meth:`put_cache` until all kernel functions finish executing; attempting
to replace it will result in a :class:`artiq.coredevice.exceptions.CacheError`.
If the cache does not contain any value associated with ``key``, an empty list
is returned.
The value is not copied, so mutating it will change what's stored in the cache.
:param str key: cache key
:return: a list of 32-bit integers
"""
return cache_get(key)

@kernel
def put_cache(self, key, value):
"""Put a value into the core device cache. The value will persist until reboot.
To remove a value from the cache, call :meth:`put_cache` with an empty list.
:param str key: cache key
:param list value: a list of 32-bit integers
"""
cache_put(key, value)
29 changes: 5 additions & 24 deletions artiq/gateware/rtio/core.py
Original file line number Diff line number Diff line change
@@ -115,7 +115,7 @@ def __init__(self, interface, counter, fifo_depth, guard_io_cycles):
ev_layout.append(("address", address_width))
ev_layout.append(("timestamp", counter.width + fine_ts_width))
# ev must be valid 1 cycle before we to account for the latency in
# generating replace, sequence_error and nop
# generating replace, sequence_error and collision
self.ev = Record(ev_layout)

self.writable = Signal()
@@ -149,7 +149,6 @@ def __init__(self, interface, counter, fifo_depth, guard_io_cycles):
sequence_error = Signal()
collision = Signal()
any_error = Signal()
nop = Signal()
if interface.enable_replace:
# Note: replace may be asserted at the same time as collision
# when addresses are different. In that case, it is a collision.
@@ -171,25 +170,8 @@ def __init__(self, interface, counter, fifo_depth, guard_io_cycles):
else:
self.sync.rsys += collision.eq(
self.ev.timestamp[fine_ts_width:] == buf.timestamp[fine_ts_width:])
self.comb += any_error.eq(sequence_error | collision)
if interface.suppress_nop:
# disable NOP at reset: do not suppress a first write with all 0s
nop_en = Signal(reset=0)
addresses_equal = [getattr(self.ev, a) == getattr(buf, a)
for a in ("data", "address")
if hasattr(self.ev, a)]
if addresses_equal:
self.sync.rsys += nop.eq(
nop_en & reduce(and_, addresses_equal))
else:
self.comb.eq(nop.eq(0))
self.sync.rsys += [
# buf now contains valid data. enable NOP.
If(self.we & ~any_error, nop_en.eq(1)),
# underflows cancel the write. allow it to be retried.
If(self.underflow, nop_en.eq(0))
]
self.comb += [
any_error.eq(sequence_error | collision),
self.sequence_error.eq(self.we & sequence_error),
self.collision.eq(self.we & collision)
]
@@ -210,7 +192,7 @@ def __init__(self, interface, counter, fifo_depth, guard_io_cycles):
fifo.we.eq(1)
)
),
If(self.we & ~replace & ~nop & ~any_error,
If(self.we & ~replace & ~any_error,
fifo.we.eq(1)
)
)
@@ -219,7 +201,7 @@ def __init__(self, interface, counter, fifo_depth, guard_io_cycles):
# Must come after read to handle concurrent read+write properly
self.sync.rsys += [
buf_just_written.eq(0),
If(self.we & ~nop & ~any_error,
If(self.we & ~any_error,
buf_just_written.eq(1),
buf_pending.eq(1),
buf.eq(self.ev)
@@ -341,8 +323,7 @@ def from_phy(cls, phy, **kwargs):
class LogChannel:
"""A degenerate channel used to log messages into the analyzer."""
def __init__(self):
self.interface = rtlink.Interface(
rtlink.OInterface(32, suppress_nop=False))
self.interface = rtlink.Interface(rtlink.OInterface(32))
self.probes = []
self.overrides = []

3 changes: 1 addition & 2 deletions artiq/gateware/rtio/phy/ttl_simple.py
Original file line number Diff line number Diff line change
@@ -79,8 +79,7 @@ def __init__(self, pad):

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

# # #

5 changes: 2 additions & 3 deletions artiq/gateware/rtio/phy/wishbone.py
Original file line number Diff line number Diff line change
@@ -5,16 +5,15 @@


class RT2WB(Module):
def __init__(self, address_width, wb=None):
def __init__(self, address_width, wb=None, rtio_enable_replace=False):
if wb is None:
wb = wishbone.Interface()
self.wb = wb
self.rtlink = rtlink.Interface(
rtlink.OInterface(
len(wb.dat_w),
address_width + 1,
suppress_nop=False,
enable_replace=False),
enable_replace=rtio_enable_replace),
rtlink.IInterface(
len(wb.dat_r),
timestamped=False)
6 changes: 2 additions & 4 deletions artiq/gateware/rtio/rtlink.py
Original file line number Diff line number Diff line change
@@ -3,8 +3,7 @@

class OInterface:
def __init__(self, data_width, address_width=0,
fine_ts_width=0, suppress_nop=True,
enable_replace=True):
fine_ts_width=0, enable_replace=True):
self.stb = Signal()
self.busy = Signal()

@@ -15,15 +14,14 @@ def __init__(self, data_width, address_width=0,
if fine_ts_width:
self.fine_ts = Signal(fine_ts_width)

self.suppress_nop = suppress_nop
self.enable_replace = enable_replace

@classmethod
def like(cls, other):
return cls(get_data_width(other),
get_address_width(other),
get_fine_ts_width(other),
other.suppress_nop)
other.enable_replace)


class IInterface:
12 changes: 8 additions & 4 deletions artiq/gui/applets.py
Original file line number Diff line number Diff line change
@@ -85,7 +85,7 @@ async def stop(self):
await asyncio.wait([self.server_task])


class AppletDock(QDockWidgetCloseDetect):
class _AppletDock(QDockWidgetCloseDetect):
def __init__(self, datasets_sub, uid, name, command):
QDockWidgetCloseDetect.__init__(self, "Applet: " + name)
self.setObjectName("applet" + str(uid))
@@ -137,7 +137,7 @@ def embed(self, win_id):
def fix_initial_size(self):
self.embed_window.resize(self.embed_widget.size())

async def terminate(self):
async def terminate(self, delete_self=True):
if self.starting_stopping:
return
self.starting_stopping = True
@@ -163,8 +163,12 @@ async def terminate(self):

self.starting_stopping = False

if delete_self:
self.setParent(None)
self.deleteLater()

async def restart(self):
await self.terminate()
await self.terminate(False)
await self.start()


@@ -235,7 +239,7 @@ def __init__(self, main_window, datasets_sub):
self.table.cellChanged.connect(self.cell_changed)

def create(self, uid, name, command):
dock = AppletDock(self.datasets_sub, uid, name, command)
dock = _AppletDock(self.datasets_sub, uid, name, command)
self.main_window.addDockWidget(QtCore.Qt.RightDockWidgetArea, dock)
dock.setFloating(True)
asyncio.ensure_future(dock.start())
3 changes: 3 additions & 0 deletions artiq/gui/log.py
Original file line number Diff line number Diff line change
@@ -303,6 +303,9 @@ def create_new_dock(self, add_to_area=True):
return dock

def on_dock_closed(self, name):
dock = self.docks[name]
dock.setParent(None)
dock.deleteLater()
del self.docks[name]
self.update_closable()

2 changes: 1 addition & 1 deletion artiq/gui/moninj.py
Original file line number Diff line number Diff line change
@@ -125,7 +125,7 @@ def __init__(self, bus_channel, channel, sysclk, title):

QtWidgets.QFrame.__init__(self)

self.setFrameShape(QtWidgets.QFrame.Panel)
self.setFrameShape(QtWidgets.QFrame.Box)
self.setFrameShadow(QtWidgets.QFrame.Raised)

grid = QtWidgets.QGridLayout()
7 changes: 4 additions & 3 deletions artiq/test/coredevice/test_cache.py
Original file line number Diff line number Diff line change
@@ -5,21 +5,22 @@
class _Cache(EnvExperiment):
def build(self):
self.setattr_device("core")
self.print = lambda x: print(x)
self.setattr_device("core_cache")

@kernel
def get(self, key):
return self.core.get_cache(key)
return self.core_cache.get(key)

@kernel
def put(self, key, value):
self.core.put_cache(key, value)
self.core_cache.put(key, value)

@kernel
def get_put(self, key, value):
self.get(key)
self.put(key, value)


class CacheTest(ExperimentCase):
def test_get_empty(self):
exp = self.create(_Cache)
6 changes: 6 additions & 0 deletions doc/manual/core_drivers_reference.rst
Original file line number Diff line number Diff line change
@@ -42,6 +42,12 @@ These drivers are for the core device and the peripherals closely integrated int
.. automodule:: artiq.coredevice.i2c
:members:

:mod:`artiq.coredevice.cache` module
-----------------------------------------

.. automodule:: artiq.coredevice.cache
:members:

:mod:`artiq.coredevice.exceptions` module
-----------------------------------------

6 changes: 6 additions & 0 deletions examples/master/device_db.pyon
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
# This is an example device database that needs to be adapted to your setup.
# The RTIO channel numbers here are for NIST CLOCK on KC705.
# The list of devices here is not exhaustive.

{
"comm": {
@@ -14,6 +15,11 @@
"class": "Core",
"arguments": {"ref_period": 1e-9}
},
"core_cache": {
"type": "local",
"module": "artiq.coredevice.cache",
"class": "CoreCache"
},
"core_dds": {
"type": "local",
"module": "artiq.coredevice.dds",