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: 6c094b500de3
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: 276a1784efc0
Choose a head ref
  • 2 commits
  • 8 files changed
  • 1 contributor

Commits on Jun 9, 2015

  1. Copy the full SHA
    b2af0f6 View commit details
  2. Copy the full SHA
    276a178 View commit details
2 changes: 1 addition & 1 deletion artiq/gateware/rtio/__init__.py
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
from artiq.gateware.rtio.core import Channel, RTIO
from artiq.gateware.rtio.moninj import Monitor
from artiq.gateware.rtio.moninj import MonInj
10 changes: 9 additions & 1 deletion artiq/gateware/rtio/core.py
Original file line number Diff line number Diff line change
@@ -247,12 +247,20 @@ def __init__(self, interface, counter, fifo_depth):


class Channel:
def __init__(self, interface, probes=[], ofifo_depth=64, ififo_depth=64):
def __init__(self, interface, probes=[], overrides=[],
ofifo_depth=64, ififo_depth=64):
self.interface = interface
self.probes = probes
self.overrides = overrides
self.ofifo_depth = ofifo_depth
self.ififo_depth = ififo_depth

@classmethod
def from_phy(cls, phy, **kwargs):
probes = getattr(phy, "probes", [])
overrides = getattr(phy, "overrides", [])
return cls(phy.rtlink, probes, overrides, **kwargs)


