Skip to content

Commit

Permalink
Merge branch 'master' into spimaster
Browse files Browse the repository at this point in the history
* master:
  artiq_flash: use term 'gateware'
  targets/kc705-nist_clock: add clock generator on LA32 for testing purposes
  doc: insist that output() must be called on TTLInOut. Closes #297
  doc: update install instructions
  coredevice: do not give up on UTF-8 errors in log. Closes #300
  use m-labs setup for defaults
  fix indentation
jordens committed Feb 29, 2016
2 parents 6c899e6 + 6dd1eb2 commit 7ab7f7d
Showing 11 changed files with 104 additions and 70 deletions.
4 changes: 2 additions & 2 deletions artiq/coredevice/comm_generic.py
Original file line number Diff line number Diff line change
@@ -158,7 +158,7 @@ def _read_bytes(self):
return self._read_chunk(self._read_int32())

def _read_string(self):
return self._read_bytes()[:-1].decode('utf-8')
return self._read_bytes()[:-1].decode("utf-8")

#
# Writer interface
@@ -242,7 +242,7 @@ def get_log(self):

self._read_header()
self._read_expect(_D2HMsgType.LOG_REPLY)
return self._read_chunk(self._read_length).decode("utf-8")
return self._read_chunk(self._read_length).decode("utf-8", "replace")