class _KernelCSRs(AutoCSR):
def __init__(self, chan_sel_width,
43 changes: 40 additions & 3 deletions artiq/gateware/rtio/moninj.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from migen.fhdl.std import *
from migen.bank.description import *
from migen.genlib.cdc import BusSynchronizer
from migen.genlib.cdc import BusSynchronizer, MultiReg


class Monitor(Module, AutoCSR):
@@ -11,7 +11,7 @@ def __init__(self, channels):
max_probe_len = max(flen(p) for cp in chan_probes for p in cp)
self.chan_sel = CSRStorage(bits_for(len(chan_probes)-1))
self.probe_sel = CSRStorage(bits_for(max_chan_probes-1))
self.probe_value = CSRStatus(max_probe_len)
self.value = CSRStatus(max_probe_len)

# # #

@@ -25,5 +25,42 @@ def __init__(self, channels):
cp_sys.append(vs.o)
cp_sys += [0]*(max_chan_probes-len(cp))
chan_probes_sys.append(Array(cp_sys)[self.probe_sel.storage])
self.comb += self.probe_value.status.eq(
self.comb += self.value.status.eq(
Array(chan_probes_sys)[self.chan_sel.storage])


class Injector(Module, AutoCSR):
def __init__(self, channels):
chan_overrides = [c.overrides for c in channels]

max_chan_overrides = max(len(co) for co in chan_overrides)
max_override_len = max(flen(o) for co in chan_overrides for o in co)
self.chan_sel = CSRStorage(bits_for(len(chan_overrides)-1))
self.override_sel = CSRStorage(bits_for(max_chan_overrides-1))
self.value = CSR(max_override_len)

# # #

chan_overrides_sys = []
for n_channel, co in enumerate(chan_overrides):
co_sys = []
for n_override, o in enumerate(co):
# We do the clock domain transfer with a simple double-latch.
# Software has to ensure proper timing of any strobe signal etc.
# to avoid problematic glitches.
o_sys = Signal.like(o)
self.specials += MultiReg(o_sys, o, "rio")
self.sync += If(self.value.re & (self.chan_sel.storage == n_channel)
& (self.override_sel.storage == n_override),
o_sys.eq(self.value.r))
co_sys.append(o_sys)
co_sys += [0]*(max_chan_overrides-len(co))
chan_overrides_sys.append(Array(co_sys)[self.override_sel.storage])
self.comb += self.value.w.eq(
Array(chan_overrides_sys)[self.chan_sel.storage])


class MonInj(Module, AutoCSR):
def __init__(self, channels):
self.submodules.mon = Monitor(channels)
self.submodules.inj = Injector(channels)
36 changes: 32 additions & 4 deletions artiq/gateware/rtio/phy/ttl_simple.py
Original file line number Diff line number Diff line change
@@ -8,17 +8,34 @@ class Output(Module):
def __init__(self, pad):
self.rtlink = rtlink.Interface(rtlink.OInterface(1))
self.probes = [pad]
override_en = Signal()
override_o = Signal()
self.overrides = [override_en, override_o]

# # #

self.sync.rio_phy += If(self.rtlink.o.stb, pad.eq(self.rtlink.o.data))
pad_k = Signal()
self.sync.rio_phy += [
If(self.rtlink.o.stb,
pad_k.eq(self.rtlink.o.data)
),
If(override_en,
pad.eq(override_o)
).Else(
pad.eq(pad_k)
)
]


class Inout(Module):
def __init__(self, pad):
self.rtlink = rtlink.Interface(
rtlink.OInterface(2, 2),
rtlink.IInterface(1))
override_en = Signal()
override_o = Signal()
override_oe = Signal()
self.overrides = [override_en, override_o, override_oe]
self.probes = []

# # #
@@ -27,10 +44,21 @@ def __init__(self, pad):
self.specials += ts.get_tristate(pad)
sensitivity = Signal(2)

self.sync.rio_phy += If(self.rtlink.o.stb,
If(self.rtlink.o.address == 0, ts.o.eq(self.rtlink.o.data[0])),
If(self.rtlink.o.address == 1, ts.oe.eq(self.rtlink.o.data[0])),
o_k = Signal()
oe_k = Signal()
self.sync.rio_phy += [
If(self.rtlink.o.stb,
If(self.rtlink.o.address == 0, o_k.eq(self.rtlink.o.data[0])),
If(self.rtlink.o.address == 1, oe_k.eq(self.rtlink.o.data[0])),
),
If(override_en,
ts.o.eq(override_o),
ts.oe.eq(override_oe)
).Else(
ts.o.eq(o_k),
ts.oe.eq(oe_k)
)
]
self.sync.rio += If(self.rtlink.o.stb & (self.rtlink.o.address == 2),
sensitivity.eq(self.rtlink.o.data))

7 changes: 6 additions & 1 deletion artiq/gui/moninj.py
Original file line number Diff line number Diff line change
@@ -41,9 +41,12 @@ def __init__(self, send_to_device, channel, force_out, name):
self._direction = QtGui.QLabel()
self._direction.setAlignment(QtCore.Qt.AlignCenter)
grid.addWidget(self._direction, 2, 1)
self._override = QtGui.QLabel()
self._override.setAlignment(QtCore.Qt.AlignCenter)
grid.addWidget(self._override, 3, 1)
self._value = QtGui.QLabel()
self._value.setAlignment(QtCore.Qt.AlignCenter)
grid.addWidget(self._value, 3, 1, 6, 1)
grid.addWidget(self._value, 4, 1, 6, 1)

self._value.setContextMenuPolicy(QtCore.Qt.ActionsContextMenu)
menu = QtGui.QActionGroup(self._value)
@@ -83,8 +86,10 @@ def set_value(self, value, oe, override):
if override:
value_s = "<b>" + value_s + "</b>"
color = " color=\"red\""
self._override.setText("<font size=\"1\" color=\"red\">OVERRIDE</font>")
else:
color = ""
self._override.setText("")
self._value.setText("<font size=\"9\"{}>{}</font>".format(
color, value_s))
oe = oe or self.force_out
67 changes: 55 additions & 12 deletions soc/runtime/moninj.c
Original file line number Diff line number Diff line change
@@ -20,6 +20,19 @@ enum {
MONINJ_REQ_TTLSET = 2
};

enum {
MONINJ_TTL_MODE_EXP = 0,
MONINJ_TTL_MODE_1 = 1,
MONINJ_TTL_MODE_0 = 2,
MONINJ_TTL_MODE_IN = 3
};

enum {
MONINJ_TTL_OVERRIDE_ENABLE = 0,
MONINJ_TTL_OVERRIDE_O = 1,
MONINJ_TTL_OVERRIDE_OE = 2
};

static struct udp_pcb *listen_pcb;

struct monitor_reply {
@@ -28,8 +41,6 @@ struct monitor_reply {
long long int ttl_overrides;
};

static long long int ttl_overrides;

static void moninj_monitor(const ip_addr_t *addr, u16_t port)
{
struct monitor_reply reply;
@@ -38,16 +49,20 @@ 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++) {
rtio_mon_chan_sel_write(i);
rtio_mon_probe_sel_write(0);
if(rtio_mon_probe_value_read())
rtio_moninj_mon_chan_sel_write(i);
rtio_moninj_mon_probe_sel_write(0);
if(rtio_moninj_mon_value_read())
reply.ttl_levels |= 1LL << i;
rtio_mon_probe_sel_write(1);
if(rtio_mon_probe_value_read())
rtio_moninj_mon_probe_sel_write(1);
if(rtio_moninj_mon_value_read())
reply.ttl_oes |= 1LL << i;
rtio_moninj_inj_chan_sel_write(i);
rtio_moninj_inj_override_sel_write(MONINJ_TTL_OVERRIDE_ENABLE);
if(rtio_moninj_inj_value_read())
reply.ttl_overrides |= 1LL << i;
}
reply.ttl_overrides = ttl_overrides;

reply_p = pbuf_alloc(PBUF_TRANSPORT, sizeof(struct monitor_reply), PBUF_RAM);
if(!reply_p) {
@@ -61,10 +76,38 @@ static void moninj_monitor(const ip_addr_t *addr, u16_t port)

static void moninj_ttlset(int channel, int mode)
{
if(mode)
ttl_overrides |= (1LL << channel);
else
ttl_overrides &= ~(1LL << channel);
rtio_moninj_inj_chan_sel_write(channel);
switch(mode) {
case MONINJ_TTL_MODE_EXP:
rtio_moninj_inj_override_sel_write(MONINJ_TTL_OVERRIDE_ENABLE);
rtio_moninj_inj_value_write(0);
break;
case MONINJ_TTL_MODE_1:
rtio_moninj_inj_override_sel_write(MONINJ_TTL_OVERRIDE_O);
rtio_moninj_inj_value_write(1);
rtio_moninj_inj_override_sel_write(MONINJ_TTL_OVERRIDE_OE);
rtio_moninj_inj_value_write(1);
rtio_moninj_inj_override_sel_write(MONINJ_TTL_OVERRIDE_ENABLE);
rtio_moninj_inj_value_write(1);
break;
case MONINJ_TTL_MODE_0:
rtio_moninj_inj_override_sel_write(MONINJ_TTL_OVERRIDE_O);
rtio_moninj_inj_value_write(0);
rtio_moninj_inj_override_sel_write(MONINJ_TTL_OVERRIDE_OE);
rtio_moninj_inj_value_write(1);
rtio_moninj_inj_override_sel_write(MONINJ_TTL_OVERRIDE_ENABLE);
rtio_moninj_inj_value_write(1);
break;
case MONINJ_TTL_MODE_IN:
rtio_moninj_inj_override_sel_write(MONINJ_TTL_OVERRIDE_OE);
rtio_moninj_inj_value_write(0);
rtio_moninj_inj_override_sel_write(MONINJ_TTL_OVERRIDE_ENABLE);
rtio_moninj_inj_value_write(1);
break;
default:
log("unknown TTL mode %d", mode);
break;
}
}

static void moninj_recv(void *arg, struct udp_pcb *upcb, struct pbuf *req,
13 changes: 6 additions & 7 deletions soc/targets/artiq_kc705.py
Original file line number Diff line number Diff line change
@@ -37,7 +37,7 @@ class NIST_QC1(MiniSoC, AMPSoC):
"rtio": None, # mapped on Wishbone instead
"rtio_crg": 13,
"kernel_cpu": 14,
"rtio_mon": 15
"rtio_moninj": 15
}
csr_map.update(MiniSoC.csr_map)
mem_map = {
@@ -66,16 +66,15 @@ def __init__(self, platform, cpu_type="or1k", **kwargs):
for i in range(2):
phy = ttl_simple.Inout(platform.request("pmt", i))
self.submodules += phy
rtio_channels.append(rtio.Channel(phy.rtlink, phy.probes,
ififo_depth=512))
rtio_channels.append(rtio.Channel.from_phy(phy, ififo_depth=512))
for i in range(16):
phy = ttl_simple.Output(platform.request("ttl", i))
self.submodules += phy
rtio_channels.append(rtio.Channel(phy.rtlink, phy.probes))
rtio_channels.append(rtio.Channel.from_phy(phy))

phy = ttl_simple.Output(platform.request("user_led", 2))
self.submodules += phy
rtio_channels.append(rtio.Channel(phy.rtlink, phy.probes))
rtio_channels.append(rtio.Channel.from_phy(phy))
self.add_constant("RTIO_TTL_COUNT", len(rtio_channels))

self.add_constant("RTIO_DDS_CHANNEL", len(rtio_channels))
@@ -84,14 +83,14 @@ def __init__(self, platform, cpu_type="or1k", **kwargs):
"rio")
phy = RT2WB(7, self.dds.bus)
self.submodules += phy
rtio_channels.append(rtio.Channel(phy.rtlink, ififo_depth=4))
rtio_channels.append(rtio.Channel.from_phy(phy, ififo_depth=4))

# RTIO core
self.submodules.rtio_crg = _RTIOCRG(platform, self.crg.pll_sys)
self.submodules.rtio = rtio.RTIO(rtio_channels,
clk_freq=125000000)
self.add_constant("RTIO_FINE_TS_WIDTH", self.rtio.fine_ts_width)
self.submodules.rtio_mon = rtio.Monitor(rtio_channels)
self.submodules.rtio_moninj = rtio.MonInj(rtio_channels)

if isinstance(platform.toolchain, XilinxVivadoToolchain):
platform.add_platform_command("""
15 changes: 7 additions & 8 deletions soc/targets/artiq_pipistrello.py
Original file line number Diff line number Diff line change
@@ -91,26 +91,25 @@ def __init__(self, platform, cpu_type="or1k", **kwargs):
for i in range(2):
phy = ttl_simple.Inout(platform.request("pmt", i))
self.submodules += phy
rtio_channels.append(rtio.Channel(phy.rtlink, phy.probes,
ififo_depth=512))
rtio_channels.append(rtio.Channel.from_phy(phy, ififo_depth=512))

phy = ttl_simple.Inout(platform.request("xtrig", 0))
self.submodules += phy
rtio_channels.append(rtio.Channel(phy.rtlink, phy.probes))
rtio_channels.append(rtio.Channel.from_phy(phy))

for i in range(16):
phy = ttl_simple.Output(platform.request("ttl", i))
self.submodules += phy
rtio_channels.append(rtio.Channel(phy.rtlink, phy.probes))
rtio_channels.append(rtio.Channel.from_phy(phy))

phy = ttl_simple.Output(platform.request("ext_led", 0))
self.submodules += phy
rtio_channels.append(rtio.Channel(phy.rtlink, phy.probes))
rtio_channels.append(rtio.Channel.from_phy(phy))

for i in range(2, 5):
phy = ttl_simple.Output(platform.request("user_led", i))
self.submodules += phy
rtio_channels.append(rtio.Channel(phy.rtlink, phy.probes))
rtio_channels.append(rtio.Channel.from_phy(phy))
self.add_constant("RTIO_TTL_COUNT", len(rtio_channels))

self.add_constant("RTIO_DDS_CHANNEL", len(rtio_channels))
@@ -119,14 +118,14 @@ def __init__(self, platform, cpu_type="or1k", **kwargs):
"rio")
phy = RT2WB(7, self.dds.bus)
self.submodules += phy
rtio_channels.append(rtio.Channel(phy.rtlink, ififo_depth=4))
rtio_channels.append(rtio.Channel.from_phy(phy, ififo_depth=4))

# RTIO core
self.submodules.rtio_crg = _RTIOCRG(platform)
self.submodules.rtio = rtio.RTIO(rtio_channels,
clk_freq=125000000)
self.add_constant("RTIO_FINE_TS_WIDTH", self.rtio.fine_ts_width)
self.submodules.rtio_mon = rtio.Monitor(rtio_channels)
self.submodules.rtio_mon = rtio.MonInj(rtio_channels)

# CPU connections
rtio_csrs = self.rtio.get_csrs()