def clear_log(self):
self._write_empty(_H2DMsgType.LOG_CLEAR)
15 changes: 13 additions & 2 deletions artiq/coredevice/ttl.py
Original file line number Diff line number Diff line change
@@ -91,6 +91,11 @@ class TTLInOut:
This should be used with bidirectional channels.
Note that the channel is in input mode by default. If you need to drive a
signal, you must call ``output``. If the channel is in output mode most of
the time in your setup, it is a good idea to call ``output`` in the
startup kernel.
:param channel: channel number
"""
def __init__(self, dmgr, channel):
@@ -107,12 +112,18 @@ def set_oe(self, oe):

@kernel
def output(self):
"""Set the direction to output."""
"""Set the direction to output.
There must be a delay of at least one RTIO clock cycle before any
other command can be issued."""
self.set_oe(True)

@kernel
def input(self):
"""Set the direction to input."""
"""Set the direction to input.
There must be a delay of at least one RTIO clock cycle before any
other command can be issued."""
self.set_oe(False)

@kernel
25 changes: 12 additions & 13 deletions artiq/frontend/artiq_flash.py
Original file line number Diff line number Diff line change
@@ -6,7 +6,6 @@
import subprocess
import tempfile

import artiq
from artiq import __artiq_dir__ as artiq_dir
from artiq.frontend.bit2bin import bit2bin

@@ -18,13 +17,13 @@ def get_argparser():
epilog="""\
Valid actions:
* proxy: load the flash proxy bitstream
* bitstream: write bitstream to flash
* proxy: load the flash proxy gateware bitstream
* gateware: write gateware bitstream to flash
* bios: write bios to flash
* runtime: write runtime to flash
* storage: write storage image to flash
* load: load bitstream into device (volatile but fast)
* start: trigger the target to (re)load its bitstream from flash
* load: load gateware bitstream into device (volatile but fast)
* start: trigger the target to (re)load its gateware bitstream from flash
Prerequisites:
@@ -37,12 +36,12 @@ def get_argparser():
""")
parser.add_argument("-t", "--target", default="kc705",
help="target board, default: %(default)s")
parser.add_argument("-m", "--adapter", default="qc2",
parser.add_argument("-m", "--adapter", default="clock",
help="target adapter, default: %(default)s")
parser.add_argument("-f", "--storage", help="write file to storage area")
parser.add_argument("-d", "--dir", help="look for files in this directory")
parser.add_argument("ACTION", nargs="*",
default="proxy bitstream bios runtime start".split(),
default="proxy gateware bios runtime start".split(),
help="actions to perform, default: %(default)s")
return parser

@@ -55,15 +54,15 @@ def main():
"kc705": {
"chip": "xc7k325t",
"start": "xc7_program xc7.tap",
"bitstream": 0x000000,
"gateware": 0x000000,
"bios": 0xaf0000,
"runtime": 0xb00000,
"storage": 0xb80000,
},
"pipistrello": {
"chip": "xc6slx45",
"start": "xc6s_program xc6s.tap",
"bitstream": 0x000000,
"gateware": 0x000000,
"bios": 0x170000,
"runtime": 0x180000,
"storage": 0x200000,
@@ -83,23 +82,23 @@ def main():
proxy_base = "bscan_spi_{}.bit".format(config["chip"])
proxy = None
for p in [opts.dir, os.path.expanduser("~/.migen"),
"/usr/local/share/migen", "/usr/share/migen"]:
"/usr/local/share/migen", "/usr/share/migen"]:
proxy_ = os.path.join(p, proxy_base)
if os.access(proxy_, os.R_OK):
proxy = "jtagspi_init 0 {}".format(proxy_)
break
if not proxy:
raise SystemExit(
"proxy bitstream {} not found".format(proxy_base))
"proxy gateware bitstream {} not found".format(proxy_base))
prog.append(proxy)
elif action == "bitstream":
elif action == "gateware":
bin = os.path.join(opts.dir, "top.bin")
if not os.access(bin, os.R_OK):
bin = tempfile.mkstemp()[1]
bit = os.path.join(opts.dir, "top.bit")
conv = True
prog.append("jtagspi_program {} 0x{:x}".format(
bin, config["bitstream"]))
bin, config["gateware"]))
elif action == "bios":
prog.append("jtagspi_program {} 0x{:x}".format(
os.path.join(opts.dir, "bios.bin"), config["bios"]))
6 changes: 2 additions & 4 deletions artiq/gateware/nist_clock.py
Original file line number Diff line number Diff line change
@@ -48,10 +48,8 @@
Subsignal("n", Pins("LPC:CLK1_M2C_N")),
IOStandard("LVDS")),

("la32", 0,
Subsignal("p", Pins("LPC:LA32_P")),
Subsignal("n", Pins("LPC:LA32_N")),
IOStandard("LVDS")),
("la32_p", 0, Pins("LPC:LA32_P"), IOStandard("LVTTL")),
("la32_n", 0, Pins("LPC:LA32_N"), IOStandard("LVTTL")),

("spi", 0,
Subsignal("clk", Pins("LPC:LA13_N")),
9 changes: 6 additions & 3 deletions artiq/gateware/targets/kc705.py
Original file line number Diff line number Diff line change
@@ -249,20 +249,23 @@ def __init__(self, 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.config["RTIO_REGULAR_TTL_COUNT"] = len(rtio_channels)

spi_pins = self.platform.request("ams101_dac", 0)
phy = ttl_simple.Output(spi_pins.ldac)
self.submodules += phy
self.config["RTIO_SPI_LDAC_CHANNEL"] = len(rtio_channels)
rtio_channels.append(rtio.Channel.from_phy(phy))
self.config["RTIO_REGULAR_TTL_COUNT"] = len(rtio_channels)

phy = spi.SPIMaster(spi_pins)
self.submodules += phy
self.config["RTIO_FIRST_SPI_CHANNEL"] = len(rtio_channels)
rtio_channels.append(rtio.Channel.from_phy(
phy, ofifo_depth=4, ififo_depth=4))

phy = ttl_simple.ClockGen(platform.request("la32_p"))
self.submodules += phy
rtio_channels.append(rtio.Channel.from_phy(phy))

self.config["RTIO_DDS_CHANNEL"] = len(rtio_channels)
self.config["DDS_CHANNEL_COUNT"] = 11
self.config["DDS_AD9914"] = True
@@ -341,7 +344,7 @@ def main():
"+ NIST Ions QC1/CLOCK/QC2 hardware adapters")
builder_args(parser)
soc_kc705_args(parser)
parser.add_argument("-H", "--hw-adapter", default="qc1",
parser.add_argument("-H", "--hw-adapter", default="clock",
help="hardware adapter type: qc1/clock/qc2 "
"(default: %(default)s)")
args = parser.parse_args()
2 changes: 1 addition & 1 deletion artiq/master/scheduler.py
Original file line number Diff line number Diff line change
@@ -198,7 +198,7 @@ async def _do(self):
await self.pool.state_changed.wait()
elif isinstance(run, float):
await asyncio_wait_or_cancel([self.pool.state_changed.wait()],
timeout=run)
timeout=run)
else:
if run.flush:
run.status = RunStatus.flushing
4 changes: 2 additions & 2 deletions artiq/runtime/main.c
Original file line number Diff line number Diff line change
@@ -137,9 +137,9 @@ static void network_init(void)
struct ip4_addr gateway_ip;

init_macadr();
fsip_or_default(&local_ip, "ip", 192, 168, 0, 42);
fsip_or_default(&local_ip, "ip", 192, 168, 1, 50);
fsip_or_default(&netmask, "netmask", 255, 255, 255, 0);
fsip_or_default(&gateway_ip, "gateway", 192, 168, 0, 1);
fsip_or_default(&gateway_ip, "gateway", 192, 168, 1, 1);

lwip_init();

2 changes: 2 additions & 0 deletions doc/manual/core_device.rst
Original file line number Diff line number Diff line change
@@ -64,6 +64,8 @@ With the CLOCK hardware, the TTL lines are mapped as follows:
+--------------------+-----------------------+--------------+
| 19 | LED | Output |
+--------------------+-----------------------+--------------+
| 20 | LA32_P | Clock |
+--------------------+-----------------------+--------------+


Pipistrello
4 changes: 4 additions & 0 deletions doc/manual/getting_started_core.rst
Original file line number Diff line number Diff line change
@@ -108,6 +108,10 @@ Create a new file ``rtio.py`` containing the following: ::
delay(2*us)


.. note::
If ``ttl0`` is a bidirectional channel (``TTLInOut``), it is in input (non-driving) mode by default. You need to call ``self.ttl0.output()`` as explained above for the LED.


Connect an oscilloscope or logic analyzer to TTL0 and run ``artiq_run.py led.py``. Notice that the generated signal's period is precisely 4 microseconds, and that it has a duty cycle of precisely 50%. This is not what you would expect if the delay and the pulse were implemented with CPU-controlled GPIO: overhead from the loop management, function calls, etc. would increase the signal's period, and asymmetry in the overhead would cause duty cycle distortion.

Instead, inside the core device, output timing is generated by the gateware and the CPU only programs switching commands with certain timestamps that the CPU computes. This guarantees precise timing as long as the CPU can keep generating timestamps that are increasing fast enough. In case it fails to do that (and attempts to program an event with a timestamp in the past), the :class:`artiq.coredevice.exceptions.RTIOUnderflow` exception is raised. The kernel causing it may catch it (using a regular ``try... except...`` construct), or it will be propagated to the host.
26 changes: 17 additions & 9 deletions doc/manual/installing.rst
Original file line number Diff line number Diff line change
@@ -40,13 +40,16 @@ If your ``$PATH`` misses reference the ``miniconda3/bin`` or ``anaconda3/bin`` y

$ export PATH=$HOME/miniconda3/bin:$PATH

Installing the host side software
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Installing the ARTIQ packages
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

For this, you need to add our Anaconda repository to your conda configuration::

$ conda config --add channels http://conda.anaconda.org/m-labs/channel/main
$ conda config --add channels http://conda.anaconda.org/m-labs/channel/dev

.. note::
To use the development versions of ARTIQ, also add the ``dev`` channel (http://conda.anaconda.org/m-labs/channel/dev).
Development versions contain more features, but are not as well-tested and are more likely to contain bugs or inconsistencies.

Then you can install the ARTIQ package, it will pull all the necessary dependencies.

@@ -60,7 +63,12 @@ Then you can install the ARTIQ package, it will pull all the necessary dependenc
$ ENV=$(date +artiq-%Y-%m-%d); conda create -n $ENV artiq-kc705-nist_qc1; \
echo "Created environment $ENV for ARTIQ"

* For the KC705 board with the FMC backplane and AD9914 DDS chips::
* For the KC705 board with the "clock" FMC backplane and AD9914 DDS chips::

$ ENV=$(date +artiq-%Y-%m-%d); conda create -n $ENV artiq-kc705-nist_clock; \
echo "Created environment $ENV for ARTIQ"

* For the KC705 board with the QC2 FMC backplane and AD9914 DDS chips::

$ ENV=$(date +artiq-%Y-%m-%d); conda create -n $ENV artiq-kc705-nist_qc2; \
echo "Created environment $ENV for ARTIQ"
@@ -89,19 +97,19 @@ You now need to flash 3 things on the FPGA board:
2. The BIOS
3. The ARTIQ runtime

First you need to :ref:`install openocd <install-openocd>`. Then, you can flash the board:
They are all shipped in our Conda packages, along with the required flash proxy bitstreams.

First you need to install OpenOCD. Then, you can flash the board:

* For the Pipistrello board::

$ artiq_flash -t pipistrello

* For the KC705 board::

$ artiq_flash

Next step (for KC705) is to flash MAC and IP addresses to the board:
$ artiq_flash -m [qc1/clock/qc2]

* See :ref:`those instructions <flash-mac-ip-addr>` to flash MAC and IP addresses.
For the KC705, the next step is to flash the MAC and IP addresses to the board. See :ref:`those instructions <flash-mac-ip-addr>`.

.. _install-from-sources:

77 changes: 43 additions & 34 deletions examples/master/device_db.pyon
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
# This is an example device database that needs to be adapted to your setup.
# The RTIO channel numbers here are for NIST QC1 on KC705.
# The RTIO channel numbers here are for NIST CLOCK on KC705.

{
"comm": {
"type": "local",
"module": "artiq.coredevice.comm_tcp",
"class": "Comm",
"arguments": {"host": "192.168.0.42"}
"arguments": {"host": "kc705.lab.m-labs.hk"}
},
"core": {
"type": "local",
@@ -15,73 +15,77 @@
"arguments": {"ref_period": 1e-9}
},

"pmt0": {
"type": "local",
"module": "artiq.coredevice.ttl",
"class": "TTLInOut",
"arguments": {"channel": 0}
},
"pmt1": {
"type": "local",
"module": "artiq.coredevice.ttl",
"class": "TTLInOut",
"arguments": {"channel": 1}
},

"ttl0": {
"type": "local",
"module": "artiq.coredevice.ttl",
"class": "TTLOut",
"arguments": {"channel": 2},
"arguments": {"channel": 0},
"comment": "This is a fairly long comment to test word wrapping in GUI."
},
"ttl1": {
"type": "local",
"module": "artiq.coredevice.ttl",
"class": "TTLOut",
"arguments": {"channel": 3},
"arguments": {"channel": 1},
"comment": "Hello World"
},
"ttl2": {
"type": "local",
"module": "artiq.coredevice.ttl",
"class": "TTLOut",
"arguments": {"channel": 4}
"arguments": {"channel": 2}
},
"ttl3": {
"type": "local",
"module": "artiq.coredevice.ttl",
"class": "TTLOut",
"arguments": {"channel": 5}
"class": "TTLInOut",
"arguments": {"channel": 3}
},

"ttl4": {
"type": "local",
"module": "artiq.coredevice.ttl",
"class": "TTLOut",
"arguments": {"channel": 6}
"arguments": {"channel": 4}
},
"ttl5": {
"type": "local",
"module": "artiq.coredevice.ttl",
"class": "TTLOut",
"arguments": {"channel": 7}
"arguments": {"channel": 5}
},
"ttl_sma": {
"ttl6": {
"type": "local",
"module": "artiq.coredevice.ttl",
"class": "TTLOut",
"arguments": {"channel": 6}
},
"ttl7": {
"type": "local",
"module": "artiq.coredevice.ttl",
"class": "TTLInOut",
"arguments": {"channel": 17}
"arguments": {"channel": 7}
},
"led": {


"ttl_sma": {
"type": "local",
"module": "artiq.coredevice.ttl",
"class": "TTLOut",
"class": "TTLInOut",
"arguments": {"channel": 18}
},
"ttl15": {
"ttl_clock_la32_p": {
"type": "local",
"module": "artiq.coredevice.ttl",
"class": "TTLClockGen",
"arguments": {"channel": 20}
},


"led": {
"type": "local",
"module": "artiq.coredevice.ttl",
"class": "TTLOut",
"arguments": {"channel": 19}
},

@@ -94,21 +98,21 @@
"dds0": {
"type": "local",
"module": "artiq.coredevice.dds",
"class": "AD9858",
"arguments": {"sysclk": 1e9, "channel": 0},
"class": "AD9914",
"arguments": {"sysclk": 3e9, "channel": 0},
"comment": "Comments work in DDS panel as well"
},
"dds1": {
"type": "local",
"module": "artiq.coredevice.dds",
"class": "AD9858",
"arguments": {"sysclk": 1e9, "channel": 1}
"class": "AD9914",
"arguments": {"sysclk": 3e9, "channel": 1}
},
"dds2": {
"type": "local",
"module": "artiq.coredevice.dds",
"class": "AD9858",
"arguments": {"sysclk": 1e9, "channel": 2}
"class": "AD9914",
"arguments": {"sysclk": 3e9, "channel": 2}
},

"qc_q1_0": {
@@ -160,7 +164,12 @@
"ttl_out": "ttl0",
"ttl_out_serdes": "ttl0",

"pmt": "pmt0",
"loop_out": "ttl0",
"loop_in": "ttl3",
"loop_clock_out": "ttl_clock_la32_p",
"loop_clock_in": "ttl7",

"pmt": "ttl3",
"bd_dds": "dds0",
"bd_sw": "ttl0",
"bdd_dds": "dds1",

0 comments on commit 7ab7f7d

Please sign in to comment.